Intégrer IAP avec Cloud Service Mesh
Ce guide explique comment intégrer Identity-Aware Proxy (IAP) à Cloud Service Mesh. L'intégration d'IAP à Cloud Service Mesh vous permet d'accéder en toute sécurité aux services conformément aux principes de BeyondCorp de Google. IAP vérifie l'identité de l'utilisateur et le contexte de la requête pour déterminer si cet utilisateur doit être autorisé à accéder à une application ou à une ressource. L'intégration d'IAP à Cloud Service Mesh offre les avantages suivants:
Contrôle complet de l'accès contextuel aux charges de travail exécutées sur Cloud Service Mesh. Vous pouvez définir des règles d'accès précises en fonction d'attributs de la requête d'origine, tels que l'identité de l'utilisateur, l'adresse IP et le type d'appareil. Vous pouvez combiner vos règles d'accès avec des restrictions basées sur le nom d'hôte et le chemin d'une URL de requête.
Activez la compatibilité des revendications contextuelles dans l'autorisation Cloud Service Mesh.
Accès évolutif, sécurisé et hautement disponible à votre application via un équilibreur de charge Google Cloud. L'équilibrage de charge hautes performances offre une protection intégrée contre les attaques par déni de service distribué (DDoS) et une compatibilité avec l'adressage IP Anycast.
Prérequis
Suivez les étapes de la page Installer les outils dépendants et valider le cluster pour effectuer les opérations suivantes :- Installer les outils nécessaires
- Télécharger
asmcli
- Accorder des autorisations d'administrateur de cluster
- Valider votre projet et votre cluster
Dans ce guide, nous partons également du principe que vous disposez des éléments suivants :
Configurer un cluster avec Cloud Service Mesh
Cette section explique comment configurer l'intégration IAP pour les nouvelles installations de Cloud Service Mesh et les mises à niveau.
Nouvelles installations
Activer
iap.googleapis.com
Dans la commande suivante, remplacezPROJECT_ID
par le projet dans lequel vous allez installer Cloud Service Mesh:gcloud services enable \ --project=PROJECT_ID \ iap.googleapis.com
L'option
--addons=HttpLoadBalancing
doit être définie pur le cluster que vous mettez à jour. Le module complémentaireHttpLoadBalancing
active un contrôleur d'équilibrage de charge HTTP (L7) pour le cluster. Exécutez la commande suivante pour mettre à jour le cluster avec les options requises par Cloud Service Mesh : À moins que vous n'ayez défini une zone ou une région par défaut, vous devez indiquer la région (--region=REGION) ou la zone (--zone=ZONE) dans la commande.gcloud container clusters update CLUSTER_NAME \ --project=PROJECT_ID \ --update-addons=HttpLoadBalancing=ENABLED
Par défaut, le fichier
iap-operator.yaml
a comme port d'état le port 31223 et le port 31224 en tant que port http. Si le port 31223 est déjà utilisé dans votre cluster, exécutez la commande suivante pour définir un autre port d'état :kpt cfg set asm gcloud.container.cluster.ingress.statusPort STATUS_PORT
Si le port 31224 est déjà utilisé dans votre cluster, exécutez la commande suivante pour définir un autre port HTTP:
kpt cfg set asm gcloud.container.cluster.ingress.httpPort HTTP_PORT
Suivez les étapes de la page Installer les fonctionnalités par défaut et Mesh CA pour installer Cloud Service Mesh à l'aide d'un script fourni par Google. Lorsque vous exécutez le script, incluez l'option suivante :
--option iap-operator
Exemple :
./asmcli install \ --project_id "PROJECT_ID" \ --cluster_name "CLUSTER_NAME" \ --cluster_location "CLUSTER_LOCATION" \ --fleet_id FLEET_PROJECT_ID \ --output_dir DIR_PATH \ --enable_all \ --option iap-operator
Lorsque vous installez Cloud Service Mesh, le fichier
iap-operator.yaml
définit le champtype
du serviceistio-ingressgateway
surNodePort
, ce qui configure la passerelle pour qu'elle ouvre un port spécifique sur le maillage de services. Cela vous permet de configurer un équilibreur de charge qui achemine le trafic envoyé à votre nom de domaine vers ce port.Si vous installez Cloud Service Mesh géré, effectuez également la procédure suivante:
Appliquez le libellé de révision à l'espace de noms
istio-system
.Téléchargez les spécifications du service de passerelle d'entrée Istio pour IAP et nommez le fichier
iap_operator.yaml
.Installez l'entrée en tant que service NodePort. Pour en savoir plus, consultez la page Migrer depuis IstioOperator.
asmcli experimental mcp-migrate-check -f iap_operator.yaml istioctl install -f /asm-generated-configs/gateways-istiooperator/"GATEWAY_NAME".yaml
Après avoir installé Cloud Service Mesh, revenez à ce guide et passez à la section suivante pour configurer l'intégration avec IAP.
Mises à niveau
Cette section couvre les cas d'utilisation suivants pour la mise à niveau :
Vous avez déjà configuré l'intégration IAP et vous mettez à niveau Cloud Service Mesh. Dans ce cas, vous avez déjà activé
iap.googleapis.com
sur votre projet et le module complémentaireHttpLoadBalancing
sur votre cluster. Passez à l'étape 3 pour télécharger le packageasm
et mettre à niveau Cloud Service Mesh.Vous mettez à niveau Cloud Service Mesh et souhaitez configurer l'intégration avec IAP pour la première fois. Dans ce cas, vous devez suivre toutes les étapes ci-dessous, mettre à niveau Cloud Service Mesh et revenir à ce guide après la mise à niveau pour terminer l'intégration.
Activer
iap.googleapis.com
Dans la commande suivante, remplacezPROJECT_ID
par le projet dans lequel vous allez installer Cloud Service Mesh.gcloud services enable \ --project=PROJECT_ID \ iap.googleapis.com
L'option
--addons=HttpLoadBalancing
doit être définie pur le cluster que vous mettez à jour. Le module complémentaireHttpLoadBalancing
active un contrôleur d'équilibrage de charge HTTP (L7) pour le cluster. Exécutez la commande suivante pour mettre à jour le cluster avec les options requises par Cloud Service Mesh : À moins que vous n'ayez défini une zone ou une région par défaut, vous devez indiquer la région (--region=REGION) ou la zone (--zone=ZONE) dans la commande.gcloud container clusters update CLUSTER_NAME \ --project=PROJECT_ID --update-addons=HttpLoadBalancing=ENABLED
Si vous mettez à jour un équilibreur de charge Cloud HTTP existant, exécutez la commande suivante pour conserver vos ports HTTP et d'état existants:
kpt cfg set asm gcloud.container.cluster.ingress.httpPort $(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
kpt cfg set asm gcloud.container.cluster.ingress.statusPort $(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="status-port")].nodePort}')
Suivez les étapes de la page Mettre à niveau Cloud Service Mesh afin d'utiliser un script fourni par Google pour mettre à niveau Cloud Service Mesh.
Lorsque vous mettez à niveau Cloud Service Mesh, le fichier
iap-operator.yaml
définit le champtype
du serviceistio-ingressgateway
surNodePort
, ce qui configure la passerelle pour qu'elle ouvre un port spécifique sur le maillage de services. Cela vous permet de configurer un équilibreur de charge qui achemine le trafic envoyé à votre nom de domaine vers ce port.Par défaut, le fichier
iap-operator.yaml
a comme port d'état le port 31223 et le port 31224 en tant que port http.Lorsque vous exécutez le script, incluez l'option suivante :
--option iap-operator
Exemple :
./asmcli install \ --project_id "PROJECT_ID" \ --cluster_name "CLUSTER_NAME" \ --cluster_location "CLUSTER_LOCATION" \ --fleet_id FLEET_PROJECT_ID \ --output_dir DIR_PATH \ --enable_all \ --option iap-operator
Terminez la mise à niveau en déclenchant l'injection automatique de proxy side-car sur vos charges de travail. Pour en savoir plus, consultez la page Déployer et redéployer des charges de travail.
Une fois la mise à niveau terminée, revenez à ce guide et passez à la section suivante pour configurer l'intégration avec IAP.
Réserver une adresse IP statique et configurer le DNS
Pour intégrer Identity-Aware Proxy à Cloud Service Mesh, vous devez configurer un équilibreur de charge HTTP(S) Google Cloud qui nécessite un nom de domaine pointant vers une adresse IP statique. Vous pouvez réserver une adresse IP externe statique, qui est alors attribuée à votre projet pour une durée indéterminée, jusqu'à ce que vous la libériez explicitement.
Réservez une adresse IP externe statique :
gcloud compute addresses create example-static-ip --global
Obtenez l'adresse IP statique :
gcloud compute addresses describe example-static-ip --global
Dans votre service d'enregistrement de noms de domaine, configurez un nom de domaine complet avec l'adresse IP statique. En règle générale, vous ajoutez un enregistrement
A
à vos paramètres DNS. Les étapes de configuration et la terminologie permettant d'ajouter un enregistrementA
pour un nom de domaine complet varient selon votre service d'enregistrement de noms de domaine.La propagation du paramètre DNS peut prendre entre 24 et 48 heures. Vous pouvez continuer à tout configurer dans ce guide, mais vous ne pouvez pas tester la configuration tant que les paramètres DNS ne sont pas propagés.
Déployer un exemple d'application
Avant d'activer IAP, vous avez besoin d'une application s'exécutant sur votre cluster GKE afin de vérifier que toutes les requêtes ont une identité. Ce guide utilise l'exemple de Bookinfo pour montrer comment configurer l'équilibreur de charge HTTP(S) et activer IAP.
Suivez les étapes pour déployer Bookinfo. Tant que vous n'avez pas déployé l'équilibreur de charge, l'application Bookinfo n'est pas accessible en dehors de votre cluster GKE (par exemple, depuis un navigateur).
Demandes externes
La ressource de passerelle de Bookinfo (définie dans samples/bookinfo/networking/bookinfo-gateway.yaml
) utilise la valeur istio-ingressgateway
préconfigurée.
Rappelez-vous que lorsque vous avez déployé Cloud Service Mesh, vous avez spécifié NodePort
pour istio-ingressgateway
, qui ouvre un port spécifique sur le maillage de services.
Bien que les nœuds de votre cluster aient des adresses IP externes, les requêtes provenant de l'extérieur de votre cluster sont bloquées par les règles de pare-feu Google Cloud. Avec IAP, le bon moyen d'exposer des applications à l'Internet public est d'utiliser un équilibreur de charge. N'exposez pas les adresses de nœud à l'aide de règles de pare-feu qui contournent IAP.
Pour acheminer les requêtes vers Bookinfo, vous devez configurer un équilibreur de charge HTTP(S) dans votre projet Google Cloud. Étant donné que l'équilibreur de charge se trouve dans votre projet, il se trouve dans le pare-feu et peut accéder aux nœuds de votre cluster. Une fois que vous avez configuré l'équilibreur de charge avec l'adresse IP statique et le nom de domaine, vous pouvez envoyer des requêtes au nom de domaine. L'équilibreur de charge transfère les requêtes aux nœuds du cluster.
Activer IAP
La procédure suivante explique comment activer IAP.
Configurer l'écran d'autorisation
Vérifiez que vous disposez déjà d'une marque à l'aide de la commande list. Vous ne pouvez disposer que d'une seule marque par projet.
gcloud iap oauth-brands list
Voici un exemple de réponse gcloud, si la marque existe :
name: projects/[PROJECT_NUMBER]/brands/[BRAND_ID] applicationTitle: [APPLICATION_TITLE] supportEmail: [SUPPORT_EMAIL] orgInternalOnly: true
Si aucune marque n'existe, utilisez la commande create :
gcloud iap oauth-brands create --application_title=APPLICATION_TITLE --support_email=SUPPORT_EMAIL
Les champs ci-dessus sont obligatoires lors de l'appel de cette API :
supportEmail
: l'adresse e-mail d'assistance affichée sur l'écran d'autorisation OAuth. Il peut s'agir de l'adresse e-mail d'un utilisateur ou d'un alias d'adresses e-mail de Google Groupes. Bien que les comptes de service possèdent également une adresse e-mail, celles-ci ne sont pas valides et ne peuvent pas être utilisées lors de la création d'une marque. Toutefois, un compte de service peut être propriétaire d'un groupe Google. Créez un groupe Google ou configurez un groupe existant, puis définissez le compte de service souhaité en tant que propriétaire du groupe.applicationTitle
: nom de l'application affiché sur l'écran d'autorisation OAuth.
La réponse contient les champs suivants :
name: projects/[PROJECT_NUMBER]/brands/[BRAND_ID] applicationTitle: [APPLICATION_TITLE] supportEmail: [SUPPORT_EMAIL] orgInternalOnly: true
Créer un client OAuth IAP
Utilisez la commande "create" pour créer un client. Utilisez la marque
name
de l'étape précédente.gcloud iap oauth-clients create projects/PROJECT_NUMBER/brands/BRAND-ID --display_name=NAME
La réponse contient les champs suivants :
name: projects/[PROJECT_NUMBER]/brands/[BRAND_NAME]/identityAwareProxyClients/[CLIENT_ID] secret: [CLIENT_SECRET] displayName: [NAME]
Utilisez l'ID client (
CLIENT_ID
dans l'exemple ci-dessus) et leCLIENT_SECRET
pour activer IAP. Créez un secret Kubernetes avec les ressources de votre client OAuth :kubectl create secret generic -n istio-system my-secret --from-literal=client_id=CLIENT_ID \ --from-literal=client_secret=CLIENT_SECRET
Déployer l'équilibreur de charge
Vous pouvez utiliser une ressource Ingress pour créer un équilibreur de charge HTTP(S) avec des certificats SSL automatiquement configurés. Les certificats SSL gérés par Google sont provisionnés, renouvelés et gérés pour votre domaine.
Créez une ressource ManagedCertificate. Cette ressource spécifie le domaine du certificat SSL. La liste
spec.domains
ne doit contenir qu'un seul domaine. Les domaines avec des caractères génériques ne sont pas acceptés. Dans le fichier YAML suivant, remplacezDOMAIN_NAME
par le nom de domaine que vous avez configuré pour l'adresse IP statique externe.cat <<EOF | kubectl apply -f - apiVersion: networking.gke.io/v1 kind: ManagedCertificate metadata: name: example-certificate namespace: istio-system spec: domains: - DOMAIN_NAME EOF
Créez une ressource BackendConfig. Cette ressource indique à GCLB comment effectuer des vérifications d'état sur la passerelle d'entrée et configurer Identity-Aware Proxy. Commencez par collecter quelques valeurs de la passerelle d'entrée sur les vérifications d'état :
Port d'entrée de la vérification de l'état : port utilisé pour la vérification de l'état d'istio-ingress.
export HC_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="status-port")].nodePort}')
Chemin d'entrée de la vérification de l'état : chemin de la vérification de l'état d'istio-ingress.
export HC_INGRESS_PATH=$(kubectl get pods -n istio-system -l app=istio-ingressgateway -o jsonpath='{.items[0].spec.containers[?(@.name=="istio-proxy")].readinessProbe.httpGet.path}')
cat <<EOF | kubectl apply -n istio-system -f - apiVersion: cloud.google.com/v1 kind: BackendConfig metadata: name: http-hc-config spec: healthCheck: checkIntervalSec: 2 timeoutSec: 1 healthyThreshold: 1 unhealthyThreshold: 10 port: ${HC_INGRESS_PORT} type: HTTP requestPath: ${HC_INGRESS_PATH} iap: enabled: true oauthclientCredentials: secretName: my-secret EOF
Annotez le service Ingress avec votre BackendConfig.
kubectl annotate -n istio-system service/istio-ingressgateway --overwrite \ cloud.google.com/backend-config='{"default": "http-hc-config"}' \ cloud.google.com/neg='{"ingress":false}'
Créez l'équilibreur de charge en définissant la ressource Ingress.
Définissez l'annotation
networking.gke.io/managed-certificates
sur le nom du certificat que vous avez créé à l'étape précédente,example-certificate
.Définissez l'annotation
kubernetes.io/ingress.global-static-ip-name
sur le nom de l'adresse IP statique que vous avez réservée,example-static-ip
.Définissez
serviceName
suristio-ingressgateway
, qui est utilisé dans la ressource de passerelle pour l'exemple Bookinfo.
cat <<EOF | kubectl apply -f - apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: example-ingress namespace: istio-system annotations: kubernetes.io/ingress.global-static-ip-name: example-static-ip networking.gke.io/managed-certificates: example-certificate spec: defaultBackend: service: name: istio-ingressgateway port: number: 80 EOF
Dans la console Google Cloud, accédez à la page Kubernetes Engine > Services et entrée :
Accéder à la page Services et entrée
Le message "Création d'entrée" doit s'afficher dans la colonne État. Attendez que GKE provisionne entièrement l'entrée avant de continuer. Actualisez la page toutes les deux ou trois minutes pour obtenir l'état le plus récent de l'entrée. Une fois l'entrée provisionnée, l'état "OK" ou le message d'erreur "Tous les services de backend sont DÉFAILLANTS" peut s'afficher. L'une des ressources provisionnées par GKE est une vérification de l'état par défaut. Si le message d'erreur s'affiche, cela signifie que l'entrée est provisionnée et que la vérification de l'état par défaut a été exécutée. Lorsque l'état "OK" ou le message d'erreur s'affiche, passez à la section suivante pour configurer les vérifications de l'état pour l'équilibreur de charge.
Configurer la liste d'accès IAP
Ajoutez un utilisateur à la règle d'accès pour IAP :
gcloud beta iap web add-iam-policy-binding \ --member=user:EMAIL_ADDRESS \ --role=roles/iap.httpsResourceAccessor
où EMAIL_ADDRESS
est l'adresse e-mail complète de l'utilisateur, telle que alice@example.com
.
Testez l'équilibreur de charge. Pointez votre navigateur sur :
http://DOMAIN_NAME/productpage
où
DOMAIN_NAME
est le nom de domaine que vous avez configuré avec l'adresse IP statique externe.Le service
productpage
de l'application Bookinfo devrait s'afficher. Si vous actualisez la page plusieurs fois, vous devriez voir différentes versions d'avis présentées à tour de rôle : étoiles rouges, étoiles noires, sans étoiles.Vous devez également tester l'accès
https
à Bookinfo.
Activer la compatibilité du jeton RCToken sur le maillage de services
Par défaut, IAP génère un jeton Web JSON (JWT) limité au client OAuth. Pour Cloud Service Mesh, vous pouvez configurer IAP pour générer un jeton RequestContextToken (RCToken), qui est un jeton JWT, mais avec une audience configurable. RCToken vous permet de configurer l'audience du jeton JWT vers une chaîne arbitraire, qui peut être utilisée dans les stratégies Cloud Service Mesh pour une autorisation précise.
Pour configurer le jeton RCToken, procédez comme suit :
Créez une variable d'environnement pour l'audience du jeton RCToken. Vous pouvez choisir n'importe quelle chaîne.
export RCTOKEN_AUD="your-rctoken-aud"
Facultatif : L'étape suivante nécessite la commande
BACKEND_SERVICE_ID
. Si vous devez connaître la valeur deBACKEND_SERVICE_ID
, exécutez la commande suivante :kubectl -n istio-system get Ingress example-ingress -o json | jq \ '.metadata.annotations."ingress.kubernetes.io/backends"'
Le résultat attendu est semblable à
"{\"BACKEND_SERVICE_ID\":\"HEALTHY\"}"
. Par exemple,"ingress.kubernetes.io/backends": "{\"k8s-be-31224--51f3b55cd1457fb6\":\"HEALTHY\"}"
. Dans cet exemple,BACKEND_SERVICE_ID
estk8s-be-31224--51f3b55cd1457fb6
.Récupérez les paramètres IAP existants.
gcloud iap settings get --format json \ --project=${PROJECT_ID} --resource-type=compute --service=BACKEND_SERVICE_ID > iapSettings.json
Mettez à jour
IapSettings
avec l'audience du jeton RCToken.cat iapSettings.json | jq --arg RCTOKEN_AUD_STR $RCTOKEN_AUD \ '. + {applicationSettings: {csmSettings: {rctokenAud: $RCTOKEN_AUD_STR}}}' \ > updatedIapSettings.json
gcloud iap settings set updatedIapSettings.json --format json \ --project=${PROJECT_ID} --resource-type=compute --service=BACKEND_SERVICE_ID
Activez l'authentification RCToken sur la passerelle d'entrée Istio.
cat <<EOF | kubectl apply -f - apiVersion: "security.istio.io/v1beta1" kind: "RequestAuthentication" metadata: name: "ingressgateway-jwt-policy" namespace: "istio-system" spec: selector: matchLabels: app: istio-ingressgateway jwtRules: - issuer: "https://cloud.google.com/iap" jwksUri: "https://www.gstatic.com/iap/verify/public_key-jwk" audiences: - $RCTOKEN_AUD fromHeaders: - name: ingress-authorization prefix: "Istio " outputPayloadToHeader: "verified-jwt" forwardOriginalToken: true EOF
Facultatif : assurez-vous que les requêtes ne disposant pas de jetons JWT valides sont rejetées :
cat <<EOF | kubectl apply -f - apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: iap-gateway-require-jwt namespace: istio-system spec: selector: matchLabels: app: istio-iap-ingressgateway action: DENY rules: - from: - source: notRequestPrincipals: ["*"] EOF
Assurez-vous que les requêtes adressées à Bookinfo
productpage
aboutissent :http://DOMAIN_NAME/productpage
Pour tester la stratégie, procédez comme suit :
Créez un objet de requête
IapSettings
, mais définissez la valeurrctokenAud
sur une chaîne différente :cat iapSettings.json | jq --arg RCTOKEN_AUD_STR wrong-rctoken-aud \ '. + {applicationSettings: {csmSettings: {rctokenAud: $RCTOKEN_AUD_STR}}}' \ > wrongIapSettings.json
Appelez l'API
IapSettings
pour définir l'audience du jeton RCToken.gcloud beta iap settings set wrongIapSettings.json --project=PROJECT_ID --resource-type=compute --service=BACKEND_SERVICE
Envoyez une requête au service
productpage
Bookinfo. Celle-ci devrait échouer :http://DOMAIN_NAME/productpage
Effectuer un nettoyage
Une fois ce tutoriel terminé, supprimez les ressources suivantes pour éviter que des frais supplémentaires ne soient facturés sur votre compte :
Supprimez le certificat géré :
kubectl delete managedcertificates example-certificate
Supprimez l'objet Ingress, ce qui libère les ressources d'équilibrage de charge :
kubectl -n istio-system delete ingress example-ingress
Supprimez l'adresse IP statique :
gcloud compute addresses delete example-static-ip --global
Si vous procédez ainsi, veillez à supprimer l'adresse IP de votre service d'enregistrement de noms de domaine.
Supprimez le cluster : cette étape supprime les ressources qui constituent le cluster, telles que les instances de calcul, les disques et les ressources réseau :
gcloud container clusters delete CLUSTER_NAME