web-dev-qa-db-fra.com

Comment puis-je implémenter ansible avec des mots de passe par hôte, en toute sécurité?

Je voudrais utiliser ansible pour gérer un groupe de serveurs existants. J'ai créé un ansible_hosts, et testé avec succès (avec le -K option) avec des commandes qui ne ciblent qu'un seul hôte

ansible -i ansible_hosts Host1 --Sudo -K # + commands ...

Mon problème est maintenant que les mots de passe utilisateur sur chaque hôte sont différents, mais je ne trouve pas de moyen de gérer cela dans Ansible.

En utilisant -K, Je ne suis invité que pour un seul mot de passe Sudo à l'avance, qui semble ensuite être essayé pour tous les hôtes suivants sans demander:

Host1 | ...
Host2 | FAILED => Incorrect Sudo password
Host3 | FAILED => Incorrect Sudo password
Host4 | FAILED => Incorrect Sudo password
Host5 | FAILED => Incorrect Sudo password

Recherches à ce jour:

  • a question StackOverflow avec une réponse incorrecte ("utilisez -K ") et une réponse de l'auteur disant" J'ai découvert que j'avais besoin de Sudo sans mot de passe "

  • les documents Ansible , qui disent "L'utilisation de Sudo sans mot de passe facilite l'automatisation, mais ce n'est pas obligatoire ". (c'est moi qui souligne)

  • cette question de sécurité StackExchange ce qui signifie que NOPASSWD est requis

  • article "Provisioning évolutif et compréhensible ..." qui dit:

    "l'exécution de Sudo peut nécessiter la saisie d'un mot de passe, ce qui est un moyen sûr de bloquer Ansible pour toujours. Une solution simple consiste à exécuter visudo sur l'hôte cible et à s'assurer que l'utilisateur Ansible utilisera pour se connecter n'a pas à tapez un mot de passe "

  • article "Basic Ansible Playbooks" , qui dit

    "Ansible pourrait se connecter au serveur cible en tant que root et éviter le besoin de Sudo, ou laisser l'utilisateur ansible avoir Sudo sans mot de passe, mais l'idée de le faire fait que ma rate menace de sauter mon gosier et de bloquer mon trachée, donc je ne le fais pas "

    Mes pensées exactement, mais alors comment s'étendre au-delà d'un seul serveur?

  • numéro ansible # 1227 , "Ansible devrait demander le mot de passe Sudo pour tous les utilisateurs d'un playbook", qui a été fermé il y a un an par mpdehaan avec le commentaire "Je n'ai pas vu beaucoup de demande pour cela, je pense la plupart des gens utilisent un seul compte d'utilisateur ou utilisent des clés la plupart du temps. "

Alors ... comment les gens utilisent-ils Ansible dans des situations comme celles-ci? Définition de NOPASSWD dans /etc/sudoers, la réutilisation du mot de passe sur les hôtes ou l'activation de la connexion SSH racine semblent toutes des réductions de sécurité plutôt drastiques.

110
supervacuo

Vous avez certainement fait vos recherches ...

D'après toute mon expérience avec ansible, ce que vous cherchez à accomplir n'est pas pris en charge. Comme vous l'avez mentionné, ansible déclare qu'il ne nécessite pas de Sudo sans mot de passe, et vous avez raison, ce n'est pas le cas. Mais je n'ai pas encore vu de méthode d'utilisation de plusieurs mots de passe Sudo dans ansible, sans bien sûr exécuter plusieurs configurations.

Donc, je ne peux pas offrir la solution exacte que vous recherchez, mais vous avez demandé ...

"Alors ... comment les gens utilisent-ils Ansible dans des situations comme celles-ci? La définition de NOPASSWD dans/etc/sudoers, la réutilisation du mot de passe sur les hôtes ou l'activation de la connexion SSH racine semblent toutes des réductions de sécurité assez drastiques."

Je peux vous donner un point de vue là-dessus. Mon cas d'utilisation est de 1 000 nœuds dans plusieurs centres de données prenant en charge une entreprise mondiale SaaS dans laquelle je dois concevoir/mettre en œuvre des contrôles de sécurité incroyablement serrés en raison de la nature de notre entreprise. La sécurité est toujours un acte d'équilibre , plus de convivialité moins de sécurité, ce processus n'est pas différent si vous exécutez 10 serveurs ou 1 000 ou 100 000.

Vous avez absolument raison de ne pas utiliser les connexions root via un mot de passe ou des clés ssh. En fait, la connexion root doit être entièrement désactivée si les serveurs ont un câble réseau branché.

Parlons de la réutilisation des mots de passe, dans une grande entreprise, est-il raisonnable de demander aux administrateurs système d'avoir des mots de passe différents sur chaque nœud? pour quelques nœuds, peut-être, mais mes administrateurs/ingénieurs se révolteraient s'ils devaient avoir des mots de passe différents sur 1000 nœuds. Une mise en œuvre qui serait presque impossible également, chaque utilisateur devrait y stocker ses propres mots de passe quelque part, espérons-le un clavier, pas une feuille de calcul. Et chaque fois que vous placez un mot de passe dans un endroit où il peut être retiré en texte brut, vous diminuez considérablement votre sécurité. Je préférerais de loin qu'ils connaissent, par cœur, un ou deux mots de passe vraiment forts plutôt que de consulter un fichier de clavier chaque fois qu'ils ont besoin de se connecter ou d'appeler Sudo sur une machine.

La réutilisation et la normalisation des mots de passe sont donc tout à fait acceptables et standard, même dans un environnement sécurisé. Sinon, ldap, keystone et d'autres services d'annuaire n'auraient pas besoin d'exister.

Lorsque nous passons aux utilisateurs automatisés, les clés ssh fonctionnent très bien pour vous faire entrer, mais vous devez toujours passer par Sudo. Vos choix sont un mot de passe standardisé pour l'utilisateur automatisé (qui est acceptable dans de nombreux cas) ou pour activer NOPASSWD comme vous l'avez souligné. La plupart des utilisateurs automatisés n'exécutent que quelques commandes, il est donc tout à fait possible et certainement souhaitable d'activer NOPASSWD, mais uniquement pour les commandes pré-approuvées. Je suggère d'utiliser votre gestion de configuration (ansible dans ce cas) pour gérer votre fichier sudoers afin que vous puissiez facilement mettre à jour la liste des commandes sans mot de passe.

Maintenant, vous pouvez suivre certaines étapes une fois que vous avez commencé à évoluer pour isoler davantage le risque. Bien que nous ayons environ 1000 nœuds, ils ne sont pas tous des serveurs de "production", certains sont des environnements de test, etc. Tous les administrateurs ne peuvent pas accéder aux serveurs de production, ceux qui peuvent cependant utiliser leur même clé SSO utilisateur/pass | comme ils le feraient ailleurs . Mais les utilisateurs automatisés sont un peu plus sûrs, par exemple un outil automatisé auquel les administrateurs hors production peuvent accéder a un utilisateur et des informations d'identification qui ne peuvent pas être utilisés en production. Si vous souhaitez lancer ansible sur tous les nœuds, vous devez le faire en deux lots, une pour la non-production et une pour la production.

Cependant, nous utilisons également des marionnettes, car il s'agit d'un outil de gestion de la configuration, de sorte que la plupart des modifications apportées à tous les environnements y seront poussées.

De toute évidence, si la demande de fonctionnalité que vous avez citée est rouverte/terminée, ce que vous cherchez à faire serait entièrement pris en charge. Même alors, la sécurité est un processus d'évaluation des risques et de compromis. Si vous n'avez que quelques nœuds pour lesquels vous pouvez vous souvenir des mots de passe sans avoir recours à une note post-it, des mots de passe séparés seraient légèrement plus sécurisés. Mais pour la plupart d'entre nous, ce n'est pas une option réalisable.

55
Zeb

Depuis Ansible 1.5, il est possible d'utiliser un coffre-fort chiffré pour Host_vars et d'autres variables. Cela vous permet au moins de stocker un par hôte (ou par groupe) ansible_Sudo_pass variable en toute sécurité. Malheureusement, --ask-vault-pass ne demandera qu'un seul mot de passe de coffre-fort par appel ansible, vous êtes donc toujours contraint à un seul mot de passe de coffre-fort pour tous les hôtes que vous utiliserez ensemble.

Néanmoins, pour certaines utilisations, cela peut être une amélioration par rapport à la possession d'un mot de passe Sudo unique sur plusieurs hôtes, car un attaquant n'ayant pas accès à vos Host_vars chiffrés aurait toujours besoin d'un mot de passe Sudo distinct pour chaque machine (ou groupe de machines) qu'il attaque.

37
Daniel Neades

Avec Ansible 1.5, il est possible de définir la variable ansible_Sudo_pass en utilisant lookup('password', …):

ansible_Sudo_pass: "{{ lookup('password', 'passwords/' + inventory_hostname) }}"

Je trouve cela plus pratique que d'utiliser des fichiers dans Host_vars/ pour plusieurs raisons:

  • J'utilise en fait with_password: "passwords/{{ inventory_hostname}} encrypt=sha256_crypt" pour provisionner les mots de passe pour l'utilisateur distant deploy (qui est ensuite nécessaire pour Sudo ), ils sont donc déjà présent dans les fichiers (bien que ces recherches en texte brut perdent la valeur de sel stockée dans le fichier lorsque la valeur hachée est générée).

  • Cela ne conserve que les mots de passe dans le fichier (pas de ansible_Sudo_pass: texte en clair connu) pour une augmentation de la sécurité cryptographique epsilon. Plus important encore, cela signifie que vous ne cryptez pas toutes les autres variables spécifiques à l'hôte, elles peuvent donc être lues sans le mot de passe du coffre-fort.

  • Placer les mots de passe dans un répertoire séparé permet de garder plus facilement les fichiers hors du contrôle des sources, ou d'utiliser un outil comme git-crypt pour les stocker sous forme cryptée (vous pouvez l'utiliser avec une version antérieure d'Ansible qui manque la fonction de coffre-fort). J'utilise git-crypt et comme je ne vérifie le référentiel que sous forme déchiffrée sur des systèmes de fichiers chiffrés, je ne me soucie pas du coffre-fort et je n'ai donc pas besoin de taper un mot de passe de coffre-fort. (L'utilisation des deux serait bien sûr plus sûre.)

