Non classé

Kubernetes Identity Management: Authentification | Journal Linux

Par Titanfall , le 22 avril 2019 - 17 minutes de lecture

Vous avez déployé Kubernetes, mais maintenant, comment allez-vous le mettre entre les mains de
vos développeurs et administrateurs en toute sécurité?

Kubernetes a pris d'assaut le monde. En quelques années, Kubernetes
(aka k8s) est passé d'un projet intéressant à un moteur de la technologie
et l'innovation. L’un des moyens les plus simples d’illustrer ce point est
la différence de fréquentation dans les deux fois KubeCon Amérique du Nord a
été à Seattle. Il y a deux ans, c'était dans un hôtel avec moins de 20
cabines de vendeurs. Cette année, c’était au Seattle Convention Center avec
8 000 participants et plus de 100 fournisseurs!

Comme avec tout autre système complexe, k8s a son propre modèle de sécurité et
doit interagir avec les utilisateurs et les autres systèmes. Dans cet article,
Je passe en revue les différentes options d’authentification et
fournir des exemples et des conseils de mise en œuvre sur la façon dont vous devriez gérer
accès à votre cluster.

Qu'est-ce que l'identité signifie pour Kubernetes?

La première chose à demander est "qu'est-ce qu'une identité?" en k8s. K8s est très
différent de la plupart des autres systèmes et applications. C'est un ensemble d'API.
Il n'y a pas d '"interface Web" (je discute du tableau de bord plus tard dans cet article).
Il n'y a aucun intérêt à "se connecter". Il n'y a pas de "session" ou de "timeout".
Chaque demande d'API est unique et distincte, et elle doit tout contenir
k8s doit s'authentifier et autoriser la demande.

Cela dit, la principale chose à retenir à propos des utilisateurs de k8s est qu’ils ne le font pas.
existe dans tout état persistant. Vous ne connectez pas k8 à un annuaire LDAP
ou Active Directory. Chaque demande doit attribuer une identité à K8 en une
de multiples méthodes possibles. Je capitalise ASSERT car il deviendra
important plus tard. La clé est de se rappeler que k8s ne s’authentifie pas
utilisateurs; cela valide les assertions.

Comptes de service

Les comptes de service sont les endroits où cette règle est légèrement déformée. C'est vrai que k8s
ne stocke pas d'informations sur les utilisateurs. Il stocke des comptes de service,
qui ne sont pas destinés à représenter les gens. Ils sont censés représenter
tout ce qui n'est pas une personne. Tout ce qui interagit avec quelque chose
sinon, dans k8s fonctionne comme un compte de service. Par exemple, si vous deviez
soumettre un pod très basique:





apiVersion: v1
genre: Pod
métadonnées:
  nom: myapp-pod
  Étiquettes:
    app: myapp
