Remarques :
- Ce tutoriel nécessite un accès à Oracle Cloud. Pour vous inscrire à un compte gratuit, reportez-vous à Introduction au niveau gratuit d'Oracle Cloud Infrastructure.
- Il utilise des exemples de valeur pour les informations d'identification, la location et les compartiments Oracle Cloud Infrastructure. A la fin de l'exercice, remplacez ces valeurs par des valeurs propres à votre environnement cloud.
Sécuriser les services Web Kubernetes à l'aide du contrôleur d'entrée Nginx, du proxy OAuth2 et des domaines d'identité Oracle
Introduction
La sécurisation des services Web hébergés par Kubernetes doit être facile. Que votre application ne prenne pas en charge l'intégration du fournisseur d'identités externe (IdP) ou que vous ayez besoin d'une solution d'accès avec connexion unique (SSO) pour simplifier la gestion et réduire le besoin de mécanismes d'authentification individuels par service, le proxy OAuth2 offre la flexibilité nécessaire pour connecter n'importe quelle application à presque n'importe quel fournisseur d'identités (IdP).
OAuth2 Le proxy agit en tant que proxy inverse devant vos services Kubernetes. Il intercepte le trafic, redirige les utilisateurs vers un serveur d'autorisation externe (comme Okta ou GitHub) pour la connexion et valide les jetons d'accès avant de transmettre les demandes aux services back-end.
Objectif
- Déployez une application Web simple sur Kubernetes, exposez-la à l'aide du contrôleur d'entrée Nginx et configurez le proxy OAuth2 pour utiliser les domaines d'identité Oracle en tant que IdP.
Prérequis
-
Accès à une location Oracle Cloud Infrastructure (OCI).
-
Cluster Oracle Cloud Infrastructure Container Engine for Kubernetes (OKE) configuré pour utiliser un sous-réseau public pour les équilibreurs de charge.
-
(Facultatif) Accès permettant de mettre à jour les enregistrements d'un domaine DNS.
Tâche 1 : créer un cluster OKE
-
Connectez-vous à la console OCI, accédez à Oracle Container Engine for Kubernetes et cliquez sur Créer.
-
Dans l'assistant Créer un cluster, cliquez sur Création rapide.
-
Entrez les informations ci-après et cliquez sur Suivant.
- Nom : entrez le nom du cluster.
- Version de Kubernetes : sélectionnez la version à utiliser.
- Adresses d'API Kubernetes : sélectionnez Adresse publique.
- Type de noeud : sélectionnez Géré.
- Noeuds de processus actif Kubernetes : sélectionnez Processus actifs privés.
- Nombre de noeuds :
1
.
-
Vérifiez et cliquez sur Créer un cluster. Attendez que le cluster soit disponible.
-
Mettez à jour la liste de sécurité associée au sous-réseau de service.
-
Cliquez sur le sous-réseau de service.
-
Cliquez sur Liste de sécurité et ajoutez les règles suivantes.
-
Entrant:
-
Sortant:
-
-
-
Mettez à jour la liste de sécurité associée au sous-réseau de noeuds de processus actif pour autoriser les connexions à partir des équilibreurs de charge.
-
Cliquez sur le nom du VCN.
-
Sous Ressources, sélectionnez Listes de sécurité, puis cliquez sur la liste de sécurité des noeuds.
-
Ajoutez la règle entrante suivante à la liste de sécurité des noeuds.
-
Cliquez sur Ajouter des règles entrantes.
-
Tâche 2 : configurer le contrôleur d'entrée Nginx
-
Une fois le cluster disponible, vous pouvez y accéder à l'aide d'OCI Cloud Shell. Cliquez sur Accéder au cluster, puis copiez et exécutez la commande suivante dans OCI Cloud Shell.
-
Exécutez la commande
kubectl get node
pour obtenir la liste des noeuds disponibles. -
Ajoutez le référentiel helm du contrôleur d'entrée Nginx. Pour plus d'informations, reportez-vous à Présentation du contrôleur NGINX entrant et à helm.
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo update
-
Créez le fichier
values-override.yaml
.controller: allowSnippetAnnotations: true service: annotations: oci.oraclecloud.com/load-balancer-type: "lb" service.beta.kubernetes.io/oci-load-balancer-backend-protocol: "TCP" service.beta.kubernetes.io/oci-load-balancer-shape: "flexible" service.beta.kubernetes.io/oci-load-balancer-shape-flex-min: "10" service.beta.kubernetes.io/oci-load-balancer-shape-flex-max: "10"
-
Déployez le contrôleur d'entrée Nginx.
helm install ingress-nginx ingress-nginx/ingress-nginx -f values-override.yaml
-
Enregistrez le fichier
yaml
suivant nomméapplication.yaml
.--- # Create ClusterIP service apiVersion: v1 kind: Service metadata: name: httpbin labels: app: httpbin spec: ports: - port: 5000 targetPort: 5000 selector: app: httpbin --- # Deployment of a sample web application apiVersion: apps/v1 kind: Deployment metadata: name: httpbin spec: replicas: 2 selector: matchLabels: app: httpbin version: v1 template: metadata: labels: app: httpbin version: v1 spec: containers: - image: mendhak/http-https-echo imagePullPolicy: IfNotPresent name: httpbin ports: - containerPort: 5000 env: - name: HTTP_PORT value: "5000"
-
Créez les ressources d'application.
kubectl apply -f application.yaml
-
Créez un enregistrement DNS pour l'adresse IP publique associée à l'équilibreur de charge.
-
Obtenez l'adresse IP publique de l'équilibreur de charge.
$ kubectl get svc ingress-nginx-controller NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE ingress-nginx-controller LoadBalancer 10.96.152.30 158.180.61.74 80:31957/TCP,443:30838/TCP 32s
-
Créez l'enregistrement DNS. Si vous ne disposez pas d'un serveur DNS, nous comptons sur le service DNS générique gratuit nip.io.
Dans ce cas, le nom de domaine qualifié complet est
158-180-61-74.nip.io
. -
-
Enregistrez le fichier
yaml
suivant nomméingress.yaml
.Remarque : veillez à mettre à jour les entrées d'hôte avec votre nom de domaine qualifié complet.
--- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: httpbin-ingress-nginx spec: ingressClassName: nginx tls: - hosts: - "<YOUR-FQDN>" rules: - host: "<YOUR-FQDN>" http: paths: - pathType: Prefix path: "/" backend: service: name: httpbin port: number: 5000
-
Exécutez la commande suivante pour créer la ressource entrante.
kubectl apply -f ingress.yaml
-
Testez la connexion au service.
$ curl -k https://<YOUR-FQDN> { "path": "/", "headers": { "host": "158-180-61-74.nip.io", "x-request-id": "b0320217391a922acecbfe10758b3ffe", "x-real-ip": "10.0.10.167", "x-forwarded-for": "10.0.10.167", "x-forwarded-host": "158-180-61-74.nip.io", "x-forwarded-port": "443", "x-forwarded-proto": "https", "x-forwarded-scheme": "https", "x-scheme": "https", "user-agent": "curl/7.87.0", "accept": "*/*" }, "method": "GET", "body": "", "fresh": false, "hostname": "158-180-61-74.nip.io", "ip": "10.0.10.167", "ips": [ "10.0.10.167" ], "protocol": "https", "query": {}, "subdomains": [ "158-180-61-74" ], "xhr": false, "os": { "hostname": "httpbin-644874bcdb-ll4mb" }, "connection": {} }
Tâche 3 : configurer une application confidentielle dans les domaines d'identité Oracle
-
Accédez à Domaines d'identité Oracle dans la console OCI et cliquez sur le domaine
OracleIdentityCloudService
. -
Sélectionnez Applications intégrées dans le menu de gauche et cliquez sur Ajouter une application.
-
Sélectionnez Application confidentielle, puis cliquez sur Lancer le workflow.
-
Renseignez les champs Nom, Description et Suivant.
-
Configurez les paramètres oAuth de l'application.
-
Dans la section Autorisation, sélectionnez Code autorisation.
-
Entrez les URL suivantes et cliquez sur Suivant.
- URL de réacheminement :
https://<YOUR-FQDN>/oauth2/callback
. - URL de réacheminement après la déconnexion :
https://<YOUR-FQDN>
. - URL de déconnexion :
https://<YOUR-FQDN>/oauth2/sign_out
.
- URL de réacheminement :
-
-
Dans Stratégie de niveau Web, sélectionnez Ignorer et effectuer une action ultérieure, puis cliquez sur Terminer.
-
Cliquez sur activer pour activer l'application.
-
Accédez à Groupes dans le menu de gauche et associez les groupes d'utilisateurs autorisés à s'authentifier auprès de cette application.
-
Notez l'ID de client et la clé secrète de client.
-
Cliquez sur le domaine OracleIdentityCloudService et développez l'URL de domaine.
Par exemple : l'URL du domaine d'identité sera
https://idcs-01234567890abcdef.identity.oraclecloud.com
(nous supprimons le numéro de port).
Tâche 4 : déployer le proxy OAuth2
Nous utilisons le proxy OAuth2 pour gérer la complexité OAuth2 ou OpenID Connect (OIDC) et nous assurer que toutes les demandes transmises aux applications sont authentifiées.
-
Enregistrez le fichier
yaml
suivant nomméoauth2-proxy.yaml
et remplacez les espaces réservés par les valeurs applicables.Remarque :
-
<Identity Domain URL>
:https://idcs-01234567890abcdef.identity.oraclecloud.com/
-
<Identity Domain FQDN>
:idcs-01234567890abcdef.identity.oraclecloud.com
--- apiVersion: apps/v1 kind: Deployment metadata: labels: k8s-app: oauth2-proxy name: oauth2-proxy spec: replicas: 1 selector: matchLabels: k8s-app: oauth2-proxy template: metadata: labels: k8s-app: oauth2-proxy spec: containers: - args: - --provider=oidc - --provider-display-name="Oracle Identity Domains" - --oidc-issuer-url=<Identity Domain URL> - --redirect-url=https://<YOUR-FQDN>/oauth2/callback - --upstream=file:///dev/null - --http-address=0.0.0.0:4180 - --email-domain=* - --set-xauthrequest=true - --session-cookie-minimal=true - --whitelist-domain=<Identity Domain FQDN> env: - name: OAUTH2_PROXY_CLIENT_ID value: "<APPLICATION_CLIENT_ID>" - name: OAUTH2_PROXY_CLIENT_SECRET value: "<APPLICATION_CLIENT_SECRET>" # docker run -ti --rm python:3-alpine python -c 'import secrets,base64; print(base64.b64encode(base64.b64encode(secrets.token_bytes(16))));' - name: OAUTH2_PROXY_COOKIE_SECRET value: "<OUTPUT_OF_THE_ABOVE_DOCKER_COMMAND>" image: quay.io/oauth2-proxy/oauth2-proxy:latest imagePullPolicy: Always name: oauth2-proxy ports: - containerPort: 4180 protocol: TCP --- apiVersion: v1 kind: Service metadata: labels: k8s-app: oauth2-proxy name: oauth2-proxy spec: ports: - name: http port: 4180 protocol: TCP targetPort: 4180 selector: k8s-app: oauth2-proxy --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: oauth2-proxy annotations: nginx.ingress.kubernetes.io/configuration-snippet: | set $xheader ""; if ( $request_uri = "/oauth2/sign_out" ){ set $xheader "https://<Identity Domain FQDN>/oauth2/v1/userlogout; } proxy_set_header X-Auth-Request-Redirect ${xheader}; spec: ingressClassName: nginx rules: - host: <YOUR-FQDN> http: paths: - path: /oauth2 pathType: Prefix backend: service: name: oauth2-proxy port: number: 4180 tls: - hosts: - <YOUR-FQDN>
-
-
Déployez le proxy OAuth2 sur OKE.
kubectl apply -f oauth2-proxy.yaml
Vérifiez que le pod est en cours d'exécution.
kubectl get pods -l k8s-app=oauth2-proxy
-
Configurez Nginx de sorte qu'il utilise le proxy OAuth2 pour l'authentification de demande.
Mettez à jour le fichier
ingress.yaml
avec les annotations d'authentification.--- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: httpbin-ingress-nginx annotations: nginx.ingress.kubernetes.io/auth-url: "https://$host/oauth2/auth" nginx.ingress.kubernetes.io/auth-signin: "https://$host/oauth2/start?rd=$escaped_request_uri" nginx.ingress.kubernetes.io/auth-response-headers: "x-auth-request-user, x-auth-request-email" spec: ingressClassName: nginx tls: - hosts: - "<YOUR-FQDN>" rules: - host: "<YOUR-FQDN>" http: paths: - pathType: Prefix path: "/" backend: service: name: httpbin port: number: 5000
-
Essayez de vous connecter à votre application. Vous devez être redirigé vers la page d'authentification Oracle. Une fois l'authentification réussie, vous devez être redirigé vers votre application.
Deux en-têtes identifient l'utilisateur authentifié.
"x-auth-request-user": "xxxx@oracle.com" "x-auth-request-email": "xxxx@oracle.com"
-
Pour vous déconnecter de l'application, vous pouvez accéder à
/oauth2/sign_out
sur votre page.https://<YOUR-FQDN>/oauth2/sign_out
Problème connu : la redirection après déconnexion ne fonctionne pas. Ce problème est suivi ici : ajoutez un paramètre id_token_hint à l'URL du fournisseur de déconnexion pour le fournisseur OIDC.
Tâche 5 : Nettoyer les ressources
-
Exécutez la commande suivante pour supprimer toutes les ressources déployées par Kubernetes.
kubectl delete -f oauth2-proxy.yaml -f ingress.yaml -f application.yaml helm uninstall ingress-nginx
-
Supprimez l'application des domaines d'identité Oracle.
-
Supprimez le cluster OKE.
-
Supprimez le VCN créé pour le cluster OKE.
Remarque :
-
Vous devez attendre la fin de la suppression du cluster OKE et du pool de noeuds.
-
Le nom du VCN contient le nom du cluster OKE :
oke-vcn-quick-<oke-cluster-name>-<random-string>
.
-
Liens connexes
Remerciements
- Auteur - Andrei Ilas (architecte cloud principal)
Ressources de formation supplémentaires
Parcourez d'autres ateliers sur docs.oracle.com/learn ou accédez à davantage de contenus de formation gratuits sur le canal Oracle Learning YouTube. De plus, rendez-vous sur education.oracle.com/learning-explorer pour devenir un explorateur Oracle Learning.
Pour obtenir de la documentation sur le produit, visitez Oracle Help Center.
Secure Kubernetes Web Services using Nginx Ingress Controller, OAuth2 Proxy, and Oracle Identity Domains
F96453-01
April 2024