Todos os produtos
Search
Central de documentação

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

Última atualização: Sep 21, 2026

O Mutual TLS (mTLS) no ingress gateway do ASM exige que os clientes apresentem um certificado durante o handshake TLS para comprovar sua identidade. Após a autenticação, as políticas de autorização controlam o que cada identidade de cliente pode acessar. Essa abordagem em duas camadas separa a autenticação (o mTLS verifica quem é o cliente) da autorização (as políticas controlam o que o cliente pode fazer).

Este guia aborda três tarefas:

  1. Gere os certificados para o mTLS (CA, servidor e cliente).

  2. Configure o ingress gateway do ASM para exigir certificados de cliente na porta 443.

  3. Crie uma política de autorização que negue o acesso de uma identidade de cliente específica a um caminho específico.

Como a identidade do cliente se mapeia para as regras de autorização

O certificado do cliente inclui um URI SPIFFE em seu Subject Alternative Name (SAN), como spiffe://test.client. As políticas de autorização do ASM usam o campo principals para corresponder a essa identidade. A política corresponde ao valor após o prefixo spiffe://. Por exemplo, o valor test.client no campo principals corresponde a um certificado com URI.1 = spiffe://test.client.

Esse mapeamento é o mecanismo principal que conecta a autenticação mTLS ao controle de acesso baseado em caminho.

Pré-requisitos

Antes de começar, certifique-se de ter:

Etapa 1: Gerar certificados mTLS

O mTLS requer três conjuntos de certificados: uma CA raiz, um certificado de servidor e um certificado de cliente. A CA raiz assina os certificados do servidor e do cliente. O gateway apresenta o certificado do servidor para se identificar, e os clientes apresentam o certificado de cliente para comprovar sua identidade.

Nota