spec:
  conteneurs:
  - nom: myapp-container
    image: busybox
    commander: ['sh', '-c', 'echo Hello Kubernetes!
     ↪&& sleep 3600']

Et puis regardez-le dans K8S après le déploiement en exécutant kubectl get pod
myapp-pod -o yaml
:





apiVersion: v1
genre: Pod
métadonnées:
  creationTimestamp: 2018-12-25T19: 17: 53Z
  Étiquettes:
    app: myapp
  nom: myapp-pod
  namespace: default
  resourceVersion: "12499217"
  selfLink: / api / v1 / espaces de noms / default / pods / myapp-pod
  uid: c6dd5181-0879-11e9-a289-525400616039
spec:
  conteneurs:
  - commande:
    - sh
    - -c
    - echo Bonjour Kubernetes! && sommeil 3600
    image: busybox
    imagePullPolicy: toujours
    nom: myapp-container
.
.
.
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      nom: default-token-bjzd4
      readOnly: true
.
.
.
  serviceAccount: par défaut
  serviceAccountName: default
  .
  .
  .

Vous remarquerez qu'il y a un serviceAccount et
serviceAccountName attribut,
qui sont tous deux défaut. Ce compte de service est injecté pour
vous par la chaîne de contrôleur d'admission. Vous pouvez définir votre propre service
compte sur les pods, mais c’est pour un article ultérieur sur l’autorisation dans k8s.
Pour l'instant, je veux expliquer ce qu'est un compte de service pour le distinguer
à partir d'un compte d'utilisateur.

Il est tentant d'utiliser des comptes de service pour représenter des personnes. Ils sont simples
pour créer et facile à utiliser. Ils souffrent cependant de multiples inconvénients:

  1. Le jeton d'un compte de service est une longue chaîne dont aucun humain ne peut se souvenir,
    donc il sera probablement écrit, ce qui peut être exploité si pas fait
    correctement.

  2. Le seul moyen d'autoriser les comptes de service est via des liaisons RBAC
    directement. (Je prévois d’entrer dans les détails dans un prochain article,
    mais imaginez avoir 2 000 développeurs pour suivre des dizaines de
    Les espaces de noms ont tous leurs propres politiques. L'audit sera un cauchemar.)

  3. Les comptes de service n'ont pas d'expiration, donc s'il y a une fuite et personne
    sait, on peut en abuser continuellement jusqu'à ce qu'on le découvre.

Si votre application s'exécute dans un pod et doit parler au serveur d'API,
vous pouvez récupérer le compte de service du pod via un secret monté
à votre pod. Si vous regardez le yaml ci-dessus, vous verrez un montage de volume
a été ajouté à /var/run/secrets/kubernetes.io/serviceaccount où
Il existe un fichier de jeton contenant le jeton du compte de service du pod.
N'intégrez pas de jetons de compte de service en tant que secrets ou configuration pour une
pod fonctionnant dans le cluster, car il est plus difficile d’utiliser la rotation
jetons et est généralement plus difficile à gérer.

Comptes utilisateur

J'ai déjà mentionné que k8s ne se connecte à aucun type de magasin d'utilisateurs (pas
directement au moins). Cela signifie qu'à chaque demande, vous devez fournir
suffisamment d’informations pour que k8s valide l’appelant. K8s ne se soucie pas comment
vous établissez l'identité, il se soucie seulement de savoir comment prouver que l'identité est valide.
Plusieurs mécanismes existent pour le faire. Je couvre le
le plus populaire ici.

Comment Kubernetes sait qui vous êtes

OpenID Connect

C’est l’option que vous devriez utiliser (à l’exception du cloud
solution basée sur le fournisseur pour une distribution gérée) pour authentifier les utilisateurs.

  1. Les jetons OpenID Connect peuvent être de très courte durée, donc s'ils sont interceptés
    et exfiltré, au moment où les attaquants savent ce qu'ils ont, le jeton
    est inutile.

  2. Utiliser OpenID Connect, k8s jamais a les informations d'identification de l'utilisateur, il est donc
    impossible de faire fuir quelque chose qu'il n'a pas.

  3. Une identité d’utilisateur présentée par OpenID Connect peut fournir non seulement
    informations de nom d'utilisateur, mais aussi informations de groupe. Cela fait beaucoup
    gestion plus facile des accès via un annuaire LDAP ou une base de données externe
    sans avoir à créer des liaisons RBAC pour des utilisateurs individuels.

  4. En ajoutant un "proxy" entre k8s et la couche d'identité, il permet
    il est plus facile d'ajouter plusieurs types d'authentification, tels que le multi-facteur
    authentification.

  5. Une pléthore d'implémentations open source OpenID Connect
    travaillera avec k8s.

OpenID Connect Primer

Avant d’explorer comment travailler avec OpenID Connect, laissez-moi vous expliquer.
le protocole. Il y a deux concepts de base à comprendre avec
OpenID Connect:

  1. OpenID Connect est un protocole de génération d'assertions construit sur le dessus
    de OAuth2.

  2. OAuth2 est un protocole d'autorisation permettant de transférer des jetons au porteur.

Il semble qu'il manque un mot dans ces deux points:
authentification! C'est parce que OpenID Connect n'est pas une authentification
protocole. Peu importe comment vous vous authentifiez. Peu importe si
l'utilisateur connecté avec un nom d'utilisateur et un mot de passe, une carte à puce ou tout simplement
regardé vraiment digne de confiance. OpenID Connect est un protocole permettant de générer,
récupérer et actualiser des assertions concernant un utilisateur. Il y a aussi
certaines normes sur ce à quoi l'assertion ressemble, mais comment l'utilisateur
authentifie est finalement à la mise en œuvre OpenID Connect.

Le deuxième point sur OAuth2 est important car ces deux protocoles
sont souvent confondus les uns avec les autres ou mal représentés. OAuth2 est un
protocole de transfert de jetons. Il ne définit pas ce que le jeton est
ou comment il devrait être utilisé. Il définit simplement comment le jeton est passé
entre porteurs et parties en instance.

Comment Kubernetes fonctionne-t-il avec OpenID Connect?

La figure 1 montre le graphique des k8s authentification
page
.

Figure 1. Open8 Connect Flow de k8s

Je ne vais pas répéter les mots exacts du site, mais voici les
bases:

  1. L'utilisateur se connecte au fournisseur d'identité de l'utilisateur.

  2. Le fournisseur d'identité génère un id_token et un
    refresh_token.

  3. le id_token est utilisé pour affirmer l'identité de l'utilisateur à k8s.

  4. Quand le id_token a expiré, le refresh_token est utilisé pour
    générer un nouveau id_token.

Un id_token est un jeton Web JSON (JWT) qui dit:

  1. Qui est l'utilisateur?

  2. À quels groupes l'utilisateur appartient-il (facultativement)?

  3. Combien de temps le jeton est valide.

  4. Et, il contient une signature numérique pour valider que le JWT n'a pas été
    altéré.

L'attribut id de l'utilisateur, sous, est généralement l'identifiant unique de l'utilisateur.
Il est courant d'utiliser l'identifiant de connexion d'Active Directory (ou samAccountName), ou
de nombreux développeurs préfèrent utiliser une adresse électronique. En général, ce n'est pas
la meilleure pratique. L'identifiant d'un utilisateur doit être à la fois unique et immuable.
Bien qu’une adresse électronique soit unique, elle n’est pas toujours immuable (par exemple, parfois
des noms
changement).

Le JWT est transmis à chaque demande de Kubectl à k8s. le
id_token
est appelé "jeton porteur", car il donne au porteur l'accès
sans aucun contrôle supplémentaire. Cela signifie que si un système dans le
flux d'un appel d'API, tel qu'un proxy de service, validant webhook
webhook en mutation – devaient laisser échapper ce jeton, il pourrait être abusé par un
attaquant. Parce que ces jetons sont si facilement maltraités, ils devraient avoir
durée de vie très courte. Je recommande une minute. De cette façon, si un jeton
est exfiltré au moment où quelqu'un le voit, sait ce que c'est et est
capable de l'utiliser, le jeton a expiré et est donc inutile. Lors de l'utilisation
ces jetons de courte durée, il est important de configurer un
refresh_token
pour mettre à jour votre id_token après son expiration.

Kubectl sait comment rafraîchir la id_token jeton en utilisant le
refresh_token appeler l'URL du service d'autorisation du fournisseur d'identité.
le refresh_token est un jeton que le serveur API du k8s n'utilise jamais et
doit être traité comme un secret par l'utilisateur. Ce jeton est utilisé pour obtenir un
nouveau JWT, à quel point un nouveau refresh_token est disponible. Où le
id_token devrait avoir une durée de vie très courte, le
refresh_token
timeout doit être similaire à un délai d'inactivité, généralement compris entre 15 et 20.
minutes. De cette façon, la mise en œuvre de votre K8 sera conforme à
les stratégies de votre entreprise se concentrent sur les délais d'inactivité. Utilisant un
refresh_token pour obtenir un nouveau id_token est plus sécurisé
qu'une vie plus longue
id_token parce que le refresh_token signifie le
Suivant:

  1. Il ne peut être utilisé qu'une seule fois. une fois qu'il est utilisé, un nouveau est généré.

  2. Il est uniquement transmis entre l'utilisateur et le fournisseur d'identité,
    il y a donc beaucoup moins d'acteurs qui pourraient potentiellement la laisser couler.

  3. Il ne vous identifie pas; s'il est exfiltré seul, il ne peut pas être utilisé
    pour vous identifier car il est opaque, afin qu'un attaquant ne sache pas quoi
    faire avec sans informations supplémentaires.

Le tableau de bord Kubernetes

Le tableau de bord ne dispose pas de son propre système de connexion. Tout ce qu'il peut faire utilise un
jeton existant agissant au nom de l'utilisateur. Cela signifie souvent mettre un
proxy inverse devant le tableau de bord qui injectera le
id_token
sur chaque demande. Le proxy inverse est alors responsable de l'actualisation
le jeton au besoin.

Quel fournisseur d'identité devrais-je utiliser?

Lors du choix d'un fournisseur d'identité, k8s n'a en réalité que deux exigences:

  1. Il doit supporte la découverte OpenID Connect.

  2. Il fournit un mécanisme pour générer des jetons et les injecter dans votre
    ~ / .kube / config.

C'est à peu près ça! La découverte est importante car elle vous garde
d'avoir à dire à K8 où les différentes URL sont manuellement, quelles sont les clés
sont utilisés pour la signature et ainsi de suite. Il est beaucoup plus facile de pointer le k8s vers une découverte
URL qui contient toutes ces informations. C’est une norme commune, et la plupart
Les fournisseurs d'identité le prennent en charge immédiatement.

Le point 2 est l'endroit où les choses deviennent intéressantes. Il y a différentes écoles
de penser à comment obtenir vos informations de jeton à partir de votre point de connexion
(généralement un navigateur Web) dans votre ~ / .kube / config.

Injection de navigateur Web

Dans ce modèle, tout se concentre sur votre navigateur Web. Vous
s'authentifier via votre navigateur, puis des commandes sont fournies à
configurez votre Kubectl client correctement. Par exemple, OpenUnison (notre propre projet)
vous fournit une seule commande pour définir votre configuration de cluster
une fois authentifié (Figure 2).

Figure 2. Jeton de navigateur

Tu utilises KubectlLa capacité intégrée de configurer le fichier de configuration à partir de
la ligne de commande pour terminer la configuration.

Cette méthode a plusieurs avantages:

  1. Les navigateurs ont le plus d'options pour l'authentification. En plus de
    nom d'utilisateur et mot de passe, vous pouvez intégrer Kerberos, multi-facteurs, etc.

  2. Vous n'avez pas besoin de gérer des configurations complexes de K8; ils sont gérés
    pour vous.

  3. Cela fonctionne avec stock Kubectl commandes, donc il n'y a rien de plus à déployer pour
    postes de travail.

Le plugin kubectl

Vous pouvez prolonger le Kubectl commande utilisant des plugins.
À l'aide d'un plugin, vous pouvez collecter les informations d'identification d'un utilisateur, puis générer
un jeton. J'ai vu des plugins qui vont collecter vos identifiants
la CLI et d’autres plug-ins qui lanceront un navigateur pour vous demander de
un login. Cette méthode est bonne du point de vue de la CLI car elle permet à votre CLI
pilotez votre expérience utilisateur. L’inconvénient majeur de cette approche est-il
nécessite l'installation du plug-in sur chaque poste de travail.

Télécharger la configuration

Avec cette méthode, le fournisseur d’identité (ou une application personnalisée)
vous fournit un fichier de configuration entièrement généré que vous pouvez télécharger.
Cela peut créer un problème de support si quelque chose n'est pas enregistré dans
au bon endroit.

Une fois que vous avez choisi un fournisseur d’identité, suivez ses instructions.
l'intégration. Les éléments clés d’importance sont l’URL de découverte, le
l'identifiant "claim" et la "claim" du groupe.

Certificats X509

L’authentification par certificat exploite la négociation TLS entre les
client (généralement le Kubectl commande) et le serveur API k8s
pour affirmer une identité en présentant un certificat au serveur API.
À l'exception d'un cas d'utilisation, cette méthode n'est pas une "meilleure pratique"
et devrait être découragé pour plusieurs raisons:

  1. Les certificats ne peuvent pas être révoqués en k8. Vous devez soit attendre jusqu'à
    le certificat a expiré ou ressaisissez l'intégralité du cluster.

  2. La clé privée d'un certificat doit jamais quitter le support sécurisé
    où c'était
    généré. Habituellement, on vous "donne" une paire de clés et un certificat à utiliser.

  3. Il est difficile d'utiliser des groupes avec des certificats. Vous devez les intégrer
    dans le sujet, et si ces groupes doivent changer, bien, voir n ° 1 ci-dessus.

La seule situation où vous devriez utiliser des certificats X509 pour
l'authentification est lorsque vous démarrez votre cluster ou en cas de
urgence et votre fournisseur d'identité n'est pas disponible. La plupart des distributions
déployer une paire de clés sur chaque maître, donc si vous ssh dans ce maître, vous pouvez
utilisation Kubectl gérer le cluster. Cela signifie que vous devez verrouiller
accès au maître (je prévois de couvrir cela dans un prochain article).

Webhooks

Cette méthode vous permet d’intégrer une connexion tierce ou un système de jeton via
un Webhook. Au lieu de dire à k8s comment valider une identité, k8s
appelle un webhook et demande "qui est-ce?"

Ne le faites pas sauf si vous êtes un fournisseur de cloud et que vous avez votre propre identité.
Solution. À peu près toutes les mises en œuvre que j'ai vues de cela se transforment en
"passons les mots de passe" ou un OpenID Connect mal pensé.

Proxy inverse avec emprunt d'identité

Ici, le client (kubectl ou autre) ne communique pas avec l'API
serveur directement. Au lieu de cela, il communique avec un proxy inverse, qui
injecte des en-têtes dans la requête pour représenter l'utilisateur. C'est souvent
souligné comme un moyen de gérer les scénarios d’authentification avancée,
cela demande le moins de travail possible du point de vue du serveur d'API.
Les étapes de la mise en œuvre sont les suivantes:

  1. Créez un compte de service.

  2. Autorisez le compte de service à effectuer l'emprunt d'identité.

  3. Configurez un proxy inverse pour injecter le compte de service et
    en-têtes d'emprunt d'identité dans chaque demande.

Cette solution fournit ces problèmes ainsi que les mêmes pièges que Webhooks.
Il est fort probable que les normes existantes satisferont vos besoins et seront plus faciles à
gérer et maintenir.

Le tirer ensemble

Pour intégrer l'identité dans les k8, suivez cette liste de contrôle de base:

  1. Utilisez les comptes de service uniquement pour les systèmes, pas pour les utilisateurs.

  2. Utilisez OpenID Connect pour les personnes; il est bien vérifié et soutenu par
    plusieurs systèmes, à la fois open-source et propriétaires.

  3. Utilisez l'authentification par certificat uniquement pour "briser le verre en cas de
    situations d'urgence.

Suivez ces règles et vous constaterez que vos développeurs sont heureux de
avoir un mot de passe de moins à retenir, et votre équipe de sécurité sera heureuse
vous suivez les meilleures pratiques et les exigences de conformité.

Ressources

Click to rate this post!
[Total: 0 Average: 0]

Commentaires

Laisser un commentaire

Votre commentaire sera révisé par les administrateurs si besoin.