Activité Création automatique de comptes d'utilisateur·rice·s

Consigne

Suivez les instructions ci-après et effectuez les tâches demandées.

Situation

Dans le cadre de l’automatisation d’une partie du processus d’onboarding dans votre entreprise, on vous demande de réaliser un script capable de créer des comptes d’utilisateur·rice·s à partir d’un fichier CSV.

Objectifs

À la fin de ce travail, vous devez :

  1. Connaître la notion de fichier CSV.
  2. Connaître l’instruction while et la variable d’environnement IFS.
  3. Être capable de lire et d’utiliser les données d’un fichier CSV.
  4. Connaître les commande adduser et addgroup.
  5. Connaître le principe du chiffrement des mots de passe (rappel).
  6. Connaître des manières de chiffrer des mots de passe sous Linux (mkpasswd, openssl, perl, etc.).
  7. Connaître la différence, en Bash, entre une chaîne placée entre guillemets (double quotes, ), entre apostrophes (single quotes, ), et entre apostrophes inversés (backticks, ` )

Résultat attendu

  • Un bref rapport qui décrit votre travail et votre démarche.
  • Votre script bash.

Ressources

Documents :

Logiciel :

  • Visual Studio Code

Matériel :

  • Un serveur Linux svr-m122-###.lab.epai-ict.ch

Mise en route

Informations complémentaires

Après avoir discuté avec votre supérieur, vous avez obtenu les informations ci-après.

  • La première ligne du fichier contient les en-têtes
  • Le caractère de séparation est le point-virgule (;).
  • Les champs Group1, Group2, Group3 et Group4 sont les noms des groupes supplémentaires de l’utilisateur·rice. Ces champs sont optionnels et peuvent donc être vides.
  • Si un groupe n’existe pas, il doit être créé.
  • Si un compte existe déjà, le script ne doit pas échouer et le compte ne doit pas être modifié.
  • Le script doit écrire les informations ci-après dans stderr :
    • la liste des comptes créés,
    • la liste des comptes qui n’ont pas été modifiés (s’il y en a),
    • la liste des groupes crée (s’il y en a).

Rappels

Pour ajouter et modifier un compte d’utilisateur·rice de manière non interactive, on utilise les commandes useradd.

Le mot de passe fourni à useradd doit être chiffré. Vous devez donc chiffrer les mots de passe du fichier CSV. Pour cela, il existe plusieurs solutions, parmi lesquelles on trouve :

  • La commande openssl passwd
  • L’exécution d’une instruction perl (perl -e 'print crypt("monMotDePasse", "\$6\$monSel"))
  • La commande mkpasswd

L’avantage de OpenSSL et de Perl est qu’ils sont très souvent préinstallés, et permettent tous les deux de chiffrer des mots de passe avec SHA-512 ($6$). En revanche, OpenSSL ne permet pas encore de chiffrer des mots de passe avec yescrypt et Perl ne peut le faire qu’à condition d’installer plusieurs paquets.

Enfin, sous Ubuntu, la commande mkpassword permet de chiffrer avec yescrypt, mais elle n’est généralement pas préinstallée. Toutefois, elle peut être facilement installée avec le paquet whosis du gestionnaire de paquets APT.

Pour affecter le résultat de la commande de chiffrement du mot de passe à une variable, on utilise la substitution de commande $(...). Par exemple :

1
2
3
my_password='epai123'
my_salt='unsel'
password_hash=$(openssl passwd -6 -salt "$my_salt" "$my_password")

Utilisation d’un fichier CSV

Pour utiliser les informations d’un fichier CSV, on a besoin d’une boucle qui permet de traiter le contenu du fichier, une ligne après l’autre.

Par exemple, si l’on a un fichier CSV (input.csv) qui utilise la virgule , comme séparateur de champs, et dont la première ligne contient les entêtes des trois champs, on peut traiter ce fichier avec la commande suivante :

1
2
3
4
5
6
7
8
while IFS="," read -r mon_champ1 mon_champ2 mon_champ3
do
  # Faire quelque chose avec les variables $mon_champ1, $mon_champ2, et $mon_champ3.
  echo "Champ 1 : $mon_champ1"
  echo "Champ 2 : $mon_champ2"
  echo "Champ 3 : $mon_champ3"
  echo ""
done < <(tail -n +2 input.csv)

Dans la commande IFS="," read -r mon_champ1 mon_champ2 mon_champ3, on utilise la commande read que vous connaissez déjà, avec l’option -r pour lui indiquer de ne pas interpréter le les backslash \ comme un caractère d’échappement, et on lui passe la variable d’environnement IFS (Internal Field Separator) pour lui indiquer que le séparateur de champs est la virgule.

Par défaut, la variable IFS contient les caractères espace (0x20), tabulation (0x09) et nouvelle ligne (0x0a). Cela signifie que les champs peuvent être séparés par n’importe quel caractère blanc. La commande suivante vous permet d’afficher le contenu de la variable en hexadécimal :

1
echo -n "$IFS" | hexdump -C

La commande tail -n +2 input.csv permet d’afficher le contenu du fichier à partir de la deuxième ligne, afin de sauter la ligne des entêtes. La syntaxe <(...) permet d’utiliser la sortie d’une commande comme s’il s’agissait d’un fichier. On utilise souvent cette syntaxe lorsqu’il n’est pas possible d’utiliser un tube (pipe, |).

Tâches

Réaliser le script

On vous demande de réaliser un script en bas nommé addusers qui s’utilise de la manière suivante : addusers <chemin du fichier csv>

Si le script est exécuté sans paramètre ou si le premier paramètre est –help ou -h, il doit afficher la syntaxe de la commande et le format du fichier CSV, dans stdout.

Si le fichier passez en paramètre n’existe pas, le script doit afficher un message d’information dans stderr

Si le script est lancé sans privilège, il doit se terminer immédiatement avec un message d’information dans stderr.

Enregister les scripts dans GitLab

Créer un dépôt git dans le serveur

Git est un système de contrôle de version pour le code source. Dans ce petit tutoriel, nous allons voir comment créer un dépôt Git n’importe quel répertoire pour gérer les versions des fichiers qui s’y trouvent.

Pour cela, rendez-vous sur votre serveur Ubuntu et commencez par faire une sauvegarde du répertoire dans lequel vous avez enregistré vos scripts.

Lorsque c’est fait, nous devons encore nous assurer que le compte admin a bien été configuré pour Git, avec les commandes ci-dessous. Avant de lancer ces commandes, remplacez l’adresse de courriel et le nom par votre adresse de courriel et votre nom.

1
2
git config --global user.name "John Smith" 
git config --global user.email "john.smith@exemple.com"

Rendez-vous ensuite dans votre le répertoire de vos scripts (p. ex. ~/projects/m122/scripts) puis lancez la commande suivante pour initialiser le dépôt Git.

1
git init --initial-branch=main

La commande git init crée un répertoire .git qui contient la configuration du dépôt, la zone tampon (staging zone ou index), et le dépôt local (local repository) proprement dit. Le dépôt est dit local par opposition au dépôt distant (remote repo) stocké dans un serveur git. Le dépôt contient toutes les versions de tous les fichiers traqués par le système. Vous pouvez voir ce répertoire en affichant le contenu de votre répertoire de script avec la commande `ls -al.

Avant d’être placés dans le dépôt, les fichiers dont on souhaite valider les changements sont d’abord copiés dans la zone tampon avec la commande git add; la commande git rm permet de retirer un fichier de cette zone. Lorsque l’on est satisfait du contenu de la zone tampon, on utilise la commande git commit pour valider les changements et créer une nouvelle version dans le dépôt local.

Formulaire de création du projet script.
Fig. 1 — Utilisation de GIT

Comme nous venons de créer le dépôt, il n’y a encore aucun fichier contrôlé. Nous pouvons voir cela en lançant la commande suivante :

1
git status

La commande nous informe que nos script ne sont pas traqués. Pour qu’ils le deviennent, copiez ces fichier dans la zone tampon avec la commande suivante :

1
git add .

Le point indique que la commande doit copier tout ce que contient l’espace de travail (le répertoire courant) de manière récursive. Pour ajouter un fichier ou un répertoire particulier, on utilise la même commande, mais avec le chemin relatif du fichier ou du répertoire à la place du point.

Si on lance de nouveau git status, cette fois la commande nous informe que les fichiers ont été modifiés, mais que ces changements n’ont pas encore été validés (commited). Tant que cette validation n’a pas eu lieu, on peut effectuer tous les changement que l’on veut la zone tampon (ajouter, remplacer ou retirer des fichiers).

Pour effectivement valider ces changements et créer une nouvelle version (ici une première version) dans le dépôt local, on utilise la commande git commit avec l’option -m qui permet de donner une description du commit (ici “Initial commit”). En principe, Git est configuré pour exiger une description pour chaque commit.

1
git commit -m "Initial commit"

La commande nous informe que les changements ont été validés. Nous pouvons lancer la commande git status pour nous assurer que tous les changements ont bien été pris en compte. Pour valider de nouveau changement, on lance successivement la commande git add . puis la commande git commit en indiquant la raison du changement avec l’option -m.

En principe, un commit est immuable, il ne peut être modifié. Il est possible, toutefois, d’amender le dernier commit avec l’option --amend à condition que ce commit n’ait pas été synchronisé avec un dépôt distant, comme celui d’un projet GitLab.

Attention : Git n’est pas un système de sauvegarde pour votre travail en cours. Vous devez vous assurer que votre code fonctionne correctement avant de valider des changements avec un commit. En particulier, lorsque le dépôt local est synchronisé avec un dépôt distant. Votre travail en cours doit être sauvegardé par un autre moyen (rsync, Unison, BorgBackup, etc.).

Créer un dépôt dans GitLab

L’EPAI met à votre disposition une instance de GitLab. Gitlab est un gestionnaire de dépôt git et constitue un exemple de ce que l’on appelle une forge logicielle. Ces systèmes soutiennent et facilitent la collaboration entre développeurs, ainsi que l’automatisation de la construction (compilation, édition de lien, etc.), des tests, de la sortie (release) et du déploiement de composants ou systèmes logiciels.

Pour créer un dépôt distant, rendez-vous sur le Gitlab de l’école et ouvrez une session avec votre compte I-FR. Cliquez sur Pojects dans la barre latérale qui se trouve sur la gauche. Dans la page des projets cliquez sur le bouton New project, puis sur Create blank project, et remplissez le formulaire qui s’affiche comme indiqué dans la figure ci-dessous, en remplaçant frossardj par votre nom d’utilisateur·rice.

Formulaire de création du projet script. Formulaire de création du projet script.
Fig. 2 — Création du projet script

Lorsque c’est fait, vous pouvez récupérer l’URI du dépôt git du projet, comme indiqué ci-dessous.

Formulaire de création du projet script.
Fig. 3 — Récupération de l'URI

Il nous reste à lier le dépôt local du serveur au dépôt du projet script dans GitLab (le dépôt distant) et à les synchroniser. Pour cela, commencez par lancer la commande ci-dessous dans votre répertoire de scripts sur votre serveur. Cette commande associe le nom origin à l’URI du dépôt que vous venez de récupérer.

1
git remote add origin git@gitlab.epai-ict.ch:<username>/scripts.git

Lorsque c’est fait, nous pouvons lancer la commande git push avec l’option -u origin main. Cette option permet d’enregistrer l’URI du dépôt de GitLab dans la configuration du dépôt du serveur, pour éviter d’avoir à spécifier cette URI à chaque synchronisation. Après l’exécution de cette commande, la commande git push sans paramètre pousse synchronise le dépôt distant avec le dépôt local.

Toutefois, comme vous pourrez le constater, la commande va échouer avec l’erreur ci-après.

1
git push -u origin main
1
2
3
4
5
6
7
8
9
10
The authenticity of host 'gitlab.epai-ict.ch (172.16.101.44)' can't be established.
ECDSA key fingerprint is SHA256:1vBqAgwN2+NiozqfA31weyAk8jf4C3QqJmrm6OmXw88.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'gitlab.epai-ict.ch' (ECDSA) to the list of known hosts.
git@gitlab.epai-ict.ch: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Pour comprendre le problème, il faut savoir que si l’URI du dépôt commence par git@, la commande git push utilise le protocole ssh, et GitLab exige une authentification par clé publique. Pour résoudre ce problème, nous devons générer une paire de clés pour le compte admin du serveur et copier la clé publique de cette paire dans notre profil GitLab.

Pour cela, exécutez la commande ci-dessous.

1
ssh-keygen -t ed25519 -C admin@svr-m122-32.lab.epai-ict.ch

Affichez la clé publique de la paire que vous venez juste de créer, et copiez-la dans le presse-papier. Rendez-vous ensuite dans GitLab, puis, dans la petite barre de recherche qui se trouve en haut de la barre latérale, tapez « SSH Keys » pour trouver la page de configuration des clés SSH.

Utilisation de la barre de recherche pour se rendre dans la configuration des clés SSH
Fig. 4 — Recherche de la configuration des clés SSH

Lorsque vous êtes sur la page de configuration, cliquez sur le bouton Add key, puis copiez votre clé publique dans la zone de texte prévue à cet effet.

Page de configuration des clés SSH avec un bouton 'Add key' sur la droite. Page de configuration des clés SSH avec un bouton 'Add key' sur la droite.
Fig. 5 — Ajouter une clé

Si tout a été effectué correctement, vous pouvez maintenant relancez la commande git push pour synchroniser le dépôt du projet GitLab avec le dépôt de votre serveur.

1
git push -u origin main
1
2
3
4
5
6
7
8
9
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Delta compression using up to 4 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 262 bytes | 262.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To gitlab.epai-ict.ch:<username>/scripts.git
 * [new branch]      main -> main
Branch 'main' set up to track remote branch 'main' from 'origin'.

Si vous faites des modifications dans votre répertoire (modifier, ajouter ou supprimer un fichier), vous pouvez ajouter ces modifications dans l’index du dépôt git avec la commande git add . ou git add <chemin d'un fichier>, valider les modifications avec la commande git commit -m "raison du changement", puis synchroniser le dépôt du répertoire et celui du projet de GitLab avec la commande git push.

La commande git push synchronise le dépôt distant avec le dépôt local. Pour effectuer la synchronisation dans l’autre sens, on utilise la commande git fetch si l’on synchroniser le dépôt local sans toucher à l’espace de travail (le répertoire de script lui-mêeme), ou git pull si l’on veut également mettre à jour l’espace de travail.

Récupérer une copie du dépôt git de GitLab

Pour récupérer une copie complète du dépôt git de votre projet GitLab, on peut utiliser la commande git clone suivi de l’URI, et éventuellement le nom du répertoire de destination (si le nom du répertoire n’est pas spécifié, Git utilise le nom du projet). Cette commande permet de cloner le dépôt du projet GitLab sur n’importe quelle machine.

Par exemple, ouvrez une nouvelle fenêtre de terminal sur votre PC, et rendez-vous dans votre répertoire de projets. Si ce n’est pas déjà fait, créez un répertoire m122 avec la commande mkdir, rendez-vous dans ce répertoire avec la commande cd, puis lancez la commande ci-dessous.

1
git clone git@gitlab.epai-ict.ch:<username>/scripts.git

Le répertoire créer par cette commande est un clone du dépôt git du projet, en tout point identique au dépôt d’origine. Il est complet et contient toutes les versions de tous les fichiers du projet. La possibilité de cloner un dépôt est la base du travail collaboratif avec git.

Formulaire de création du projet script.
Fig. 6 — Utilisation de GIT

Attention : vous en savez maintenant probablement assez pour être dangereux avec Git, mais pas suffisamment pour être conscient du danger. Assurez-vous de bien maitriser les bases avant de l’utiliser en production. Pour cela, vous pouvez, par exemple, utiliser le jeu sérieux Oh My GIT!.