Automatiser la gestion des comptes d’administrateurs locaux avec Ansible – Partie 3

Maintenant que je me suis préparé pour pouvoir contrôler mes nombreux serveurs linux avec Ansible, avant d’en automatiser la gestion des comptes d’administrateurs locaux je vais commencer par faire un état des lieux des comptes déjà présents sur ces serveurs.

Je souhaite notamment dresser une liste de tous les comptes d’utilisateur présents sur ces serveurs, pour identifier ceux qui me paraissent indésirables (par exemple, des comptes génériques utilisés par plusieurs personnes, ou des comptes personnels mais de personnes qui ne sont plus administrateurs de ces serveurs) et ceux pour lesquels je devrai me renseigner sur leur utilité.

Pour cela je vais récupérer tous les fichiers /etc/passwd de tous les serveurs et catégoriser tous les comptes d’utilisateurs que je trouverai, de manière à, par exemple, ignorer tous les comptes qui ne m’inquiètent pas parce que je les connais, mettre de côté les comptes qui semblent acceptables et auxquels je m’intéresserai dans un second temps, et au final identifier ceux qui méritent une action prioritaire de ma part.

Récupération de tous les fichiers /etc/passwd avec Ansible

Dans mon dossier “playbooks”, j’ajoute un dossier “recup_passwd” qui va contenir toutes les ressources nécessaires à cet état des lieux. Et dans ce dossier recup_passwd, je vais commencer par créer un premier playbook, nommé recup_passwd.yml, qui a le contenu suivant :

---
- name: recup_passwd
  hosts: all
  remote_user: root
  any_errors_fatal: false

tasks:
  - name: recupere passwd
    fetch:
      src: /etc/passwd
      dest: allpasswd
      fail_on_missing: yes

  - name: trie comptes
    local_action: 
      module: shell
      _raw_params: "./trie_comptes.sh"
    run_once: True

 

Concrètement, ce playbook va faire deux tâches :

  • la première est de récupérer le fichier /etc/passwd de chaque machine, et de le ranger dans un dossier allpasswd. Il n’y aura pas de collision car le module fetch, dans le dossier allpasswd, va créer un dossier par machine.
  • la deuxième consiste à invoquer un script shell qui va trier les comptes. Ce script a pour but de classer les comptes de toutes les machines dans diverses catégories et d’identifier les machines dans lesquelles on les trouve. Contrairement aux tâches classiques ansible, celle ci ne doit pas s’exécuter sur les serveurs distants, mais localement sur le serveur ansible qui aura récupéré tous les fichiers passwd.

 

#!/bin/bash

RESTE=reste.txt

# cree un fichier "categorie" avec les comptes presents dans "fichier" mentionnés dans "liste"
# apres appel a cette fonction, les comptes de "liste" sont retirés du "fichier"
function extrait_comptes {
    categorie="$1"
    fichier="$2"
    liste="$3"
    TMP=`mktemp`

    rm ${categorie}.txt
    for compte in $liste
    do
      echo "$compte existe dans les serveurs suivants :" >> ${categorie}.txt
      grep %${compte}: $fichier | cut -d '%' -f 1 | sort | sed -e 's/^/     /' >> ${categorie}.txt
      echo >> ${categorie}.txt

      cp $fichier $TMP
      cat $TMP | grep -v "%${compte}:"> $fichier
      rm $TMP
    done

}


# initialise un fichier "RESTE" avec tous les comptes de toutes les machines
# au format de /etc/passwd
# en ajoutant le nom du serveur dans une premiere colonne
[ -f $RESTE ] && rm $RESTE

find allpasswd -name passwd -exec grep -H : {} > $RESTE \;
sed -i 's#/etc/passwd:#%#g' $RESTE
sed -i 's#allpasswd/##g' $RESTE


extrait_comptes "comptes_admin_connus" \
                $RESTE \
                "root mapomme "

extrait_comptes "comptes_frequents_ignores" \
                $RESTE \
                "bin daemon "

extrait_comptes "comptes_admin_a_supprimer" \
                $RESTE \
                "duchmol "

 

L’exécution de mon playbook se fait ainsi (par exemple) :

$ ansible-playbook -i preprod.yml playbooks/recup_passwd/recup_passwd.yml

Et là, si la magie opère, ansible se connecte à tous mes serveurs de pré-production, récupère les fichiers /etc/passwd et lance le script shell qui  m’analyse une première fois tout ça.

Avec l’exemple ci-dessus, j’obtiens quatre fichiers, au même endroit que le playbook :

  • un fichier des “comptes admin connus”, qui m’indique tous les serveurs sur lesquels sont présents des comptes d’utilisateurs pour root et mapomme ;
  • un fichier des “comptes fréquents que j’ignore”, où je trouve tous les serveurs sur lesquels sont présents, pour l’instant, les comptes bin et daemon ;
  • un fichier des “comptes admin à supprimer”, où je trouve tous les serveurs sur lesquels est encore présent, par exemple, le compte d’un ancien admin “duchmol” ;
  • et un fichier “reste.txt” dans lequel je retrouve tous les autres comptes, mais plus les comptes root, mapomme, bin, daemon ou duchmol.

En plusieurs passes d’analyse du fichier reste, et en modifiant et en relançant le script trie_comptes.sh à chaque fois, et moyennant l’ajout d’autres catégories, j’ai pu facilement identifier tous les comptes pour lesquels je devais intervenir, et les machines sur lesquelles intervenir, pour supprimer ces comptes, creuser davantage pour savoir à quoi ils servent. Et ce, jusqu’à ce qu’il ne reste plus rien dans reste.txt.

Evidemment, j’ai du relancer le playbook sur tous les groupes de serveurs (production, intégration…) mais une fois les fichiers passwd collectés, il est inutile de relancer le playbook sur l’ensemble des serveurs. Avec près de 500 serveurs, c’est long et inutile puisque les fichiers passwd sont déjà récupérés. Aussi, il est préférable de relancer trie_comptes.sh directement, soit d’appeler le playbook en le limitant à un seul serveur, ce qui a le même effet, et me permet d’introduire un paramètre utile de la commande dans d’autres cas de figure.

$ ansible-playbook -i preprod.yml playbooks/recup_passwd/recup_passwd.yml --limit uniqueserveur

Le paramètre –limit permet de n’exécuter le playbook que sur un sous-ensemble des serveurs de l’inventaire, ici sur celui nommé “uniqueserveur”. C’est très utile en phase de mise au point pour pouvoir tester l’effet d’un playbook sans risquer de tout pêter.

Le paramètre –limit peut prendre le nom d’un serveur de l’inventaire, comme dans cet exemple mais on peut en préciser plusieurs, en les séparant par des virgules ou en utilisant un wildcard, en exclure certains, en les préfixant par un !. Par exemple, pour lancer mon playbook sur tous les serveurs de preprod sauf mon uniqueserveur, je pourrais taper :

$ ansible-playbook -i preprod.yml playbooks/recup_passwd/recup_passwd.yml --limit !uniqueserveur

Dans le prochain article, je décrirai les playbooks qui m’ont permis, après avoir mené cette analyse, de reconfigurer les comptes administrateur de mes serveurs pour répondre à mes objectifs.

Laisser un commentaire