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 :
Générez les certificats requis pour le mTLS (autorité de certification, serveur et client).
Configurez la passerelle d'entrée ASM pour exiger des certificats clients sur le port 443.
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 :
L'injection automatique de sidecar est activée. Pour plus d'informations, consultez la section Configurer les politiques d'injection de proxy sidecar
La passerelle d'entrée et l'application httpbin sont déployées, et le port 443 est activé sur la passerelle d'entrée. Pour plus d'informations, consultez la section Déployer l'application httpbin
OpenSSL est installé sur votre machine locale.
É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é.
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.
-
Créez un fichier nommé
ca.cnfavec le contenu suivant. -
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 PEMCette commande produit deux fichiers :
cacert.pem(le certificat de l'autorité de certification) etcakey.pem(la clé privée de l'autorité de certification). -
Créez un fichier nommé
server.cnfavec 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 -
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.csrCette procédure génère deux fichiers :
servercert.pem(le certificat serveur) etserverkey.pem(la clé privée du serveur). -
Créez un fichier nommé
client.cnfavec 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.clientDeux champs de cette configuration déterminent l'identité du client aux fins d'autorisation :
Champ Valeur Rôle commonName_defaulttest.clientIdentifie le client URI.1(SAN)spiffe://test.clientMis en correspondance par le champ principalsdes politiques d'autorisation (après le préfixespiffe://) -
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.csrCette opération produit deux fichiers :
clientcert.pem(le certificat client) etclient.key.pem(la clé privée du client). -
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.pemCe Secret regroupe trois fichiers :
Clé Fichier Objectif tls.keyserverkey.pemClé privée du serveur pour la terminaison TLS tls.crtservercert.pemCertificat serveur présenté aux clients ca.crtcacert.pemCertificat 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.
-
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.comLe paramètre
tls.mode: MUTUALimpose aux clients de présenter un certificat signé par l'autorité de certification stockée dans le Secrettest.com. En l'absence de certificat client valide, l'établissement de la connexion TLS échoue et la passerelle rejette la connexion.RemarqueLes autres modes TLS incluent
SIMPLE(TLS unilatéral côté serveur, aucun certificat client requis) etPASSTHROUGH(la terminaison TLS n'est pas effectuée au niveau de la passerelle). Utilisez le modeMUTUALlorsque vous devez authentifier l'identité du client au niveau de la passerelle. -
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/200Remplacez
<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.
-
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 -IRé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: 6Une réponse
HTTP/2 200confirme 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.
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.
-
Déployez la politique AuthorizationPolicy suivante pour refuser l'accès de
test.clientau chemin/status/418de 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: ingressgatewayCette politique cible la passerelle d'entrée (
istio: ingressgateway) et refuse toute requête émanant du principaltest.clientvers le chemin/status/418. La valeurprincipalstest.clientcorrespond à l'URI SPIFFEspiffe://test.clientcontenue dans le SAN du certificat client.
Vérifier la politique d'autorisation
-
Confirmez que
test.clientpeut 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 -IRé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: 6Une réponse
200indique que la politique DENY s'applique uniquement au chemin/status/418, et non aux autres chemins. -
Confirmez que
test.clientse 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/418Résultat attendu :
RBAC: access deniedLe message
RBAC: access deniedconfirme que la politique d'autorisation a bloquétest.clientpour ce chemin. -
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/418Ré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.