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 :
- Connaître la notion de fichier CSV.
- Connaître l’instruction while et la variable d’environnement IFS.
- Être capable de lire et d’utiliser les données d’un fichier CSV.
- Connaître les commande adduser et addgroup.
- Connaître le principe du chiffrement des mots de passe (rappel).
- Connaître des manières de chiffrer des mots de passe sous Linux (mkpasswd, openssl, perl, etc.).
- 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 :
- Le fichier CSV (user.csv)
- Article : How to Parse a CSV File in Bash
- Article : Quotes, apostrophe, guillemets et apostrophe inversée
- Oh My GIT!
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.
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.


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

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.

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.


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.
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!.