Comment protéger les services Kubernetes privés derrière une connexion GitHub avec oauth2_proxy

introduction

Kubernetesingresses facilite l’exposition des services Web à Internet. En ce qui concerne les services privés, cependant, vous voudrez probablement limiter le nombre de personnes pouvant y accéder. oauth2_proxy peut servir de barrière entre l'Internet public et les services privés. oauth2_proxy est un serveur proxy et proxy inverse qui fournit une authentification à l'aide de différents fournisseurs, tels que GitHub, et valide les utilisateurs à l'aide de leur adresse électronique ou d'autres propriétés.

Dans ce tutoriel, vous utiliserez oauth2_proxy avec GitHub pour protéger vos services. Une fois que vous avez terminé, vous disposez d’un système d’autorisation ressemblant à celui du diagramme suivant:

A diagram of a request flow end-result

Conditions préalables

Pour compléter ce tutoriel, vous aurez besoin de:

[[step-1 -—- configuration-your-domains]] == Étape 1 - Configuration de vos domaines

Après avoir suivi le didacticiel lié dans la section Prérequis, vous aurez deux services Web en cours d'exécution sur votre cluster:echo1 etecho2. Vous aurez également une entrée qui mappeecho1.your_domain etecho2.your_domain à leurs services correspondants.

Dans ce tutoriel, nous allons utiliser les conventions suivantes:

  • Tous les services privés relèveront du sous-domaine.int.your_domain, commeservice.int.your_domain. Le regroupement des services privés sous un sous-domaine est idéal car le cookie d'authentification sera partagé entre tous les sous-domaines*.int.your_domain.

  • Le portail de connexion sera servi surauth.int.your_domain.

[.note] #Note: Assurez-vous de remplaceryour_domain par votre propre nom de domaine partout où il apparaît dans ce didacticiel.
#

Pour commencer, mettez à jour la définition d'entrée existante pour déplacer les servicesecho1 etecho2 sous.int.your_domain. Ouvrezecho_ingress.yaml dans votre éditeur de texte afin de pouvoir modifier les domaines:

nano echo_ingress.yaml

Renommez toutes les instances deecho1.your_domain enecho1.int.your_domain et remplacez toutes les instances deecho2.your_domain parecho2.int.your_domain:

echo_ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: echo-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    certmanager.k8s.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
  - hosts:
    - echo1.int.your_domain
    - echo2.int.your_domain
    secretName: letsencrypt-prod
  rules:
  - host: echo1.int.your_domain
    http:
      paths:
      - backend:
          serviceName: echo1
          servicePort: 80
  - host: echo2.int.your_domain
    http:
      paths:
      - backend:
          serviceName: echo2
          servicePort: 80

Enregistrez le fichier et appliquez les modifications:

kubectl apply -f echo_ingress.yaml

Cela mettra également à jour les certificats TLS pour vos servicesecho1 etecho2.

Maintenant, mettez à jour votre configuration DNS pour refléter les modifications que vous avez apportées. Tout d’abord, recherchez l’adresse IP de votre réseau Nginx en exécutant la commande suivante pour en imprimer les détails:

kubectl get svc --namespace=ingress-nginx

Vous verrez l'adresse IP sousEXTERNAL-IP dans la sortie:

OutputNAME            TYPE           CLUSTER-IP      EXTERNAL-IP       PORT(S)                      AGE
ingress-nginx   LoadBalancer   10.245.247.67   203.0.113.0   80:32486/TCP,443:32096/TCP   20h

Copiez l'adresse IP externe dans votre presse-papiers. Accédez à votre service de gestion DNS et recherchez les enregistrementsA pourecho1-2.your_domain pour pointer vers cette adresse IP externe. Si vous utilisez DigitalOcean pour gérer vos enregistrements DNS, consultezHow to Manage DNS Records pour obtenir des instructions.

Supprimez les enregistrements pourecho1 etecho2. Ajoutez un nouvel enregistrementA pour le nom d'hôte*.int.your_domain et pointez-le vers l'adresse IP externe de l'entrée.

Désormais, toute demande adressée à un sous-domaine sous*.int.your_domain sera acheminée vers l'entrée Nginx, vous pouvez donc utiliser ces sous-domaines dans votre cluster.

Ensuite, vous allez configurer GitHub en tant que votre fournisseur de connexion.

[[step-2 -—- creating-a-github-oauth-application]] == Étape 2 - Création d'une application GitHub OAuth

oauth2_proxy prend en charge divers fournisseurs de connexion. Dans ce tutoriel, vous utiliserez le fournisseur GitHub. Pour commencer, créez une nouvelle application GitHub OAuth.

Dans la pageOAuth Apps tab of the Developer settings de votre compte, cliquez sur le boutonNew OAuth App.

Les champsApplication name etHomepage URL peuvent être tout ce que vous voulez. Dans le champAuthorization callback URL, entrezhttps://auth.int.your_domain/oauth2/callback.

Après avoir enregistré l'application, vous recevrez un identifiant client et un secret. Notez les deux comme vous en aurez besoin à l'étape suivante.

Maintenant que vous avez créé une application GitHub OAuth, vous pouvez installer et configurer oauth2_proxy.

[[step-3 -–- setting-up-the-login-portal]] == Étape 3 - Configuration du portail de connexion