Vous pouvez également utiliser la fonction de recherche avec ansible_ssh_pass ; cela peut même être possible avec les versions antérieures d'Ansible qui n'ont pas ansible_Sudo_pass .

23
Alex Dupuy

Utiliser pass est une méthode simple pour fournir des mots de passe Sudo à ansible. pass stocke un mot de passe par fichier, ce qui facilite le partage de mots de passe via git ou d'autres méthodes. Il est également sécurisé (en utilisant GnuPG) et si vous utilisez gpg-agent, il vous permet d'utiliser ansible sans entrer de mot de passe à chaque utilisation.

Pour fournir le mot de passe enregistré sous servers/foo pour le serveur foo à ansible, utilisez-le dans un fichier d'inventaire comme celui-ci:

[servers]
foo ansible_Sudo=True \
    ansible_Sudo_pass="{{ lookup('pipe', 'pass servers/foo') }}"

Étant donné que vous avez déverrouillé la clé de gpg-agent plus tôt, cela fonctionnera ansible sans avoir à entrer de mot de passe.


Mise à jour: Ansible a cette fonctionnalité intégrée de nos jours, via le plugin passwordstore . L'équivalent de ce qui précède serait:

[servers]
foo ansible_Sudo=True \
    ansible_Sudo_pass="{{ lookup('passwordstore', 'servers/foo') }}"

