ASM網關支援對外提供mTLS服務。mTLS協議要求用戶端提供自身認證,認證中包含了使用者的身份資訊。您可以在授權策略中配置只有特定的使用者才可以成功訪問該服務,進而為服務提供更加進階別的保護。本文將介紹如何在ASM入口網關上配置mTLS服務,並且通過授權策略實現對特定使用者的訪問限制。
前提條件
已開啟sidecar自動注入。具體操作,請參見配置Sidecar注入策略。
已部署入口網關和httpbin應用,請確保入口網關開啟了443連接埠。具體操作,請參見部署httpbin應用。
步驟一:產生mTLS通訊認證
在建立認證時,如果需要填寫認證資訊,請使用預設值。這些預設值已在設定檔中預先設定。
使用以下內容建立ca.cnf檔案,產生根憑證。
執行以下命令,產生根憑證。
openssl req -x509 -config ca.cnf -newkey rsa:4096 -sha256 -nodes -out cacert.pem -outform PEM
此命令會輸出
cacert.pem
和cakey.pem
檔案。使用以下內容建立server.cnf檔案,用於產生伺服器憑證。
HOME = . RANDFILE = $ENV::HOME/.rnd #################################################################### [ req ] default_bits = 2048 default_keyfile = serverkey.pem distinguished_name = server_distinguished_name req_extensions = server_req_extensions string_mask = utf8only #################################################################### [ server_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = CN stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = bj localityName = Locality Name (eg, city) localityName_default = bj organizationName = Organization Name (eg, company) organizationName_default = test commonName = Common Name (e.g. server FQDN or YOUR name) commonName_default = test.com emailAddress = Email Address emailAddress_default = test@example.com #################################################################### [ server_req_extensions ] subjectKeyIdentifier = hash basicConstraints = CA:FALSE keyUsage = digitalSignature, keyEncipherment subjectAltName = @alternate_names nsComment = "OpenSSL Generated Certificate" #################################################################### [ alternate_names ] DNS.1 = test.com
依次執行以下命令,產生伺服器憑證。
openssl req -config server.cnf -newkey rsa:2048 -sha256 -nodes -out server.csr -outform PEM
touch index.txt echo '01' > serial.txt
openssl ca -config ca.cnf -policy signing_policy -extensions signing_req -out servercert.pem -infiles server.csr
此命令會輸出
servercert.pem
和serverkey.pem
。使用以下內容建立client.cnf檔案,用於建立用戶端認證。
HOME = . RANDFILE = $ENV::HOME/.rnd #################################################################### [ req ] default_bits = 2048 default_keyfile = client.key.pem distinguished_name = server_distinguished_name req_extensions = server_req_extensions string_mask = utf8only #################################################################### [ server_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = CN stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = bj localityName = Locality Name (eg, city) localityName_default = bj organizationName = Organization Name (eg, company) organizationName_default = test.client commonName = Common Name (e.g. server FQDN or YOUR name) commonName_default = test.client emailAddress = Email Address emailAddress_default = test.client@example.com #################################################################### [ server_req_extensions ] subjectKeyIdentifier = hash basicConstraints = CA:FALSE keyUsage = digitalSignature, keyEncipherment subjectAltName = @alternate_names nsComment = "OpenSSL Generated Certificate" #################################################################### [ alternate_names ] URI.1 = spiffe://test.client
用戶端認證的
CommonName
為test.client
,SAN資訊中需要新增欄位URI.1 = spiffe://test.client
,這裡需要額外加上spiffe://
首碼,因為ASM的授權策略中principals欄位會匹配spiffe://
之後的部分。依次執行以下命令,產生用戶端認證。
openssl req -config client.cnf -newkey rsa:2048 -sha256 -nodes -out clientcert.csr -outform PEM
openssl ca -config ca.cnf -policy signing_policy -extensions signing_req -out clientcert.pem -infiles clientcert.csr
此命令會輸出
clientcert.pem
以及client.key.pem
。使用ASM認證管理匯入mTLS認證,請確保此處匯入的認證名稱為
test.com
。具體操作,請參見使用ASM認證管理。您也可以使用kubectl直接建立secret來完成認證匯入。使用資料面叢集的kubeconfig,執行如下命令。
kubectl create -n istio-system secret generic test.com \ --from-file=tls.key=serverkey.pem \ --from-file=tls.crt=servercert.pem \ --from-file=ca.crt=cacert.pem
步驟二:在網關443連接埠上配置mTLS監聽
本節將為ASM網關的443連接埠配置mTLS監聽,讓外部客戶端可以通過mTLS訪問httpbin服務。
使用以下內容,更新網關規則。
apiVersion: networking.istio.io/v1beta1 kind: Gateway metadata: name: httpbin namespace: default spec: selector: istio: ingressgateway servers: - hosts: - '*' port: name: test number: 80 protocol: HTTP - hosts: - test.com port: number: 443 name: https protocol: HTTPS tls: mode: MUTUAL credentialName: test.com
執行以下命令,使用client認證訪問httpbin服務。
curl --header "host:test.com" --resolve "test.com:443:${ASM網關IP}" --cacert cacert.pem --cert clientcert.pem --key client.key.pem https://test.com/status/200 -I
預期輸出:
HTTP/2 200 server: istio-envoy date: Sun, 28 Jul 2024 7:30:30 GMT content-type: text/html; charset=utf-8 access-control-allow-origin: * access-control-allow-credentials: true content-length: 0 x-envoy-upstream-service-time: 6
步驟三:配置授權策略,限制test.client訪問
使用以下內容,部署授權策略。限制test.client不能訪問httpbin應用的
/status/418
路徑。具體操作,請參見為HTTP流量設定授權策略。apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: test namespace: istio-system spec: action: DENY rules: - from: - source: principals: - test.client to: - operation: paths: - /status/418 selector: matchLabels: istio: ingressgateway
執行以下命令,使用client認證訪問
/status/200
路徑。curl --header "host:test.com" --resolve "test.com:443:${ASM網關IP}" --cacert cacert.pem --cert clientcert.pem --key client.key.pem https://test.com/status/200 -I
預期輸出:
HTTP/2 200 server: istio-envoy date: Sun, 28 Jul 2024 7:33:30 GMT content-type: text/html; charset=utf-8 access-control-allow-origin: * access-control-allow-credentials: true content-length: 0 x-envoy-upstream-service-time: 6
執行以下命令,使用client認證訪問
/status/418
路徑。curl --header "host:test.com" --resolve "test.com:443:${ASM網關IP}" --cacert cacert.pem --cert clientcert.pem --key client.key.pem https://test.com/status/418
預期輸出:
RBAC: access denied%
執行以下命令,使用server認證訪問
/status/418
路徑。curl --header "host:test.com" --resolve "test.com:443:${ASM網關IP}" --cacert cacert.pem --cert servercert.pem --key serverkey.pem https://test.com/status/418
預期輸出:
-=[ teapot ]=- _...._ .' _ _ `. | ."` ^ `". _, \_;`"---"`|// | ;/ \_ _/ `"""`