Ao preencher os campos do certificado durante a geração, aceite os valores padrão. Os arquivos de configuração abaixo já definem todos os campos necessários.

  1. Crie um arquivo chamado ca.cnf com o seguinte conteúdo.

    ca.cnf

    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. Gere o certificado da CA raiz e a chave privada.

    openssl req -x509 -config ca.cnf -newkey rsa:4096 -sha256 -nodes -out cacert.pem -outform PEM

    Esse comando gera dois arquivos: cacert.pem (o certificado da CA) e cakey.pem (a chave privada da CA).

  3. Crie um arquivo chamado server.cnf com o seguinte conteúdo.

    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. Gere o certificado do servidor, inicialize o banco de dados de assinatura da CA e assine o certificado.

    # Generate the CSR and private key
    openssl req -config server.cnf -newkey rsa:2048 -sha256 -nodes -out server.csr -outform PEM
    
    # Initialize the CA signing database
    touch index.txt
    echo '01' > serial.txt
    
    # Sign the server certificate with the root CA
    openssl ca -config ca.cnf -policy signing_policy -extensions signing_req -out servercert.pem -infiles server.csr

    Esse comando gera dois arquivos: servercert.pem (o certificado do servidor) e serverkey.pem (a chave privada do servidor).

  5. Crie um arquivo chamado client.cnf com o seguinte conteúdo.

    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

    Dois campos nesta configuração determinam a identidade do cliente para autorização:

    Campo

    Valor

    Função

    commonName_default

    test.client

    Identifica o cliente

    URI.1 (SAN)

    spiffe://test.client

    Usado pelo campo principals nas políticas de autorização (após o prefixo spiffe://)

  6. Gere o certificado do cliente e assine-o com a CA raiz.

    # Generate the CSR and private key
    openssl req -config client.cnf -newkey rsa:2048 -sha256 -nodes -out clientcert.csr -outform PEM
    
    # Sign the client certificate with the root CA
    openssl ca -config ca.cnf -policy signing_policy -extensions signing_req -out clientcert.pem -infiles clientcert.csr

    Esse comando gera dois arquivos: clientcert.pem (o certificado do cliente) e client.key.pem (a chave privada do cliente).

  7. Importe o certificado mTLS usando o recurso de gerenciamento de certificados do ASM. Defina o nome do certificado como test.com. Para mais informações, consulte Use the certificate management feature of ASM.

    Como alternativa, crie um Secret do Kubernetes diretamente. Execute o seguinte comando usando o kubeconfig do seu cluster do plano de dados:

    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

    Este Secret contém três arquivos:

    Chave

    Arquivo

    Finalidade

    tls.key

    serverkey.pem

    Chave privada do servidor para terminação TLS

    tls.crt

    servercert.pem

    Certificado do servidor apresentado aos clientes

    ca.crt

    cacert.pem

    Certificado da CA raiz usado para verificar os certificados dos clientes

Etapa 2: Configurar o listener mTLS no gateway

Adicione um listener mTLS na porta 443 do ingress gateway do ASM. Após essa configuração, os clientes externos devem apresentar um certificado de cliente válido para acessar o serviço httpbin.

  1. Atualize o recurso Gateway com o seguinte conteúdo.

    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

    A configuração tls.mode: MUTUAL exige que os clientes apresentem um certificado assinado pela CA no Secret test.com. Sem um certificado de cliente válido, o handshake TLS falha e o gateway rejeita a conexão.

    Nota

    Outros modos TLS incluem SIMPLE (apenas TLS no lado do servidor, sem necessidade de certificado de cliente) e PASSTHROUGH (o gateway não termina o TLS). Use MUTUAL quando precisar autenticar a identidade do cliente no nível do gateway.

  2. Verifique se o mTLS rejeita requisições sem um certificado de cliente.

    curl -v --resolve "test.com:443:<ASM-gateway-IP>" \
      --cacert cacert.pem \
      https://test.com/status/200

    Substitua <ASM-gateway-IP> pelo endereço IP do seu ingress gateway do ASM.

    A requisição falha com um erro de handshake TLS porque não há certificado de cliente. Isso confirma que o gateway exige o mTLS.

  3. Verifique se o mTLS aceita requisições com um certificado de cliente válido.

    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

    Saída esperada:

    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

    Uma resposta HTTP/2 200 confirma que o gateway aceitou o certificado do cliente e encaminhou a requisição para o httpbin.

Etapa 3: Restringir o acesso de clientes com uma política de autorização

Depois que o mTLS autentica cada cliente, as políticas de autorização controlam o que cada cliente pode acessar. Nesta etapa, crie uma política DENY que bloqueie o acesso da identidade test.client a um caminho específico. Isso não afeta os demais clientes.

Nota

Quando existem várias políticas de autorização na mesma carga de trabalho, o sistema avalia as políticas DENY antes das políticas ALLOW. O sistema rejeita qualquer requisição que corresponda a uma regra DENY, independentemente das regras ALLOW.

  1. Implante o seguinte AuthorizationPolicy para negar o acesso de test.client ao caminho /status/418 no aplicativo httpbin. Para mais informações, consulte 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

    Esta política aplica-se ao ingress gateway (istio: ingressgateway) e nega qualquer requisição do principal test.client para o caminho /status/418. O valor test.client no campo principals corresponde ao URI SPIFFE spiffe://test.client no SAN do certificado do cliente.

Verifique a política de autorização

  1. Confirme se test.client ainda pode acessar outros caminhos. Envie uma requisição para /status/200:

    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

    Saída esperada:

    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

    Uma resposta 200 significa que a política DENY se aplica apenas a /status/418, e não a outros caminhos.

  2. Confirme se o sistema nega o acesso de test.client a /status/418:

    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

    Saída esperada:

    RBAC: access denied

    A mensagem RBAC: access denied confirma que a política de autorização bloqueou o acesso de test.client a este caminho.

  3. Confirme se uma identidade de cliente diferente ainda pode acessar /status/418. Para isso, envie uma requisição usando o certificado do servidor:

    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

    Saída esperada:

        -=[ teapot ]=-
    
           _...._
         .'  _ _ `.
        | ."` ^ `". _,
        \_;`"---"`|//
          |       ;/
          \_     _/
            `"""`

    A resposta teapot confirma que a regra DENY bloqueia apenas a identidade test.client. Outras identidades com certificados válidos ainda podem acessar /status/418.