Tous les produits
Search
Centre de documentation

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

Dernière mise à jour :Aug 11, 2026

Le protocole TLS mutuel (mTLS) sur la passerelle d'entrée ASM impose aux clients de présenter un certificat lors de l'établissement de la connexion TLS pour prouver leur identité. Une fois l'authentification validée, des politiques d'autorisation déterminent les ressources accessibles par chaque identité client. Cette approche à deux niveaux dissocie l'authentification (le mTLS vérifie l'identité du client) de l'autorisation (les politiques contrôlent les actions autorisées).

Ce guide couvre trois tâches :

  1. Générez les certificats requis pour le mTLS (autorité de certification, serveur et client).

  2. Configurez la passerelle d'entrée ASM pour exiger des certificats clients sur le port 443.

  3. Créez une politique d'autorisation refusant l'accès à un chemin spécifique pour une identité client donnée.

Correspondance entre l'identité client et les règles d'autorisation

Le certificat client inclut une URI SPIFFE dans son nom alternatif de sujet (SAN), par exemple spiffe://test.client. Les politiques d'autorisation ASM utilisent le champ principals pour identifier cette entité. La politique compare la valeur située après le préfixe spiffe://. Par exemple, une valeur principals définie sur test.client correspond à un certificat contenant URI.1 = spiffe://test.client.

Ce mécanisme lie l'authentification mTLS au contrôle d'accès basé sur les chemins.

Prérequis

Avant de commencer, assurez-vous que :

Étape 1 : Générer les certificats mTLS

Le mTLS nécessite trois ensembles de certificats : une autorité de certification racine (CA), un certificat serveur et un certificat client. L'autorité de certification racine signe les certificats serveur et client. La passerelle présente le certificat serveur pour s'identifier, tandis que les clients présentent le certificat client pour prouver leur identité.

Remarque

Lors de la génération, acceptez les valeurs par défaut pour les champs du certificat. Les fichiers de configuration ci-dessous définissent déjà tous les champs requis.

  1. Créez un fichier nommé ca.cnf avec le contenu suivant.

    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. Générez le certificat et la clé privée de l'autorité de certification racine.

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

    Cette commande produit deux fichiers : cacert.pem (le certificat de l'autorité de certification) et cakey.pem (la clé privée de l'autorité de certification).

  3. Créez un fichier nommé server.cnf avec le contenu suivant.

    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. Générez le certificat serveur, initialisez la base de données de signature de l'autorité de certification, puis signez le certificat.

    # 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

    Cette procédure génère deux fichiers : servercert.pem (le certificat serveur) et serverkey.pem (la clé privée du serveur).

  5. Créez un fichier nommé client.cnf avec le contenu suivant.

    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

    Deux champs de cette configuration déterminent l'identité du client aux fins d'autorisation :

    Champ Valeur Rôle
    commonName_default test.client Identifie le client
    URI.1 (SAN) spiffe://test.client Mis en correspondance par le champ principals des politiques d'autorisation (après le préfixe spiffe://)
  6. Générez le certificat client et signez-le avec l'autorité de certification racine.

    # 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

    Cette opération produit deux fichiers : clientcert.pem (le certificat client) et client.key.pem (la clé privée du client).

  7. Importez le certificat mTLS via la fonctionnalité de gestion des certificats d'ASM. Définissez le nom du certificat sur test.com. Pour plus d'informations, consultez la section Utiliser la fonctionnalité de gestion des certificats d'ASM.

    Vous pouvez également créer directement un Secret Kubernetes. Exécutez la commande suivante en utilisant le fichier kubeconfig de votre cluster de plan de données :

    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

    Ce Secret regroupe trois fichiers :

    Clé Fichier Objectif
    tls.key serverkey.pem Clé privée du serveur pour la terminaison TLS
    tls.crt servercert.pem Certificat serveur présenté aux clients
    ca.crt cacert.pem Certificat de l'autorité de certification racine utilisé pour vérifier les certificats clients

Étape 2 : Configurer l'écouteur mTLS sur la passerelle

Ajoutez un écouteur mTLS sur le port 443 de la passerelle d'entrée ASM. Après cette configuration, les clients externes doivent présenter un certificat client valide pour accéder au service httpbin.

  1. Mettez à jour la ressource Gateway avec le contenu suivant.

    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

    Le paramètre tls.mode: MUTUAL impose aux clients de présenter un certificat signé par l'autorité de certification stockée dans le Secret test.com. En l'absence de certificat client valide, l'établissement de la connexion TLS échoue et la passerelle rejette la connexion.

    Remarque

    Les autres modes TLS incluent SIMPLE (TLS unilatéral côté serveur, aucun certificat client requis) et PASSTHROUGH (la terminaison TLS n'est pas effectuée au niveau de la passerelle). Utilisez le mode MUTUAL lorsque vous devez authentifier l'identité du client au niveau de la passerelle.

  2. Vérifiez que le mTLS rejette les requêtes ne contenant pas de certificat client.

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

    Remplacez <ASM-gateway-IP> par l'adresse IP de votre passerelle d'entrée ASM.

    La requête échoue avec une erreur d'établissement de connexion TLS car aucun certificat client n'est fourni. Cela confirme que la passerelle applique bien le protocole mTLS.

  3. Vérifiez que le mTLS accepte les requêtes accompagnées d'un certificat client valide.

    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

    Résultat attendu :

    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

    Une réponse HTTP/2 200 confirme que la passerelle a accepté le certificat client et a transféré la requête vers httpbin.

Étape 3 : Restreindre l'accès client via une politique d'autorisation

Une fois que le mTLS a authentifié chaque client, des politiques d'autorisation déterminent les ressources accessibles. Dans cette étape, créez une politique DENY qui bloque l'identité test.client pour un chemin spécifique. Les autres clients ne sont pas affectés.

Remarque

Lorsque plusieurs politiques d'autorisation s'appliquent à la même charge de travail, les politiques DENY sont évaluées avant les politiques ALLOW. Toute requête correspondant à une règle DENY est rejetée, indépendamment des règles ALLOW.

  1. Déployez la politique AuthorizationPolicy suivante pour refuser l'accès de test.client au chemin /status/418 de l'application httpbin. Pour plus d'informations, consultez la section Configurer des politiques d'autorisation pour les requêtes 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

    Cette politique cible la passerelle d'entrée (istio: ingressgateway) et refuse toute requête émanant du principal test.client vers le chemin /status/418. La valeur principals test.client correspond à l'URI SPIFFE spiffe://test.client contenue dans le SAN du certificat client.

Vérifier la politique d'autorisation

  1. Confirmez que test.client peut toujours accéder aux autres chemins. Envoyez une requête vers /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

    Résultat attendu :

    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

    Une réponse 200 indique que la politique DENY s'applique uniquement au chemin /status/418, et non aux autres chemins.

  2. Confirmez que test.client se voit refuser l'accès à /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

    Résultat attendu :

    RBAC: access denied

    Le message RBAC: access denied confirme que la politique d'autorisation a bloqué test.client pour ce chemin.

  3. Confirmez qu'une autre identité client peut toujours accéder à /status/418. Envoyez une requête en utilisant le certificat serveur à la place :

    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

    Résultat attendu :

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

    La réponse « teapot » confirme que la règle DENY cible uniquement l'identité test.client. Les autres identités disposant de certificats valides peuvent toujours accéder à /status/418.