Remarques :

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

Prérequis

Tâche 1 : créer un cluster OKE

  1. Connectez-vous à la console OCI, accédez à Oracle Container Engine for Kubernetes et cliquez sur Créer.

  2. Dans l'assistant Créer un cluster, cliquez sur Création rapide.

    Création rapide

  3. 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.

    Créer un cluster

  4. Vérifiez et cliquez sur Créer un cluster. Attendez que le cluster soit disponible.

  5. Mettez à jour la liste de sécurité associée au sous-réseau de service.

    1. Cliquez sur le sous-réseau de service.

      Sous-réseau de services

    2. Cliquez sur Liste de sécurité et ajoutez les règles suivantes.

      • Entrant:

        Règles entrantes de liste de sécurité

      • Sortant:

        Règles sortantes de liste de sécurité

  6. 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.

    1. Cliquez sur le nom du VCN.

      VCN du cluster OKE

    2. Sous Ressources, sélectionnez Listes de sécurité, puis cliquez sur la liste de sécurité des noeuds.

      Liste de sécurité

    3. Ajoutez la règle entrante suivante à la liste de sécurité des noeuds.

      Entrante de la liste de sécurité des noeuds

    4. Cliquez sur Ajouter des règles entrantes.

Tâche 2 : configurer le contrôleur d'entrée Nginx

  1. 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.

    Accéder au cluster

  2. Exécutez la commande kubectl get node pour obtenir la liste des noeuds disponibles.

    Obtenir les noeuds

  3. 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
    
  4. 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"
    
  5. Déployez le contrôleur d'entrée Nginx.

    helm install ingress-nginx ingress-nginx/ingress-nginx -f values-override.yaml
    
  6. 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"
    
  7. Créez les ressources d'application.

    kubectl apply -f application.yaml
    
  8. 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.

  9. 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
    
  10. Exécutez la commande suivante pour créer la ressource entrante.

    kubectl apply -f ingress.yaml
    
  11. 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

  1. Accédez à Domaines d'identité Oracle dans la console OCI et cliquez sur le domaine OracleIdentityCloudService.

  2. Sélectionnez Applications intégrées dans le menu de gauche et cliquez sur Ajouter une application.

  3. Sélectionnez Application confidentielle, puis cliquez sur Lancer le workflow.

    Nouvelle application confidentielle

  4. Renseignez les champs Nom, Description et Suivant.

    Détails de l'application

  5. Configurez les paramètres oAuth de l'application.

    1. Dans la section Autorisation, sélectionnez Code autorisation.

    2. 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.

    Paramètres oauth de l'application

  6. Dans Stratégie de niveau Web, sélectionnez Ignorer et effectuer une action ultérieure, puis cliquez sur Terminer.

    stratégie de niveau Web

  7. Cliquez sur activer pour activer l'application.

    Activer l'application

  8. Accédez à Groupes dans le menu de gauche et associez les groupes d'utilisateurs autorisés à s'authentifier auprès de cette application.

    Associer des groupes d'utilisateurs à l'application

  9. Notez l'ID de client et la clé secrète de client.

    ID et clé secrète du client d'application

  10. Cliquez sur le domaine OracleIdentityCloudService et développez l'URL de domaine.

    URL de domaine d'identité

    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.

  1. 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>
    
  2. 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
    
  3. 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
    
  4. 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.

    Authentification (page)

    Deux en-têtes identifient l'utilisateur authentifié.

    "x-auth-request-user": "xxxx@oracle.com"
    "x-auth-request-email": "xxxx@oracle.com"
    
  5. 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

  1. 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
    
  2. Supprimez l'application des domaines d'identité Oracle.

  3. Supprimez le cluster OKE.

  4. 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>.

Remerciements

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.