Il est même possible de créer un mot de passe s'il n'existe pas encore, ce qui peut être extrêmement utile.

21
fqxp

Il s'agit néanmoins d'un fil assez ancien:

  • Nous utilisons deux systèmes d'authentification différents en interne, la gestion des machines se fait depuis les postes de travail locaux de mon équipe.
  • J'ai écrit un vars_plugin pour Ansible (une implémentation assez complète peut être trouvée sur https://Gist.github.com/mfriedenhagen/e488235d732b7becda81 ) qui différencie plusieurs systèmes d'authentification:
  • Le nom du système d'authentification est spécifique au groupe.
  • L'utilisateur login/Sudo utilisé est spécifique au groupe et à l'administrateur.
  • Je tire donc l'utilisateur de l'environnement d'administration et le mot de passe correspondant via la bibliothèque de porte-clés python à partir d'un mot de passe sécurisé (nous utilisons le trousseau de Mac OS X, mais de la documentation kwallet Gnome et _win_crypto sont également pris en charge).
  • J'ai défini des autorisations sur les mots de passe dans le trousseau de Mac OS X pour m'informer du fait que la sécurité du programme de ligne de commande demande l'accès à un mot de passe pour chaque système d'authentification utilisé par les hôtes, donc j'exécute "ansible -s all -m ping" et obtenez deux invites (une pour chaque système d'authentification) où j'appuie sur la barre d'espace et ansible récupère les mots de passe.
