1.13. Sécurité
Si votre application Service Mesh est construite avec un ensemble complexe de microservices, vous pouvez utiliser Red Hat OpenShift Service Mesh pour personnaliser la sécurité de la communication entre ces services. L'infrastructure d'OpenShift Container Platform et les fonctionnalités de gestion du trafic de Service Mesh vous aident à gérer la complexité de vos applications et à sécuriser les microservices.
Avant de commencer
Si vous avez un projet, ajoutez-le à la ressourceServiceMeshMemberRoll
.
Si vous n'avez pas de projet, installez l'exemple d'application Bookinfo et ajoutez-le à la ressource ServiceMeshMemberRoll
. L'exemple d'application permet d'illustrer les concepts de sécurité.
1.13.1. À propos de la sécurité mutuelle de la couche transport (mTLS)
Mutual Transport Layer Security (mTLS) est un protocole qui permet à deux parties de s'authentifier mutuellement. Il s'agit du mode d'authentification par défaut dans certains protocoles (IKE, SSH) et facultatif dans d'autres (TLS). Vous pouvez utiliser mTLS sans modifier le code de l'application ou du service. Le TLS est entièrement géré par l'infrastructure du service mesh et entre les deux proxys sidecar.
Par défaut, mTLS dans Red Hat OpenShift Service Mesh est activé et configuré en mode permissif, où les sidecars dans Service Mesh acceptent à la fois le trafic en texte clair et les connexions qui sont chiffrées à l'aide de mTLS. Si un service dans votre maillage communique avec un service en dehors du maillage, un mTLS strict pourrait interrompre la communication entre ces services. Utilisez le mode permissif pendant que vous migrez vos charges de travail vers Service Mesh. Ensuite, vous pouvez activer mTLS strict dans votre maillage, votre espace de noms ou votre application.
L'activation de mTLS dans votre maillage au niveau du plan de contrôle du maillage de services sécurise l'ensemble du trafic dans votre maillage de services sans réécrire vos applications et charges de travail. Vous pouvez sécuriser les espaces de noms dans votre maillage au niveau du plan de données dans la ressource ServiceMeshControlPlane
. Pour personnaliser les connexions de cryptage du trafic, configurez les espaces de noms au niveau de l'application avec les ressources PeerAuthentication
et DestinationRule
.
1.13.1.1. Activation de mTLS strict à travers le maillage de services
Si vos charges de travail ne communiquent pas avec des services externes, vous pouvez rapidement activer mTLS à travers votre maillage sans interruption de la communication. Vous pouvez l'activer en définissant spec.security.dataPlane.mtls
sur true
dans la ressource ServiceMeshControlPlane
. L'opérateur crée les ressources nécessaires.
apiVersion: maistra.io/v2 kind: ServiceMeshControlPlane spec: version: v2.3 security: dataPlane: mtls: true
Vous pouvez également activer mTLS en utilisant la console web d'OpenShift Container Platform.
Procédure
- Connectez-vous à la console web.
- Cliquez sur le menu Project et sélectionnez le projet dans lequel vous avez installé le plan de contrôle Service Mesh, par exemple istio-system.
-
Cliquez sur Operators
Installed Operators. - Cliquez sur Service Mesh Control Plane sous Provided APIs.
-
Cliquez sur le nom de votre ressource
ServiceMeshControlPlane
, par exemplebasic
. - Sur la page Details, cliquez sur la bascule dans la section Security pour Data Plane Security.
1.13.1.1.1. Configuration des sidecars pour les connexions entrantes pour des services spécifiques
Vous pouvez également configurer mTLS pour des services individuels en créant une politique.
Procédure
Créez un fichier YAML à l'aide de l'exemple suivant.
Politique d'authentification par les pairs exemple policy.yaml
apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: default namespace: <namespace> spec: mtls: mode: STRICT
-
Remplacez
<namespace>
par l'espace de noms dans lequel se trouve le service.
-
Remplacez
Exécutez la commande suivante pour créer la ressource dans l'espace de noms où se trouve le service. Elle doit correspondre au champ
namespace
de la ressource Policy que vous venez de créer.$ oc create -n <namespace> -f <policy.yaml>
Si vous n'utilisez pas mTLS automatique et que vous définissez PeerAuthentication
sur STRICT, vous devez créer une ressource DestinationRule
pour votre service.
1.13.1.1.2. Configuration des sidecars pour les connexions sortantes
Créez une règle de destination pour configurer Service Mesh afin qu'il utilise mTLS lors de l'envoi de requêtes à d'autres services dans le maillage.
Procédure
Créez un fichier YAML à l'aide de l'exemple suivant.
Exemple de règle de destination destination-rule.yaml
apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: default namespace: <namespace> spec: host: "*.<namespace>.svc.cluster.local" trafficPolicy: tls: mode: ISTIO_MUTUAL
-
Remplacez
<namespace>
par l'espace de noms dans lequel se trouve le service.
-
Remplacez
Exécutez la commande suivante pour créer la ressource dans l'espace de noms où se trouve le service. Elle doit correspondre au champ
namespace
de la ressourceDestinationRule
que vous venez de créer.$ oc create -n <namespace> -f <destination-rule.yaml>
1.13.1.1.3. Définition des versions minimale et maximale du protocole
Si votre environnement a des exigences spécifiques pour le trafic crypté dans votre maillage de services, vous pouvez contrôler les fonctions cryptographiques autorisées en définissant les valeurs spec.security.controlPlane.tls.minProtocolVersion
ou spec.security.controlPlane.tls.maxProtocolVersion
dans votre ressource ServiceMeshControlPlane
. Ces valeurs, configurées dans votre ressource de plan de contrôle Service Mesh, définissent la version TLS minimale et maximale utilisée par les composants du maillage lorsqu'ils communiquent de manière sécurisée via TLS.
La valeur par défaut est TLS_AUTO
et ne spécifie pas de version de TLS.
Valeur | Description |
---|---|
| par défaut |
| TLS version 1.0 |
| TLS version 1.1 |
| TLS version 1.2 |
| TLS version 1.3 |
Procédure
- Connectez-vous à la console web.
- Cliquez sur le menu Project et sélectionnez le projet dans lequel vous avez installé le plan de contrôle Service Mesh, par exemple istio-system.
-
Cliquez sur Operators
Installed Operators. - Cliquez sur Service Mesh Control Plane sous Provided APIs.
-
Cliquez sur le nom de votre ressource
ServiceMeshControlPlane
, par exemplebasic
. - Cliquez sur l'onglet YAML.
Insérez l'extrait de code suivant dans l'éditeur YAML. Remplacez la valeur de
minProtocolVersion
par la valeur de la version TLS. Dans cet exemple, la version TLS minimale est fixée àTLSv1_2
.ServiceMeshControlPlane snippet
kind: ServiceMeshControlPlane spec: security: controlPlane: tls: minProtocolVersion: TLSv1_2
- Cliquez sur Save.
- Cliquez sur Refresh pour vérifier que les modifications ont été correctement mises à jour.
1.13.1.2. Valider le chiffrement avec Kiali
La console Kiali offre plusieurs moyens de vérifier si vos applications, services et charges de travail ont activé le chiffrement mTLS.
Figure 1.5. Icône de l'en-tête mTLS activé à l'échelle de la maille
Sur le côté droit de l'en-tête, Kiali affiche une icône de cadenas lorsque le maillage a strictement activé mTLS pour l'ensemble du maillage de services. Cela signifie que toutes les communications dans le maillage utilisent mTLS.
Figure 1.6. Icône de l'en-tête maillage mTLS partiellement activé
Kiali affiche une icône de cadenas creux lorsque le maillage est configuré en mode PERMISSIVE
ou qu'il y a une erreur dans la configuration mTLS du maillage.
Figure 1.7. Badge de sécurité
La page Graph offre la possibilité d'afficher un badge Security sur les bords du graphique pour indiquer que mTLS est activé. Pour activer les badges de sécurité sur le graphique, dans le menu Display, sous Show Badges, cochez la case Security. Lorsqu'une arête affiche une icône de cadenas, cela signifie qu'au moins une requête avec mTLS activé est présente. S'il y a à la fois des requêtes mTLS et des requêtes non mTLS, le panneau latéral indique le pourcentage de requêtes utilisant mTLS.
La page Applications Detail Overview affiche une icône Security sur les bords du graphique lorsqu'au moins une requête avec mTLS activé est présente.
La page Workloads Detail Overview affiche une icône Security sur les bords du graphique lorsqu'au moins une requête avec mTLS activé est présente.
La page Services Detail Overview affiche une icône Security sur les bords du graphique lorsqu'au moins une requête avec mTLS activé est présente. Notez également que Kiali affiche une icône de verrouillage dans la section Network à côté des ports configurés pour mTLS.
1.13.2. Configuration du contrôle d'accès basé sur les rôles (RBAC)
Les objets de contrôle d'accès basé sur les rôles (RBAC) déterminent si un utilisateur ou un service est autorisé à effectuer une action donnée au sein d'un projet. Vous pouvez définir un contrôle d'accès à l'échelle du maillage, de l'espace de noms et de la charge de travail pour vos charges de travail dans le maillage.
Pour configurer RBAC, créez une ressource AuthorizationPolicy
dans l'espace de noms pour lequel vous configurez l'accès. Si vous configurez un accès à l'échelle de la maille, utilisez le projet dans lequel vous avez installé le plan de contrôle Service Mesh, par exemple istio-system
.
Par exemple, avec RBAC, vous pouvez créer des politiques qui.. :
- Configurer la communication au sein du projet.
- Autoriser ou refuser l'accès complet à toutes les charges de travail dans l'espace de noms par défaut.
- Autoriser ou refuser l'accès à la passerelle d'entrée.
- Exiger un jeton pour l'accès.
Une politique d'autorisation comprend un sélecteur, une action et une liste de règles :
-
Le champ
selector
indique la cible de la politique. -
Le champ
action
indique s'il faut autoriser ou refuser la demande. Le champ
rules
précise le moment où l'action doit être déclenchée.-
Le champ
from
précise les contraintes relatives à l'origine de la demande. -
Le champ
to
précise les contraintes relatives à la cible et aux paramètres de la demande. -
Le champ
when
spécifie des conditions supplémentaires pour l'application de la règle.
-
Le champ
Procédure
Créez votre ressource
AuthorizationPolicy
. L'exemple suivant montre une ressource qui met à jour la politique d'entréeAuthorizationPolicy
pour interdire à une adresse IP d'accéder à la passerelle d'entrée.apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: ingress-policy namespace: istio-system spec: selector: matchLabels: app: istio-ingressgateway action: DENY rules: - from: - source: ipBlocks: ["1.2.3.4"]
Exécutez la commande suivante après avoir écrit votre ressource pour la créer dans votre espace de noms. L'espace de noms doit correspondre au champ
metadata.namespace
de la ressourceAuthorizationPolicy
.$ oc create -n istio-system -f <filename>
Prochaines étapes
Les exemples suivants illustrent d'autres configurations courantes.
1.13.2.1. Configurer la communication au sein du projet
Vous pouvez utiliser AuthorizationPolicy
pour configurer le plan de contrôle de votre Service Mesh afin d'autoriser ou de refuser le trafic communiquant avec votre maillage ou les services de votre maillage.
1.13.2.1.1. Restreindre l'accès aux services en dehors d'un espace de noms
Vous pouvez refuser les demandes provenant de toute source qui n'appartient pas à l'espace de noms info
avec l'exemple de ressource AuthorizationPolicy
suivant.
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: httpbin-deny namespace: info spec: selector: matchLabels: app: httpbin version: v1 action: DENY rules: - from: - source: notNamespaces: ["info"]
1.13.2.1.2. Création de politiques d'autorisation "allow-all" et "deny-all" par défaut
L'exemple suivant montre une politique d'autorisation "allow-all" qui permet un accès complet à toutes les charges de travail dans l'espace de noms info
.
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-all namespace: info spec: action: ALLOW rules: - {}
L'exemple suivant montre une stratégie qui refuse tout accès à toutes les charges de travail dans l'espace de noms info
.
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: deny-all namespace: info spec: {}
1.13.2.2. Autoriser ou refuser l'accès à la passerelle d'entrée
Vous pouvez définir une politique d'autorisation pour ajouter des listes d'autorisation ou de refus basées sur les adresses IP.
apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: ingress-policy namespace: istio-system spec: selector: matchLabels: app: istio-ingressgateway action: ALLOW rules: - from: - source: ipBlocks: ["1.2.3.4", "5.6.7.0/24"]
1.13.2.3. Restreindre l'accès avec un jeton Web JSON
Vous pouvez restreindre l'accès à votre maillage à l'aide d'un jeton Web JSON (JWT). Après authentification, un utilisateur ou un service peut accéder aux routes et aux services associés à ce jeton.
Créez une ressource RequestAuthentication
, qui définit les méthodes d'authentification prises en charge par une charge de travail. L'exemple suivant accepte un JWT émis par http://localhost:8080/auth/realms/master
.
apiVersion: "security.istio.io/v1beta1" kind: "RequestAuthentication" metadata: name: "jwt-example" namespace: info spec: selector: matchLabels: app: httpbin jwtRules: - issuer: "http://localhost:8080/auth/realms/master" jwksUri: "http://keycloak.default.svc:8080/auth/realms/master/protocol/openid-connect/certs"
Ensuite, créez une ressource AuthorizationPolicy
dans le même espace de noms pour travailler avec la ressource RequestAuthentication
que vous avez créée. L'exemple suivant exige qu'un JWT soit présent dans l'en-tête Authorization
lors de l'envoi d'une requête aux charges de travail httpbin
.
apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "frontend-ingress" namespace: info spec: selector: matchLabels: app: httpbin action: DENY rules: - from: - source: notRequestPrincipals: ["*"]
1.13.3. Configuration des suites de chiffrement et des courbes ECDH
Les suites de chiffrement et les courbes de Diffie-Hellman à courbe elliptique (courbes ECDH) peuvent vous aider à sécuriser votre maillage de services. Vous pouvez définir une liste séparée par des virgules de suites de chiffrement en utilisant spec.security.controlplane.tls.cipherSuites
et de courbes ECDH en utilisant spec.security.controlplane.tls.ecdhCurves
dans votre ressource ServiceMeshControlPlane
. Si l'un de ces attributs est vide, les valeurs par défaut sont utilisées.
Le paramètre cipherSuites
est efficace si votre maillage de services utilise TLS 1.2 ou une version antérieure. Il n'a aucun effet lors de la négociation avec TLS 1.3.
Définissez vos suites de chiffrement dans la liste séparée par des virgules, par ordre de priorité. Par exemple, ecdhCurves: CurveP256, CurveP384
donne à CurveP256
une priorité plus élevée que CurveP384
.
Vous devez inclure TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
ou TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
lorsque vous configurez la suite de chiffrement. La prise en charge de HTTP/2 nécessite au moins l'une de ces suites de chiffrement.
Les suites de chiffrement prises en charge sont les suivantes
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
- TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
- TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
- TLS_RSA_WITH_AES_128_GCM_SHA256
- TLS_RSA_WITH_AES_256_GCM_SHA384
- TLS_RSA_WITH_AES_128_CBC_SHA256
- TLS_RSA_WITH_AES_128_CBC_SHA
- TLS_RSA_WITH_AES_256_CBC_SHA
- TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
- TLS_RSA_WITH_3DES_EDE_CBC_SHA
Les courbes ECDH prises en charge sont les suivantes :
- CourbeP256
- CourbeP384
- CourbeP521
- X25519
1.13.4. Ajout d'une clé et d'un certificat d'une autorité de certification externe
Par défaut, Red Hat OpenShift Service Mesh génère un certificat racine et une clé auto-signés et les utilise pour signer les certificats de charge de travail. Vous pouvez également utiliser le certificat et la clé définis par l'utilisateur pour signer les certificats de charge de travail avec le certificat racine défini par l'utilisateur. Cette tâche présente un exemple d'insertion de certificats et de clés dans Service Mesh.
Conditions préalables
- Installez Red Hat OpenShift Service Mesh avec TLS mutuel activé pour configurer les certificats.
- Cet exemple utilise les certificats du référentiel Maistra. Pour la production, utilisez vos propres certificats provenant de votre autorité de certification.
- Déployez l'application d'exemple Bookinfo pour vérifier les résultats à l'aide de ces instructions.
- OpenSSL est nécessaire pour vérifier les certificats.
1.13.4.1. Ajouter un certificat et une clé existants
Pour utiliser un certificat et une clé de signature (CA) existants, vous devez créer un fichier de chaîne de confiance qui inclut le certificat CA, la clé et le certificat racine. Vous devez utiliser les noms de fichiers exacts suivants pour chacun des certificats correspondants. Le certificat CA est nommé ca-cert.pem
, la clé est ca-key.pem
, et le certificat racine, qui signe ca-cert.pem
, est nommé root-cert.pem
. Si votre charge de travail utilise des certificats intermédiaires, vous devez les spécifier dans un fichier cert-chain.pem
.
-
Enregistrez localement les certificats d'exemple du référentiel Maistra et remplacez
<path>
par le chemin d'accès à vos certificats. Créez un secret nommé
cacert
qui comprend les fichiers d'entréeca-cert.pem
,ca-key.pem
,root-cert.pem
etcert-chain.pem
.$ oc create secret generic cacerts -n istio-system --from-file=<path>/ca-cert.pem \ --from-file=<path>/ca-key.pem --from-file=<path>/root-cert.pem \ --from-file=<path>/cert-chain.pem
Dans la ressource
ServiceMeshControlPlane
, définissezspec.security.dataPlane.mtls true
commetrue
et configurez le champcertificateAuthority
comme indiqué dans l'exemple suivant. La valeur par défaut derootCADir
est/etc/cacerts
. Il n'est pas nécessaire de définir le champprivateKey
si la clé et les certificats sont montés à l'emplacement par défaut. Service Mesh lit les certificats et la clé à partir des fichiers secret-mount.apiVersion: maistra.io/v2 kind: ServiceMeshControlPlane spec: security: dataPlane: mtls: true certificateAuthority: type: Istiod istiod: type: PrivateKey privateKey: rootCADir: /etc/cacerts
Après avoir créé/modifié/supprimé le secret
cacert
, les pods de plan de contrôle Service Meshistiod
etgateway
doivent être redémarrés pour que les modifications soient prises en compte. Utilisez la commande suivante pour redémarrer les modules :$ oc -n istio-system delete pods -l 'app in (istiod,istio-ingressgateway, istio-egressgateway)'
L'Opérateur recréera automatiquement les pods après qu'ils aient été supprimés.
Redémarrez les pods d'application info pour que les proxies sidecar récupèrent les changements de secret. Utilisez la commande suivante pour redémarrer les modules :
$ oc -n info delete pods --all
Vous devriez obtenir un résultat similaire à celui qui suit :
pod "details-v1-6cd699df8c-j54nh" deleted pod "productpage-v1-5ddcb4b84f-mtmf2" deleted pod "ratings-v1-bdbcc68bc-kmng4" deleted pod "reviews-v1-754ddd7b6f-lqhsv" deleted pod "reviews-v2-675679877f-q67r2" deleted pod "reviews-v3-79d7549c7-c2gjs" deleted
Vérifiez que les pods ont été créés et sont prêts avec la commande suivante :
$ oc get pods -n info
1.13.4.2. Vérification des certificats
Utilisez l'exemple d'application Bookinfo pour vérifier que les certificats de charge de travail sont signés par les certificats qui ont été insérés dans l'autorité de certification. Pour ce faire, vous devez avoir installé openssl
sur votre machine
Pour extraire les certificats des charges de travail info, utilisez la commande suivante :
$ sleep 60 $ oc -n info exec "$(oc -n bookinfo get pod -l app=productpage -o jsonpath={.items..metadata.name})" -c istio-proxy -- openssl s_client -showcerts -connect details:9080 > bookinfo-proxy-cert.txt $ sed -n '/-----BEGIN CERTIFICATE-----/{:start /-----END CERTIFICATE-----/!{N;b start};/.*/p}' info-proxy-cert.txt > certs.pem $ awk 'BEGIN {counter=0;} /BEGIN CERT/{counter++} { print > "proxy-cert-" counter ".pem"}' < certs.pem
Après avoir exécuté la commande, vous devriez avoir trois fichiers dans votre répertoire de travail :
proxy-cert-1.pem
proxy-cert-2.pem
etproxy-cert-3.pem
.Vérifiez que le certificat racine est le même que celui spécifié par l'administrateur. Remplacez
<path>
par le chemin d'accès à vos certificats.$ openssl x509 -in <path>/root-cert.pem -text -noout > /tmp/root-cert.crt.txt
Exécutez la syntaxe suivante dans la fenêtre du terminal.
$ openssl x509 -in ./proxy-cert-3.pem -text -noout > /tmp/pod-root-cert.crt.txt
Comparez les certificats en exécutant la syntaxe suivante dans la fenêtre du terminal.
$ diff -s /tmp/root-cert.crt.txt /tmp/pod-root-cert.crt.txt
Vous devriez obtenir le résultat suivant :
Files /tmp/root-cert.crt.txt and /tmp/pod-root-cert.crt.txt are identical
Vérifiez que le certificat de l'autorité de certification est le même que celui spécifié par l'administrateur. Remplacez
<path>
par le chemin d'accès à vos certificats.$ openssl x509 -in <path>/ca-cert.pem -text -noout > /tmp/ca-cert.crt.txt
Exécutez la syntaxe suivante dans la fenêtre du terminal.
openssl x509 -in ./proxy-cert-2.pem -text -noout > /tmp/pod-cert-chain-ca.crt.txt
Comparez les certificats en exécutant la syntaxe suivante dans la fenêtre du terminal.
$ diff -s /tmp/ca-cert.crt.txt /tmp/pod-cert-chain-ca.crt.txt
Vous devriez obtenir le résultat suivant :
Files /tmp/ca-cert.crt.txt and /tmp/pod-cert-chain-ca.crt.txt are identical.
Vérifiez la chaîne de certificats depuis le certificat racine jusqu'au certificat de charge de travail. Remplacez
<path>
par le chemin d'accès à vos certificats.$ openssl verify -CAfile <(cat <path>/ca-cert.pem <path>/root-cert.pem) ./proxy-cert-1.pem
Vous devriez obtenir le résultat suivant :
./proxy-cert-1.pem: OK
1.13.4.3. Suppression des certificats
Pour supprimer les certificats que vous avez ajoutés, procédez comme suit.
Supprimez le secret
cacerts
. Dans cet exemple,istio-system
est le nom du projet de plan de contrôle Service Mesh.$ oc delete secret cacerts -n istio-system
Redéployer Service Mesh avec un certificat racine auto-signé dans la ressource
ServiceMeshControlPlane
.apiVersion: maistra.io/v2 kind: ServiceMeshControlPlane spec: security: dataPlane: mtls: true