The ASM gateway supports external mTLS services. The mTLS protocol requires clients to present their certificates, which contain user identity information. You can configure authorization policies to restrict access to specific users, enhancing protection for the service. This topic explains how to configure the mTLS service on the ASM ingress gateway and limit access through authorization policies.
Prerequisites
Automatic sidecar injection is enabled. For more information, see Configure sidecar proxy injection policies.
The ingress gateway and HTTPBin application are deployed, and the ingress gateway has port 443 enabled. For more information, see Deploy the HTTPBin application.
Step 1: Generate mTLS communication certificates
When creating the certificate, if you need to fill in the certificate information, use the default values. These default values are pre-set in the configuration file.
Create the ca.cnf file with the following content to generate the root certificate.
Run the following command to generate the root certificate.
openssl req -x509 -config ca.cnf -newkey rsa:4096 -sha256 -nodes -out cacert.pem -outform PEM
This command generates the
cacert.pem
andcakey.pem
files.Create the server.cnf file with the following content to generate the server certificate.
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
Run the following commands in sequence to generate the server certificate.
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
These commands generate the
servercert.pem
andserverkey.pem
files.Create the client.cnf file with the following content to generate the client certificate.
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
The
CommonName
of the client certificate istest.client
, and a new fieldURI.1 = spiffe://test.client
needs to be added to the Subject Alternative Name (SAN) information. Thespiffe://
prefix is required because theprincipals
field in the ASM authorization policy matches the part afterspiffe://
.Run the following commands in sequence to generate the client certificate.
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
These commands generate the
clientcert.pem
andclient.key.pem
files.Use the certificate management feature of ASM to import the mTLS certificate. Ensure that the imported certificate name is
test.com
. For more information, see Use the certificate management feature of ASM.You can also use kubectl to directly create a secret to import the certificate. Use the kubeconfig of the data plane cluster and run the following command.
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
Step 2: Configure an mTLS listener on port 443 of the gateway
Configure an mTLS listener on port 443 of the ASM gateway, allowing external clients to access the HTTPBin service over mTLS.
Update the gateway rule with the following content.
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
Run the following command to access the HTTPBin service using the client certificate.
curl --header "host:test.com" --resolve "test.com:443:${ASM gateway IP}" --cacert cacert.pem --cert clientcert.pem --key client.key.pem https://test.com/status/200 -I
Expected output:
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
Step 3: Configure authorization policy to restrict test.client access
Deploy the authorization policy with the following content to restrict test.client from accessing the
/status/418
path of the HTTPBin application. For more information, see Configure authorization policies for HTTP requests.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
Run the following command to access the
/status/200
path using the client certificate.curl --header "host:test.com" --resolve "test.com:443:${ASM gateway IP}" --cacert cacert.pem --cert clientcert.pem --key client.key.pem https://test.com/status/200 -I
Expected output:
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
Run the following command to access the
/status/418
path using the client certificate.curl --header "host:test.com" --resolve "test.com:443:${ASM gateway IP}" --cacert cacert.pem --cert clientcert.pem --key client.key.pem https://test.com/status/418
Expected output:
RBAC: access denied%
Run the following command to access the
/status/418
path using the server certificate.curl --header "host:test.com" --resolve "test.com:443:${ASM gateway IP}" --cacert cacert.pem --cert servercert.pem --key serverkey.pem https://test.com/status/418
Expected output:
-=[ teapot ]=- _...._ .' _ _ `. | ."` ^ `". _, \_;`"---"`|// | ;/ \_ _/ `"""`