Article écrit par Martin
Kubernetes nous offre des possibilités d’industrialisation de nos infrastructures. C’est particulièrement intéressant dans le cadre d’environnements de recette ou d’intégration.
On peut en effet rapidement se retrouver à avoir plusieurs environnements distincts (intégration, revue, recette…) par projet.
Ces environnements, quand ils veulent être rendus accessibles à des tiers, peuvent se retrouver exposés sur Internet.
Dès lors, leur sécurisation est un enjeu qui ne peut pas être ignoré.
Anatomie d’une application simple
Pour une application classique, on va retrouver les composants Kubernetes suivants :
- ingress
- service
- pod
L’ingress est la porte d’entrée sur l’extérieur, jouant le rôle de reverse proxy vers votre service qui sera lui en charge de répartir les requêtes sur les différentes occurrences de votre application (pod).
Sécuriser ses ingress avec OAuth2 proxy
Choix de OAuth2 proxy
Dans notre contexte, nous avons un cluster destiné à nos applications en phase de recette. Chaque projet peut être déployé N fois selon l’environnement ciblé.
On peut donc progressivement se retrouver avec un nombre conséquent d’ingress dans notre cluster.
Notre objectif est de sécuriser simplement chacun de ces ingress en le mettant derrière une authentification de type Azure Active Directory.
En arrivant sur notre service, on devra être redirigé vers la mire de login si l’on n’est pas encore authentifié. Notre autre prérequis est que la configuration par ingress soit la plus simple possible.
Pour se faire, notre choix se porte sur OAuth2 Proxy. À l’image d’un cert manager le service s’installe et se configure de façon unique dans le cluster.
La configuration sur les ingress cibles se fait ensuite avec quelques annotations que nous détaillerons plus loin.
Fonctionnement de OAuth2 proxy
Imaginons que nous souhaitons exposer notre application sur foo.recette.ouidou.fr
. L’ingress de l’application répondra donc sur ce domaine. Le proxy sera lui exposé sur proxy.recette.ouidou.fr
.
Lorsqu’on se rendra sur cette URL, l’ingress interrogera le service OAuth2 proxy en passant automatiquement les cookies accessibles à ce dernier.
Si ce cookie est valide, il ne se passe rien de plus, la requête entrante est considérée comme authentifiée. Si ce n’est pas le cas, le proxy enclenche un round trip OAuth 2 classique. L’utilisateur sera redirigé vers la mire de login de son Active Directory.
Une fois authentifié, il sera renvoyé vers le proxy qui écrira un cookie puis le redirigera vers l’app en question.
Il est important d’avoir en tête que la portée du cookie détermine la portée de l’authentification.
Ici mon cookie a pour portée recette.ouidou.fr
. Cela signifie qu’une fois authentifié, je le serai sur l’ensemble des services qui sont sur *.recette.ouidou.fr
de manière indifférenciée.
Sauf à démultiplier les proxy ce n’est donc pas une solution permettant de gérer finement des accès par application.
Mise en place et configuration de OAuth2 proxy
L’installation se fait simplement avec Helm :
helm repo add oauth2-proxy https://oauth2-proxy.github.io/manifests
helm install oauth2-proxy oauth2-proxy/oauth2-proxy -n mon-namespace
Une fois réalisée, nous allons modifier la configuration du secret créé pour nous :
kubectl edit secret oauth2-proxy
3 clés attendent une valeur :
client-id
: l’identification de l’app registrationclient-secret
: le secret de l’app registrationcookie-secret
: une valeur aléatoire, jouant le rôle de salt pour chiffrer les cookies
Note : il est également possible d’utiliser redis en backend de session mais votre proxy ne sera plus stateless.
Je ne détaille pas le process de création d’une app registration dans le portail Azure, vous trouverez facilement de la documentation là-dessus.
L’URL de redirection devra simplement être configurée pour atterrir sur https://url-du-proxy/oauth2/callback
.
J’ai ensuite réalisé quelques modifications au niveau de l’objet deployment
.
kubectl edit deployment oauth2-proxy
J’ai uniquement modifié les arguments de démarrage du conteneur
spec:
automountServiceAccountToken: true
containers:
- args:
- --provider=azure
- --azure-tenant=${tenant_id}
- --cookie-domain=recette.ouidou.fr
- --email-domain=ouidou.fr
- --oidc-issuer-url=https://login.microsoftonline.com/${tenant_id}/v2.0
- --reverse-proxy=true
- --whitelist-domain=.recette.ouidou.fr
- --http-address=0.0.0.0:4180
- --https-address=0.0.0.0:4443
- --metrics-address=0.0.0.0:44180
- --config=/etc/oauth2_proxy/oauth2_proxy.cfg
Parmi les éléments importants vous devrez configurer votre identifiant de tenant Azure (remplacer la valeur ${tenant_id}
par votre valeur).
Le --cookie-domain
permet de préciser la portée de votre cookie. Il faut évidemment que le proxy soit lui-même dans cette portée.
--reverse-proxy
permet de préciser à OAuth2 proxy qu’il est lui-même derrière un reverse proxy, dans notre cas un ingress nginx.
La partie --whitelist-domain
permet de spécifier les domaines qui sont safe pour une redirection. On verra juste après que c’est l’ingress cible qui demande où doit se faire la redirection. Si celle-ci n’est pas considérée comme acceptable par OAuth2 proxy, il ne redirigera pas.
metrics-address
permet de définir l’URL où alimenter Prometheus.
L’étendue des possibles en matière de configuration est vaste, je vous invite à consulter la documentation associée.
Configuration de l’ingress applicatif
Il nous reste maintenant la partie la plus simple qui consiste à configurer l’ingress de notre application.
kubectl -n $mon-namespace annotate ingress $app-ingress nginx.ingress.kubernetes.io/auth-response-headers=x-auth-request-user,x-auth-request-email
kubectl -n $mon-namespace annotate ingress $app-ingress nginx.ingress.kubernetes.io/auth-signin=https://url-du-proxy/oauth2/start?rd=$scheme://$host$escaped_request_uri
kubectl -n $mon-namespace annotate ingress $app-ingress nginx.ingress.kubernetes.io/auth-url=https://url-du-proxy/oauth2/auth
Je le mentionnais plus haut, le paramètre rd
est important, c’est lui qui déterminera l’URL de redirection. Si vous ne le précisez pas, vous serez correctement authentifié, mais vous resterez sur le proxy.
C’est tout côté configuration, votre ingress applicatif est maintenant protégé par votre proxy qui assurera l’authentification avec votre Active Directory.
Nous avons ici présenté un cas utilisant Azure Active Directory mais OAuth2 proxy est évidemment compatible avec tout un tas d’autre SSO.