All Products
Search
Document Center

Alibaba Cloud Service Mesh:Configure mTLS service on ASM ingress gateway and restrict specific client access

Last Updated:Oct 21, 2024

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

Step 1: Generate mTLS communication certificates

Note

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.

  1. Create the ca.cnf file with the following content to generate the root certificate.

    Expand to view CNF file content

    HOME = .`
    RANDFILE = $ENV::HOME/.rnd
    ####################################################################
    [ ca ]
    default_ca = CA_default # The default ca section
    [ CA_default ]
    default_days = 1000 # how long to certify for
    default_crl_days = 30 # how long before next CRL
    default_md = sha256 # use public key default MD
    preserve = no # keep passed DN ordering
    x509_extensions = ca_extensions # The extensions to add to the cert
    email_in_dn = no # Don't concat the email in the DN
    copy_extensions = copy # Required to copy SANs from CSR to cert
    
    #====Following 7 lines are for signing other certificates, not for making the CA certificate.====
    base_dir = .
    certificate = $base_dir/cacert.pem # The CA certifcate
    private_key = $base_dir/cakey.pem # The CA private key
    new_certs_dir = $base_dir # Location for new certs after signing
    database = $base_dir/index.txt # Database index file
    serial = $base_dir/serial.txt # The current serial number
    unique_subject = no # Set to 'no' to allow creation of several certificates with same subject.
    
    ####################################################################
    [ req ]
    default_bits = 4096
    default_keyfile = cakey.pem
    distinguished_name = ca_distinguished_name
    x509_extensions = ca_extensions
    string_mask = utf8only
    ####################################################################
    [ ca_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-asm
    organizationalUnitName = Organizational Unit (eg, division)
    organizationalUnitName_default = R&D
    commonName = Common Name (e.g. server FQDN or YOUR name)
    commonName_default = Test CA
    emailAddress = Email Address
    emailAddress_default = test@example.com
    ####################################################################
    [ ca_extensions ]
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid:always, issuer
    basicConstraints = critical, CA:true
    keyUsage = keyCertSign, cRLSign
    
    
    #====All lines below are for signing other certs, not for making the CA cert.======
    
    ####################################################################
    [ signing_policy ]
    countryName = optional
    stateOrProvinceName = optional
    localityName = optional
    organizationName = optional
    organizationalUnitName = optional
    commonName = supplied
    emailAddress = optional
    ####################################################################
    [ signing_req ]
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid,issuer
    basicConstraints = CA:FALSE
    keyUsage = digitalSignature, keyEncipherment
  2. 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 and cakey.pem files.

  3. 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
  4. 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 and serverkey.pem files.

  5. 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 is test.client, and a new field URI.1 = spiffe://test.client needs to be added to the Subject Alternative Name (SAN) information. The spiffe:// prefix is required because the principals field in the ASM authorization policy matches the part after spiffe://.

  6. 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 and client.key.pem files.

  7. 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.

  1. 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
  2. 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

  1. 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
  2. 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
  3. 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%
  4. 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 ]=-
    
           _...._
         .'  _ _ `.
        | ."` ^ `". _,
        \_;`"---"`|//
          |       ;/
          \_     _/
            `"""`