Ansible: Comment changer le mot de passe root du serveur MySQL en réapprovisionnant le serveur

14

J'ai provisionné mon serveur avec le playbook Ansible. J'ai utilisé le playbook root / bedrock-Ansible .

L'une des tâches consistait à configurer le serveur mysql avec le mot de passe de l'utilisateur root mysql.

Maintenant, j'ai un besoin urgent de changer ce mot de passe. Les étapes que j'ai prises:

  1. J'ai mis à jour des variables pour les rôles Ansible
  2. J'ai exécuté la commande ansible-playbook -i hosts/staging server.ymlafin de réapprovisionner le serveur

Toutes les tâches ont été exécutées comme prévu (aucune modification), mais le script a échoué [mariadb | Set root user password]avec ce message:

msg: unable to connect to database, check login_user and login_password are correct or ~/.my.cnf has the credentials

Je suppose qu'une fois le mot de passe racine MySQL défini, le réapprovisionnement du serveur ne peut pas modifier ce mot de passe.

Est-il possible de changer le mot de passe root de MySQL en réapprovisionnant le serveur avec Ansible? Quelles sont mes options?

luqo33
la source

Réponses:

15

Le problème que vous rencontrez est qu'Ansible essaie d'utiliser le même mot de passe root pour vous connecter que vous souhaitez le changer en:

- name: Set root user password
  mysql_user: name=root
              host="{{ item }}"
              password="{{ mysql_root_password }}"
              check_implicit_admin=yes
              login_user="{{ mysql_user }}"
              login_password="{{ mysql_root_password }}"
              state=present

Évidemment, cela ne fonctionnera jamais si vous voulez utiliser ce jeu pour le changer.

Au lieu de cela, vous devez changer le jeu ci-dessus pour qu'il ressemble à:

- name: Set root user password
  mysql_user: name=root
              host="{{ item }}"
              password="{{ mysql_root_password }}"
              check_implicit_admin=yes
              login_user="{{ mysql_user }}"
              login_password="{{ mysql_old_root_password }}"
              state=present

Et puis mettez à jour les fichiers d'inventaire pertinents pour ajouter cette nouvelle variable.

Donc, votre group_vars/productiondevrait maintenant contenir:

mysql_old_root_password: productionpw
mysql_root_password: newproductionpw

Il semble que ce playbook utilise le mot de passe root dans le roles/mariadb/tasks/main.ymlplaybook et aussi roles/wordpress-setup/tasks/database.ymlvous pouvez donc vouloir exécuter tout le server.ymlplaybook pour vous assurer qu'il est correctement configuré.

ydaetskcoR
la source
Merci beaucoup pour une excellente réponse. C'est définitivement la voie à suivre. J'ai fini par réinitialiser le mot de passe root dans la console avec mysqladmin- mais c'était avant de voir votre réponse
luqo33
7

Vous pouvez abuser de ~ / .my.cnf pour pouvoir changer le mot de passe racine mysql.

L'astuce consiste à avoir une tâche "Définir le mot de passe root" (nr.1), qui définira le mot de passe. Ensuite, vous avez une tâche, qui crée un ~ / .my.cnf avec les informations d'identification correctes (nr.2).

Sur un nouveau système, ~ / .my.cnf n'est pas présent. La tâche n ° 1 créera mysql-root-user avec des informations d'identification données. Sur un système actuel, les informations d'identification de ~ / .my.cnf sont utilisées pour se connecter et définir le mot de passe sur mysql_root_password . La tâche n ° 2 créera ~ / .my.cnf , ou remplacera les anciennes informations d'identification existantes ~ / .my.cnf par de nouvelles.

Le gros avantage de cette approche est de n'avoir qu'une seule variable "mysql_root_password", qui est toujours la bonne du point de vue d'un playbook. Sur le ou les systèmes actuels, ~ / .my.cnf est une sorte de stockage pour les identifiants mysql locaux actuels.

- name: Set root user password
  # If .my.cnf already exists, this will cause an mysql-root-password update.
  mysql_user:
    name: root
    password: "{{ mysql_root_password}}"
    check_implicit_admin: true

- name: Create .my.cnf
  template:
   src: "client.my.cnf.j2"
   dest: "/root/.my.cnf"
   owner: root
   group: root
   mode: 0600

avec client.my.cnf.j2:

[client]
user=root
password={{ mysql_root_password }}

Lectures complémentaires

Notes pertinentes de ansible-mysql_user_module-documentation :

  • Note 1:

    Pour sécuriser cet utilisateur dans le cadre d'un playbook idempotent, vous devez créer au moins deux tâches: la première doit changer le mot de passe de l'utilisateur root, sans fournir de détails login_user / login_password. Le second doit supprimer un fichier ~ / .my.cnf contenant les nouvelles informations d'identification racine. Les exécutions suivantes du playbook réussiront ensuite en lisant les nouvelles informations d'identification du fichier. ansible-mysql_user_module, notes

  • Note 2:

    Login_password et login_user sont requis lorsque vous transmettez des informations d'identification. Si aucun n'est présent, le module tentera de lire les informations d'identification à partir de ~ / .my.cnf, et finira par revenir à l'utilisation de la connexion par défaut MySQL de «root» sans mot de passe. ansible-mysql_user_module, notes

Markus Schulte
la source
J'aime assez cette approche et c'est bien mieux que la version dans ma réponse. Ce devrait probablement être la réponse acceptée.
ydaetskcoR
2
C'est pratique, mais sur de nombreux systèmes, il y a en fait 4 utilisateurs «root» créés, avec les hôtes 127.0.0.1, localhost, :: 1 et quel que soit le nom d'hôte local. Ce qui précède ne modifie que root @ localhost, laissant trois autres comptes root avec des mots de passe vides.
robo
Liste tous les utilisateurs root: mysql --database mysql --execute "select host from user where user = 'root';". Ce message fait la même chose que cette réponse mais a un code pour définir tous les mots de passe.
hlovdal
2

Pour la prochaine personne qui vient chercher des réponses ici. Bien que la réponse acceptée soit vraie, vous devez être très diligent si vous utilisez MySQL 5.7 car il n'y a pas de connexion anonyme autorisée dans mysqld en mode démon (service). Au lieu de cela, vous DEVEZ gratter le /var/log/mysqld.log pour un mot de passe TEMPORAIRE que quelqu'un a décidé de créer et d'utiliser sur le login_password = ydaetskcoR. C'est une fonctionnalité qu'ils ont décidé d'implémenter sur la version 5.7 du référentiel de développement, donc si vous voulez l'éviter, utilisez une version plus ancienne (5.6).

Documentation ici: https://dev.mysql.com/doc/refman/5.7/en/server-options.html#option_mysqld_initialize-insecure

http://mysqlserverteam.com/initialize-your-mysql-5-7-instances-with-ease/

einarc
la source
1

Il existe un playbook Ansible utilisé pour renforcer MySQL.

https://github.com/dev-sec/ansible-mysql-hardening

Cela a non seulement changé le mot de passe root, mais effectue également quelques étapes supplémentaires pour durcir le serveur.

Jetez un œil au fichier Lisez-moi.

ww12z
la source
Ne semble pas gérer la modification du mot de passe root lorsqu'il est vide.
flickerfly