3

Quiconque se retrouve ici en retard: c.f. https://stackoverflow.com/a/37002802

Per Host, in your inventory hosts file (inventory/<inventoryname>/hosts)
[server]
10.0.0.0 ansible_Sudo_pass=foobar

Per group, in your inventory groups file (inventory/<inventoryname>/groups)
[server:vars]
ansible_Sudo_pass=foobar

Per group, in group vars (group_vars/<groupname>/ansible.yml) and encrypted (ansible-vault create group_vars/<groupname>/ansible.yml)
ansible_Sudo_pass: "foobar"
0
gen.st4ck

Une façon possible de procéder consiste à utiliser des variables environnementales.

par exemple.

pass1=foo pass2=bar ansible-playbook -i production servers.xml

Ensuite, dans les jeux, vous pouvez rechercher le mot de passe Sudo en utilisant:

lookup('env', 'pass1') 
lookup('env', 'pass2') 
0
Paul Calabro

C'est parfaitement possible. Vous pouvez définir votre inventaire pour utiliser des variables pour des choses comme les mots de passe:

INVENTAIRE:

[023_mqtt]
023-softbank-mqtt01 ansible_Host=IP.IP.IP.IP ansible_ssh_private_key_file=/path/to/my_key ansible_ssh_user=my_user ansible_become=yes ansible_become_method=Sudo ansible_become_pass='{{ my_user_pass }}'

Vous avez besoin d'un fichier group_vars/023_mqtt.yaml où se trouve votre inventaire, si vous utilisez un serveur de saut (si vous en avez besoin):

ansible_ssh_common_args: '-o ProxyCommand="ssh -i /path/to/your/jump_key -W %h:%p -q [email protected]"'

Enfin, vous définissez un coffre-fort pour stocker vos mots de passe. De préférence pour le créer dans le même dossier que votre fichier d'inventaire:

ansible-vault create passwds.yaml
[enter a vault pass]

Ajoutez les mots de passe:

my_user : 'my_user's Sudo password'

Pour exécuter cela, passez le coffre-fort en tant que variables supplémentaires:

 ansible -a "docker ps" -i /path/to/hosts hosts_group --ask-vault-pass --extra-vars '@passwd.yaml'

Je l'ai défini pour plusieurs hôtes, chacun avec sa propre clé SSH, phrase de passe SSH et mot de passe SSH Sudo et cela fonctionne très bien. Pour l'article complet, consultez mon git:

https://github.com/flow0787/ansible/blob/master/README.md

0
Florin