Je configure un serveur MySQL et souhaite qu'Ansible définisse le mysql-root
mot de passe lors de l'installation.
Avec l'aide d'Internet, j'ai trouvé cette solution:
- name: Set MySQL root password before installing
debconf: name='mysql-server' question='mysql-server/root_password' value='{{mysql_root_pwd | quote}}' vtype='password'
- name: Confirm MySQL root password before installing
debconf: name='mysql-server' question='mysql-server/root_password_again' value='{{mysql_root_pwd | quote}}' vtype='password'
- name: Install Mysql
apt: pkg=mysql-server state=latest
mysql_root_pwd
est une variable chargée à partir du coffre-fort Ansible. Cela fonctionne bien, mais maintenant sur le serveur il y a beaucoup de lignes dans le journal:
Apr 10 14:39:59 servername ansible-debconf: Invoked with value=THEPASSWORD vtype=password question=mysql-server/root_password name=mysql-server unseen=None
Apr 10 14:39:59 servername ansible-debconf: Invoked with value=THEPASSWORD vtype=password question=mysql-server/root_password_again name=mysql-server unseen=None
Comment puis-je empêcher Ansible d'écrire des mots de passe en texte clair dans les fichiers journaux?
Le comportement observé semble être un bogue dans le module debconf. J'ai déposé un rapport de bogue .
L'utilisateur bcoca de github a souligné que l'on peut utiliser le no_log: true
directive dans les tâches, qui définissent les mots de passe, pour empêcher la journalisation. Ceci est une solution de contournement, qui fonctionne pour moi jusqu'à ce que le bug soit corrigé.
Pour empêcher une tâche contenant des informations confidentielles d'être journalisée, dans syslog ou autre, définissez no_log: true sur la tâche:
- name: secret stuff
command: "echo {{secret_root_password}} | Sudo su -"
no_log: true
L'exécution de la tâche sera toujours enregistrée, mais avec peu de détails. De plus, le module utilisé doit prendre en charge no_log, alors testez les modules personnalisés.
Voir Ansible FAQ pour plus de détails. Il peut être appliqué à un playbook entier, mais la sortie devient un peu désagréable avec "censuré!" messages.
Il y a un meilleur moyen que juste no_log: True
- name: write in string variables login and password
set_fact:
temp_user: "{{ USER_VAR }}"
temp_pass: "{{ PASSWORD_VAR }}"
- name: Your operation with password in output
Shell: '/opt/hello.sh'
ignore_errors: True
no_log: True
register: myregister
- debug:
msg: '{{ myregister.stderr | regex_replace(temp_user) | regex_replace(temp_pass) }}'
when: myregister.stderr != ""
- debug:
msg: '{{ myregister.stdout | regex_replace(temp_user) | regex_replace(temp_pass) }}'
when: myregister.stdout != ""
- fail:
msg: "error Shell /opt/hello.sh"
when: myregister.stderr != ""
Comme vous pouvez le voir, vous devez ajouter:
ignore_errors: true
no_log: true
Et puis faites la sortie du résultat de la commande avec regex_replace, où:
USER_VAR - variable de connexion
PASSWORD_VAR - variable de mot de passe
Avec cette approche, vous masquerez non seulement les mots de passe et les connexions, mais obtiendrez également le résultat de votre opération
J'ai résolu en mettant à niveau la version Ansible vers 1.6.1
Sudo pip install ansible==1.6.1
Selon documents Ansible :
log_path
S'il est présent et configuré dans
ansible.cfg
, Ansible enregistrera les informations sur les exécutions à l'emplacement désigné. Assurez-vous que l'utilisateur exécutant Ansible dispose d'autorisations sur le fichier journal:log_path=/var/log/ansible.log
Ce comportement n'est pas activé par défaut. Notez qu'ansible enregistrera, sans ce paramètre, les arguments du module appelés dans le syslog des machines gérées. Les arguments de mot de passe sont exclus.
Sonne comme le réglage log_path
sur votre nœud de contrôle entraînera pas des journaux sur les nœuds de destination.
Ceci est un complément à la réponse de TheDESTROS de ce fil:
wrapper-script.sh.j2
echo {{ secret_eg_from_ansible_vault }} | su - "ls -l"
- name: create template
template:
src: wrapper-script.sh.j2
dest: /tmp/wrapper-script.sh
mode: 0700
no_log: True
- name: invoke command with secret and remove it
Shell: /tmp/wrapper-script.sh; rm -f /tmp/wrapper-script.sh
Vous avez besoin d'un peu moins de code et vous pouvez ignorer les commandes de vos journaux. Il n'y a qu'une seule caveeat, si un secret est dans les commandes stdout. Si vous voulez éviter le modèle externe, le module copy
avec le paramètre content
peut aider à écrire un petit script wrapper à la volée.
Le no_log: true
L'approche doit être utilisée en dernier recours si d'autres tentatives échouent car cela rendra l'exécution de la tâche totalement opaque et vous n'aurez aucune idée de l'échec.
Les pratiques de sécurité recommandent de donner des informations d'identification à partir de stdin ou lorsque cela n'est pas possible en utilisant des fichiers d'informations d'identification (ou même des exécutables).
Voici un exemple sur la façon d'effectuer une connexion podman sécurisée en évitant d'exposer le mot de passe:
- name: secured login
become: true
command: >
podman login --username={{ user }} --password-stdin ...
args:
stdin: "{{ secret }}"
register: result
Avec cela, le secret ne sera pas exposé, dans result
mais vous pourrez toujours voir la sortie de la commande.
La plupart des outils nécessitant une connexion mettent en œuvre l'une des approches les plus sécurisées mentionnées. L'utilisation des informations d'identification sur CLI dans le code est comme avoir 123456
comme mot de passe bancaire.
L'argument environnement du playbook est approprié pour garder un secret caché. Le secret n'est pas imprimé même avec -vvvv. Il est disponible pour toute la pièce.
- hosts: control_Host
gather_facts: no
become: no
environment:
PASSWORD: "{{ password }}"
tasks:
- local_action: "Shell ./foobar.sh ${PASSWORD}"
- local_action: "Shell echo ${PASSWORD}"
production:
ansible-playbook -i ... playbooks/demo.yml -v
PLAY [control_Host] *********************************************************************************
TASK [Shell] *********************************************************************************
changed: [localhost -> localhost] => {
"changed": true,
"cmd": "./foobar.sh ${PASSWORD}",
"delta": "0:00:00.013467",
"end": "2020-04-03 17:42:03.950534",
"rc": 0,
"start": "2020-04-03 17:42:03.937067"
}
TASK [Shell] *********************************************************************************
changed: [localhost -> localhost] => {
"changed": true,
"cmd": "echo ${PASSWORD}",
"delta": "0:00:00.005925",
"end": "2020-04-03 17:42:04.319085",
"rc": 0,
"start": "2020-04-03 17:42:04.313160"
}
STDOUT:
my_secret_password