Mini-test 3
Modifier des fichiers de config sans intervention humaine
8 questions + partie avancee
Cliquez Voir la solution sur chaque slide
Question 1 / 8 3 strategies a connaitre
Nommez les 3 strategies et donnez un exemple de cas ou chacune est appropriee :
| Strategie | Quand l'utiliser | Outil bash |
|---|---|---|
| 1. Ecraser avec sa version | On controle entierement le contenu (versionne dans fichiers-config/) |
cp ou cat ... > |
| 2. Ajouter a la fin | Petits ajouts non destructifs (un bloc fail2ban a la suite) | tee -a, >> |
| 3. Modif chirurgicale | Changer une seule valeur dans un fichier existant qu'on respecte | sed -i |
Bonus : il existe aussi debconf-set-selections
pour repondre a l'avance aux dialogues debconf des paquets (mots de passe
MySQL, acceptations de licence, etc.).
Question 2 / 8 associer commandes -> strategie
Une commande peut aller dans une seule strategie. Plusieurs commandes par strategie. Cliquez sur une etiquette deposee pour la retirer.
Strategie 1 - Ecraser : cp, cat > dest, tee <<EOF (heredoc sans -a). On ne respecte pas l'existant, on remplace.
Strategie 2 - Ajouter a la fin : tee -a, echo >>, cat src >> dest. Le double chevron ou le -a est le marqueur. L'existant reste, on ajoute apres.
Strategie 3 - Modif chirurgicale : sed -i (et sa variante sed -i.bak qui sauvegarde l'original). On respecte le fichier et on touche juste a une ligne ciblee.
Pourquoi pas les autres ?
mv : deplace ou renomme un fichier, ne le modifie pas. Ce n'est pas une strategie d'edition de config.vim : editeur interactif, demande la presence d'un humain. Inutilisable dans un script automatise.Memo : dans un script de provisionnement, regle quelle strategie avant de regarder quel outil. Apres seulement, on choisit l'outil. Et on prefere tee a > ou >> quand on a besoin de sudo (la redirection echoue avec sudo, tee fonctionne).
Question 3 / 8 strategie 1 - ecraser
ircd-hybrid.conf de reference, versionne
a cote de votre script dans ./fichiers-config/ircd-hybrid.conf.
Vous voulez l'installer comme fichier de config du serveur.
Donnez les 2 commandes qui :
# 1. Sauvegarde datee de l'existant sudo cp /etc/ircd-hybrid.conf /etc/ircd-hybrid.conf.bak.$(date +%Y%m%d-%H%M%S) # 2. Copier le fichier de reference par dessus sudo cp ./fichiers-config/ircd-hybrid.conf /etc/ircd-hybrid.conf # Bonus : valider les permissions sudo chown root:root /etc/ircd-hybrid.conf sudo chmod 644 /etc/ircd-hybrid.conf
Pourquoi sauvegarder d'abord ? Si la copie casse
quelque chose, vous voulez pouvoir revenir au fichier original. La
suffixe avec $(date +...) empeche d'ecraser une vieille
sauvegarde en relancant le script.
Variante en heredoc si on ne veut pas de fichier separe :
sudo tee /etc/ircd-hybrid.conf > /dev/null <<'EOF' listen=YES anonymous_enable=NO local_enable=YES enable_ssl=yes EOF
Question 4 / 8 strategie 2 - ajouter a la fin
/etc/fail2ban/jail.local, sans
toucher au reste. Voici la situation :
Donnez la commande bash qui ajoute ce bloc a la fin du fichier /etc/fail2ban/jail.local :
NAME
tee - lit l'entree standard et ecrit dans des fichiers ET stdout
SYNOPSIS
tee [OPTIONS] [FICHIER...]
OPTIONS
-a, --append ajouter (append) au lieu d'ecraser
-i, --ignore-interrupts
ignorer Ctrl-C (utile dans un pipe)
PARTICULARITE
tee est utile pour ecrire dans un fichier qui necessite sudo
depuis un pipe. (Avec >>, la redirection est faite par le shell
AVANT sudo, donc >> echoue sur les fichiers proteges.)
EXEMPLES
# Ecraser un fichier (silencer stdout avec /dev/null)
echo "ligne" | sudo tee /etc/config > /dev/null
# Ajouter a la fin
echo "ligne" | sudo tee -a /etc/config > /dev/null
# Avec heredoc multilignes
sudo tee -a /etc/fail2ban/jail.local > /dev/null <<'EOF'
[ircd-hybrid]
enabled = true
EOF
REDIRECTION
> fichier ecrase
>> fichier ajoute a la fin (append)
2> fichier redirige stderr
&> fichier redirige stdout ET stderr
2>&1 fusionne stderr dans stdout
> /dev/null ignorer la sortie
PIEGE AVEC SUDO
sudo cmd >> /fichier-protege # echoue !
Raison : le shell ouvre /fichier-protege AVANT d'invoquer sudo,
donc l'ouverture se fait avec les droits de l'utilisateur.
Solution : passer par "sudo tee -a" (la redirection est interne).
HEREDOC (here-document)
<<DELIMITEUR lit du texte inline jusqu'a la ligne DELIMITEUR
<<'DELIMITEUR' delimiteur quote -> PAS d'expansion de variables
(utile pour les fichiers contenant $, `, etc.)
<<-DELIMITEUR accepte les TABS de retrait (mais pas les espaces)
EXEMPLE complet
sudo tee -a /etc/fail2ban/jail.local > /dev/null <<'EOF'
[ircd-hybrid]
enabled = true
port = 6667
EOF
sudo tee -a /etc/fail2ban/jail.local > /dev/null <<'EOF' [ircd-hybrid] enabled = true port = 6667 logpath = /var/log/ircd-hybrid/ircd.log EOF
Decomposition :
tee -a = append (ajoute a la fin du fichier)> /dev/null = on masque l'echo de tee (qui repete ce qu'il ecrit dans stdout)<<'EOF' ... EOF = heredoc : un bloc de texte inline'EOF' = pas d'interpretation des $variables dans le blocEquivalent plus court pour une seule ligne :
echo "[ircd-hybrid]" | sudo tee -a /etc/fail2ban/jail.local # Mais pour un bloc de plusieurs lignes, le heredoc est plus propre
Probleme cache : si on relance le script, ce bloc sera ajoute une deuxieme fois. On verra comment regler ca dans la partie avancee a la fin du mini-test.
Question 5 / 8 strategie 3 - sed chirurgical
/etc/ircd-hybrid.conf contient la ligne suivante
(avec un # qui la rend inactive) :
Vous voulez decommenter cette ligne (retirer le #) avec une seule commande sed dans votre script. Donnez la commande, et expliquez chaque element.
NAME
sed - stream editor (editeur de flux ligne par ligne)
SYNOPSIS
sed [OPTIONS] 'COMMANDE' [FICHIER...]
OPTIONS frequentes
-i edition in-place (modifie le fichier)
-i.bak sauvegarde l'original sous .bak avant
-n ne pas imprimer par defaut (avec p pour selectionner)
-E regex etendues (sans backslash devant + ? | ())
-e CMD plusieurs commandes (peut etre repete)
COMMANDE substitution
s/MOTIF/REMPLACEMENT/FLAGS
FLAGS
g toutes les occurrences (defaut : la 1ere seulement)
i insensible a la casse
2 2e occurrence seulement
ANCRES utiles
^ debut de ligne
$ fin de ligne
. un caractere
.* zero ou plus de caracteres
ADRESSES (selectionner les lignes a traiter)
/MOTIF/ s/.../.../ seulement les lignes qui matchent
3 s/.../.../ seulement la ligne 3
3,7 s/.../.../ lignes 3 a 7
EXEMPLES
# Decommenter une ligne precise
sudo sed -i 's/^#enable_ssl=yes/enable_ssl=yes/' /etc/ircd-hybrid.conf
# Avec backup .bak (securite)
sudo sed -i.bak 's/^#enable_ssl/enable_ssl/' /etc/ircd-hybrid.conf
# Changer un parametre (n'importe quelle valeur)
sudo sed -i 's/^Port .*/Port 2222/' /etc/ssh/sshd_config
# Decommenter (espace optionnel apres #)
sudo sed -i 's/^# *PasswordAuthentication/PasswordAuthentication/' /etc/ssh/sshd_config
# Astuce delimiteur : si le motif contient des /, utiliser un autre delimiteur
sudo sed -i 's|/var/log/old|/var/log/new|' /etc/syslog.conf
sudo sed -i 's/^#enable_ssl=yes/enable_ssl=yes/' /etc/ircd-hybrid.conf
Decomposition :
sed - l'editeur de flux-i - in-place, modifie le fichier directement
(sinon sed ecrit sur stdout sans toucher au fichier)s/MOTIF/REMPLACEMENT/ - commande "substitute"^ dans le motif - ancre le debut de ligne
(evite de toucher des lignes qui contiendraient ce texte ailleurs)/ peut etre remplace par n'importe quel caractere si
le motif en contient (ex. s|/var/log|/srv/log|)Variantes utiles :
# Activer une option pas encore presente (apres une ligne specifique) sudo sed -i '/^[General]/a enable_ssl=yes' /etc/ircd-hybrid.conf # Remplacer une valeur quelconque sudo sed -i 's/^max_clients=.*/max_clients=50/' /etc/ircd-hybrid.conf # Tester d'abord SANS -i (afficher le resultat) sed 's/^#enable_ssl=yes/enable_ssl=yes/' /etc/ircd-hybrid.conf | less
Question 6 / 8 retirer l'interactivite - niveaux 1 et 2
Donnez :
NAME
apt-get - utilitaire APT en ligne de commande (scriptable)
SYNOPSIS
apt-get [OPTIONS] COMMANDE [PAQUET...]
COMMANDES principales
update rafraichit la liste des paquets disponibles
install installer ou mettre a niveau un paquet
upgrade mettre a niveau tous les paquets installes
dist-upgrade comme upgrade mais peut ajouter/retirer des paquets
remove retirer un paquet (conserve les fichiers de config)
purge retirer + effacer les fichiers de config
autoremove retirer les paquets installes en dependance et non utilises
OPTIONS utiles en script
-y, --yes repond "yes" automatiquement aux prompts
-q, --quiet moins de sortie (utile dans les logs)
--no-install-recommends n'installer que les vraies dependances
-o Dpkg::Options::="..." passer une option a dpkg
CONFLITS DE CONFIG (fichiers /etc/*)
Quand un paquet propose un nouveau /etc/foo.conf et que vous l'aviez modifie,
dpkg vous demande quoi faire. Pour scripter, on choisit AVANT :
-o Dpkg::Options::="--force-confdef"
preserver le defaut decide par le mainteneur
-o Dpkg::Options::="--force-confold"
garder l'ANCIEN fichier (votre version modifiee)
-o Dpkg::Options::="--force-confnew"
ecraser avec le NOUVEAU fichier du paquet
VARIABLES D'ENVIRONNEMENT
DEBIAN_FRONTEND=noninteractive
desactive TOUS les dialogues debconf (questions
"voulez-vous installer X comme service ?")
APT_LISTCHANGES_FRONTEND=none
desactive l'affichage des changelogs
EXEMPLES
# Installation completement silencieuse
export DEBIAN_FRONTEND=noninteractive
sudo apt-get install -y \
-o Dpkg::Options::="--force-confdef" \
-o Dpkg::Options::="--force-confold" \
ircd-hybrid
# Inline (frontend juste pour cette commande)
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y ircd-hybrid
# Minimaliste (pas de paquets recommandes)
sudo apt-get install -y --no-install-recommends nginx
export DEBIAN_FRONTEND=noninteractive sudo apt-get install -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" ircd-hybrid
Niveau 1 : switch -y
Repond "yes" aux questions de confirmation classiques d'apt ("Do you want to continue?"). Sans ca, le script s'arrete en attendant votre touche.
Niveau 2 : DEBIAN_FRONTEND=noninteractive
Variable d'environnement qui dit au gestionnaire de paquets Debian/Ubuntu : "pas d'interface utilisateur, pas de question, choisis les defauts". Couvre les dialogues debconf (les ecrans bleus qui demandent par exemple un mot de passe MySQL).
Niveau 3 (avance) : les options Dpkg
--force-confdef : utilise le defaut du paquet en cas
de conflit de config--force-confold : garde l'ancienne config si on
est en mise a jourToujours utiliser apt-get dans les scripts
(interface stable), pas apt (interface
utilisateur qui peut changer).
Question 7 / 8 retirer l'interactivite - niveau 3
mysql-server, un ecran bleu vous
demande le mot de passe root MySQL. Vous voulez automatiser ca.
Donnez la sequence de commandes pour :
NAME
debconf-set-selections - precharger des reponses dans la base debconf
SYNOPSIS
debconf-set-selections [--checkonly] [--verbose] [FICHIER]
DESCRIPTION
Permet de repondre AVANT installation aux questions debconf
(les ecrans bleus de configuration). Lit des lignes au format :
PAQUET QUESTION/CLE TYPE VALEUR
TYPES (champ 3)
string texte libre (ex: nom, mot de passe)
password identique mais pour les mdp
boolean true | false
select un choix parmi plusieurs
multiselect plusieurs choix
DECOUVRIR les cles d'un paquet
# Installer debconf-utils une fois
sudo apt-get install -y debconf-utils
# Voir TOUTES les cles + valeurs courantes d'un paquet installe
sudo debconf-get-selections | grep mysql-server
EXEMPLES
# Format ligne directe
echo 'mysql-server mysql-server/root_password password motdepasse' | \
sudo debconf-set-selections
# Avec heredoc multi-lignes
sudo debconf-set-selections <<EOF
mysql-server mysql-server/root_password password motdepasse
mysql-server mysql-server/root_password_again password motdepasse
EOF
# Puis installation silencieuse
export DEBIAN_FRONTEND=noninteractive
sudo apt-get install -y mysql-server
PIEGES
- debconf-set-selections doit etre lance AVANT apt-get install
- DEBIAN_FRONTEND=noninteractive doit aussi etre exporte
- Les espaces entre les champs sont libres (tabs ou espaces)
export DEBIAN_FRONTEND=noninteractive # 1. Pre-positionner les reponses sudo debconf-set-selections <<EOF mysql-server mysql-server/root_password password monMotDePasse mysql-server mysql-server/root_password_again password monMotDePasse EOF # 2. Installer normalement sudo apt-get install -y mysql-server
Comment trouver les bonnes cles debconf ?
# Apres avoir installe le paquet manuellement une fois, on regarde # les questions posees : sudo debconf-get-selections | grep mysql-server
Hierarchie complete pour retirer l'interactivite :
-y, --yes, --assume-yesDEBIAN_FRONTEND=noninteractiveuseradd au lieu de adduser,
chpasswd au lieu de passwddebconf-set-selections pour repondre a l'avance aux dialoguesman de la commande pour --batch, --quiet, --auto...expect (simule un humain qui tape)Question 8 / 8 tout assembler
enable_ssl dans /etc/ircd-hybrid.conf[ircd-hybrid] a /etc/fail2ban/jail.local (idempotent)Ecrivez le bout de script (pas besoin de la banniere ni du shebang) :
export DEBIAN_FRONTEND=noninteractive
set -e
# 1. Mise a jour et installation
sudo apt-get update -y
sudo apt-get install -y ircd-hybrid
# 2. Activer enable_ssl (strategie sed - ligne deja presente, commentee)
sudo sed -i 's/^#enable_ssl=yes/enable_ssl=yes/' /etc/ircd-hybrid.conf
# 3. Ajouter le bloc fail2ban (strategie tee -a, idempotente)
if ! grep -q '^\[ircd-hybrid\]' /etc/fail2ban/jail.local 2>/dev/null; then
sudo tee -a /etc/fail2ban/jail.local > /dev/null <<'EOF'
[ircd-hybrid]
enabled = true
port = 21
logpath = /var/log/ircd-hybrid.log
EOF
fi
# 4. Redemarrer les services
sudo systemctl restart ircd-hybrid
sudo systemctl restart fail2ban
echo "Configuration terminee."
Astuces du pro :
set -e arrete le script au premier echec (evite de continuer si l'install rate)2>/dev/null sur le grep evite l'erreur si le fichier n'existe pas encorePartie avancee
Idempotence, securite, robustesse :
les techniques pour des scripts qui ne cassent rien quand on les relance
Ces questions vont plus loin que l'examen.
Elles construisent des reflexes de "vrai" admin.
Question avancee 1 idempotence : detecter avant d'agir
[ircd-hybrid] a la fin de
/etc/fail2ban/jail.local avec tee -a. Si on relance
le script (parce qu'on veut corriger une autre etape), le bloc
est ajoute une deuxieme fois. Resultat : un fichier qui contient
deux fois le meme bloc, et fail2ban refusera de demarrer.
Modifiez la commande pour qu'elle detecte si le bloc est deja present et n'ajoute rien dans ce cas. Donnez la commande complete (avec la detection).
Indice : la cle est de tester avant d'agir. Quelle commande retourne un code de sortie 0 ou non-0 selon qu'un motif est dans un fichier ?
NAME
grep - chercher des motifs dans des fichiers
SYNOPSIS
grep [OPTIONS] MOTIF [FICHIER...]
OPTIONS frequentes
-q, --quiet aucune sortie - utilise UNIQUEMENT le code de retour
-F, --fixed-strings motif litteral (pas de regex)
-E, --extended-regexp regex etendues
-i, --ignore-case insensible a la casse
-v, --invert-match inverser (lignes qui NE matchent PAS)
-c, --count compter les lignes
-n, --line-number afficher les numeros de ligne
-r, --recursive recursif dans un dossier
-l, --files-with-matches juste les noms de fichiers
-x, --line-regexp match la ligne entiere
CODES DE SORTIE (cle pour scripter)
0 au moins un match trouve
1 aucun match
2 erreur (fichier introuvable, etc.)
Donc en bash : "if grep -q ... ; then ..." marche sans piping
ni $(...). C'est l'idiome standard pour "tester si X est dans un fichier".
ANCRES (regex de base)
^MOTIF debut de ligne
MOTIF$ fin de ligne
^MOTIF$ ligne entiere
Caracteres a echapper dans le motif : [ ] . * + ? ( ) | { } $ ^
Avec -F, tout est litteral, plus besoin d'echapper.
EXEMPLES (idempotence)
# Ajouter un bloc seulement s'il n'existe pas deja
if ! grep -q '^\[ircd-hybrid\]' /etc/fail2ban/jail.local 2>/dev/null; then
sudo tee -a /etc/fail2ban/jail.local > /dev/null <<'EOF'
[ircd-hybrid]
enabled = true
EOF
fi
# Variante : grep -qF si le motif contient des caracteres regex penibles
if ! grep -qF '[ircd-hybrid]' /etc/fail2ban/jail.local 2>/dev/null; then
...
fi
# Cibler la ligne entiere (eviter les faux positifs)
if ! grep -qx 'PasswordAuthentication no' /etc/ssh/sshd_config; then
...
fi
La technique : grep -q + if !
if ! grep -q '^\[ircd-hybrid\]' /etc/fail2ban/jail.local 2>/dev/null; then
sudo tee -a /etc/fail2ban/jail.local > /dev/null <<'EOF'
[ircd-hybrid]
enabled = true
port = 6667
logpath = /var/log/ircd-hybrid/ircd.log
EOF
fi
Decomposition :
grep -q : quiet, n'affiche rien, retourne juste un code de sortie (0 si trouve, 1 sinon)^\[ircd-hybrid\] : ancre au debut de ligne + crochets echappesif ! : "si NON trouve, alors..."2>/dev/null : si le fichier n'existe pas encore, on masque l'erreurLe terme : idempotence
Une operation est idempotente si la rejouer N fois donne le meme resultat que la jouer une seule fois. En administration systeme, c'est une qualite essentielle : on doit pouvoir relancer un script (apres un crash, une correction) sans craindre de tout casser.
Autres patterns d'idempotence dans la vraie vie :
# mkdir -p ne genere pas d'erreur si le repertoire existe deja
mkdir -p /var/backups/ircd
# useradd n'echoue plus si le -f est mis (force)
id -u mqtt-iot &>/dev/null || sudo adduser --system mqtt-iot
# systemctl is-enabled avant enable
systemctl is-enabled ircd-hybrid || sudo systemctl enable ircd-hybrid
# Marker file : ne refaire qu'une fois
if [ ! -f /var/lib/mon-script.done ]; then
# ... operations
touch /var/lib/mon-script.done
fi
Ces outils existent precisement parce que rendre un script idempotent est la bonne pratique fondamentale en administration. C'est aussi ce qu'Ansible et les outils de configuration management font automatiquement.
Bilan
Touche R pour recommencer ce mini-test