Vous utiliserez Helm pour installer le sproxy oauth2proxy onto the cluster. First, you’ll create a Kubernetes secret to hold the GitHub application’s Client ID and Secret, as well as an encryption secret for browser cookies set by oauth2.

Exécutez la commande suivante pour générer un secret de cookie sécurisé:

python -c 'import os,base64; print base64.b64encode(os.urandom(16))'

Copier le résultat dans votre presse-papier

Créez ensuite le secret Kubernetes en substituant les valeurs en surbrillance pour votre secret de cookie, votre ID client GitHub et votre clé secrète GitHub:

kubectl -n default create secret generic oauth2-proxy-creds \
--from-literal=cookie-secret=YOUR_COOKIE_SECRET \
--from-literal=client-id=YOUR_GITHUB_CLIENT_ID \
--from-literal=client-secret=YOUR_GITHUB_SECRET

Vous verrez le résultat suivant:

Outputsecret/oauth2-proxy-creds created

Ensuite, créez un nouveau fichier nomméoauth2-proxy-config.yaml qui contiendra la configuration pouroauth2_proxy:

nano oauth2-proxy-config.yaml

Les valeurs que vous définissez dans ce fichier remplacent les valeurs par défaut du diagramme de Helm. Ajoutez le code suivant au fichier:

oauth2-proxy-config.yaml

config:
  existingSecret: oauth2-proxy-creds

extraArgs:
  whitelist-domain: .int.your_domain
  cookie-domain: .int.your_domain
  provider: github

authenticatedEmailsFile:
  enabled: true
  restricted_access: |-
    [email protected]
    [email protected]

ingress:
  enabled: true
  path: /
  hosts:
    - auth.int.your_domain
  annotations:
    kubernetes.io/ingress.class: nginx
    certmanager.k8s.io/cluster-issuer: letsencrypt-prod
  tls:
    - secretName: oauth2-proxy-https-cert
      hosts:
        - auth.int.your_domain

Ce code a les effets suivants:

  1. Indique à oauth2_proxy d'utiliser le secret que vous avez créé.

  2. Définit le nom de domaine et le type de fournisseur.

  3. Définit une liste d'adresses électroniques autorisées. Si un compte GitHub est associé à l'une de ces adresses électroniques, il sera autorisé à accéder aux services privés.

  4. Configure l’entrée qui servira le portail de connexion surauth.int.your_domain avec un certificat TLS de Let’s Encrypt.

Maintenant que vous avez le secret et le fichier de configuration prêts, vous pouvez installeroauth2_proxy. Exécutez la commande suivante:

helm repo update \
&& helm upgrade oauth2-proxy --install stable/oauth2-proxy \
--reuse-values \
--values oauth2-proxy-config.yaml

L’émission et l’installation du certificat Let’s Encrypt peuvent prendre quelques minutes.

Pour vérifier que le déploiement a réussi, accédez àhttps://auth.int.your_domain. Vous verrez une page qui vous invite à vous connecter avec GitHub.

Avec oauth2_proxy configuré et en cours d’exécution, il ne reste plus qu’à exiger l’authentification sur vos services.

[[step-4 -—- protection-des-services-privés]] == Étape 4 - Protection des services privés

Afin de protéger un service, configurez son entrée Nginx pour appliquer l'authentification via oauth2_proxy. Nginx et nginx-ingress prennent en charge cette configuration de manière native, il vous suffit donc d'ajouter quelques annotations à la définition d'entrée.

Protégeons les servicesecho1 etecho2 que vous avez configurés dans le didacticiel des prérequis. Ouvrezecho_ingress.yaml dans votre éditeur:

nano echo_ingress.yaml

Ajoutez ces deux annotations supplémentaires au fichier pour exiger une authentification:

echo_ingress.yaml

   annotations:
     kubernetes.io/ingress.class: nginx
     certmanager.k8s.io/cluster-issuer: letsencrypt-prod
     nginx.ingress.kubernetes.io/auth-url: "https://auth.int.your_domain/oauth2/auth"
     nginx.ingress.kubernetes.io/auth-signin: "https://auth.int.your_domain/oauth2/start?rd=https%3A%2F%2F$host$request_uri"

Enregistrez le fichier et appliquez les modifications:

kubectl apply -f echo_ingress.yaml

Maintenant, lorsque vous naviguez vershttps://echo1.int.your_domain, il vous sera demandé de vous connecter à l'aide de GitHub pour y accéder. Après vous être connecté avec un compte valide, vous serez redirigé vers le serviceecho1. Il en va de même pourecho2.

Conclusion

Dans ce tutoriel, vous avez configuré oauth2_proxy sur votre cluster Kubernetes et protégé un service privé derrière une connexion GitHub. Pour tout autre service que vous devez protéger, suivez simplement les instructions données à l’étape 4.

oauth2_proxy prend en charge de nombreux fournisseurs autres que GitHub. Pour en savoir plus sur les différents fournisseurs, consultezthe official documentation.

En outre, vous devrez peut-être ajuster de nombreux paramètres de configuration, bien que les valeurs par défaut conviennent à la plupart des besoins. Pour une liste de paramètres, voirthe Helm chart’s documentation etoauth2_proxy’s documentation.