SSH, scripts bash, processus, cron et depannage : l'excellence operationnelle visee par LPIC-1 102-500.
SSH (port 22) chiffre l'administration distante. Bonne pratique examen : authentification par cles, interdiction du login root, changement du port optionnel.
ssh-keygen -t ed25519 -C "eleve@lpic1"
ssh-copy-id eleve@serveur1
ssh -p 22 eleve@serveur1
sudo nano /etc/ssh/sshd_config
Port 22
PermitRootLogin no
PasswordAuthentication no
sudo systemctl restart sshd
chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys
PermitRootLogin yes tombe en quelques heures. Clés, root interdit et fail2ban transforment une cible facile en forteresse silencieuse.sudo visudo
# Exemples progressifs :
alice ALL=(ALL) ALL # totale (oky lab, a restreindre en prod)
deploiement ALL=(ALL) /usr/bin/systemctl restart nginx
%compta ALL=(ALL) /usr/bin/apt update, /usr/bin/apt upgrade
Defaults timestamp_timeout=10
Defaults logfile="/var/log/sudo.log"
fail2ban surveille les logs (/var/log/auth.log) et bannit temporairement les IP apres N echecs (anti brute-force SSH). Completez avec : mises a jour regulieres, UFW actif (22 restreint), mots de passe forts, comptes verrouilles (passwd -l), aucune cle en 777.
sudo apt install fail2ban
sudo systemctl enable --now fail2ban
sudo fail2ban-client status
sudo fail2ban-client status sshd
grep "Failed password" /var/log/auth.log
sudo ufw allow from 192.168.1.0/24 to any port 22
ssh-keygen -t ed25519 crée une paire dans ~/.ssh/ : la privée reste chez toi, la publique part avec ssh-copy-id. chmod 700 ~/.ssh et 600 authorized_keys sont vitaux : trop ouverts, SSH ignore la clé sans message clair. sudo sshd -t valide sshd_config avant le restart, et grep "Failed password" /var/log/auth.log révèle l'attaque que fail2ban doit bloquer.777 ou un dossier ~/.ssh en 755 fait rejeter l'authentification par clés. Éditer sshd_config sans tester puis redémarrer à distance enferme dehors. Alice ALL=(ALL) ALL convient au labo, jamais en production où chaque droit se restreint à une commande. fail2ban éteint laisse le brute-force tourner toute la nuit.~/.ssh et authorized_keys pour que la clé soit acceptée ?700 sur ~/.ssh et 600 sur authorized_keys. Plus permissif, et le serveur refuse la clé par sécurité.
sshd_config (PermitRootLogin, PasswordAuthentication), droits 700/600 sur ~/.ssh, ssh-keygen + ssh-copy-id, syntaxe sudoers et visudo, principe de fail2ban (logs - bannissement).#!/bin/bash
# sauvegarde.sh : archive horodatee de /srv
set -u # erreur si variable non definie
SRC="/srv"
DEST="/tmp/srv-$(date +%F).tar.gz"
if [ ! -d "$SRC" ]; then
echo "Erreur : $SRC introuvable" >&2
exit 1
fi
tar czf "$DEST" "$SRC"
echo "Archive creee : $DEST"
exit 0
Puis chmod +x sauvegarde.sh et execution ./sauvegarde.sh ou bash sauvegarde.sh. Le shebang (#!) choisit l'interpreteur.
/srv tout seul avec horodatage et code retour. L'automatisation fiable commence par dix lignes bien écrites.exit la cloche qui dit si le plat est réussi ou raté.NOM="alice" # pas d'espace autour du =
echo "Bonjour $NOM" # guillemets : protege + etend
echo 'Bonjour $NOM' # apostrophes : litteral
echo "./s.sh toto" ; ./s.sh toto
# dans s.sh : $0=nom $1=toto $#=nb $?=retour $$=pid
COMPTEUR=$((COMPTEUR + 1))
echo $((3 + 4 * 2)) # 11
export LANG=fr_FR.UTF-8 # transmise aux fils
# Tests : [ ] classique, [[ ]] etendu
[ -f /etc/passwd ] && echo "fichier present"
[ "$1" = "prod" ] || { echo "usage : $0 prod|test" >&2; exit 2; }
[ -d /data ] || mkdir -p /data
# Boucles
for svc in sshd nginx cron; do
systemctl is-active "$svc"
done
i=1
while [ "$i" -le 3 ]; do echo "tour $i"; i=$((i+1)); done
# Fonction
sauvegarder() {
tar czf "/tmp/$1.tar.gz" "$2"
}
sauvegarder srv /srv
NOM="alice" colle sans espace autour du = ; echo "Bonjour $NOM" étend la variable, echo 'Bonjour $NOM' affiche le texte brut. $1 vaut le premier argument, $# leur nombre, $? le retour de la dernière commande, $((3 + 4 * 2)) calcule 11. [ -f /etc/passwd ] && echo ok n'affiche que si le test réussit : chaque brique se lit comme une phrase.NOM = alice casse l'affectation. Une variable non quotée $SRC éclate sur les espaces : écris toujours "$SRC". Oublier chmod +x bloque l'exécution directe. $1 vide sans test provoque un script qui efface au mauvais endroit : vérifie les arguments et sors avec exit 2 et un message sur stderr.$# et $1 après ./s.sh toto ?$# vaut 1 et $1 vaut toto : $0 est le nom du script, $# compte les arguments, $1 est le premier.
chmod +x, $1/$#/$?/$$, $(( )), tests -e -f -d -r -w -x -z -n, for/while/fonction, exit N et && / ||.ps aux | head # instantane : USER PID %CPU %MEM CMD
ps aux | grep nginx
top # temps reel (q pour quitter) ; htop en couleurs
jobs # taches du shell ; sleep 60 & (arriere-plan)
kill 1234 # SIGTERM (demande polie)
kill -9 1234 # SIGKILL (brutal, sans appel)
pkill -f backup.sh # par motif
nice -n 10 ./lourd.sh # priorite basse ; renice pour ajuster
ps, envoyer le bon signal et décoder un cron à cinq champs permet de tuer proprement le fautif et de prouver pourquoi la tâche planifiée a manqué son rendez-vous.SIGTERM le sifflet qui demande de ranger proprement, SIGKILL le coupe-circuit brutal. cron est le pointeur automatique : cinq cases minute, heure, jour, mois et jour de semaine qui sonnent l'heure exacte du passage.Ordre : minute heure jour-du-mois mois jour-semaine commande. * = toutes les valeurs, */10 = tous les 10.
crontab -l # afficher
crontab -e # editer
# Sauvegarde quotidienne a 2h30 :
30 2 * * * /home/eleve/sauvegarde.sh >> /var/log/sauvegarde.log 2>&1
# Toutes les 10 minutes :
*/10 * * * * /usr/bin/check.sh
# Lundi 8h :
0 8 * * 1 /usr/bin/rapport.sh
# Systeme : /etc/crontab, /etc/cron.d/, /etc/cron.daily/ ...
echo "/home/eleve/sauvegarde.sh" | at 02:30 tomorrow
atq && atrm 3
systemctl list-timers # timers systemd (successeurs modernes de cron)
30 2 * * * /home/eleve/sauvegarde.sh >> /var/log/sauvegarde.log 2>&1 se lit champ par champ : minute 30, heure 2, tous les jours, tous les mois, tous les jours de semaine. La sortie et les erreurs partent dans le même journal grâce à >> ... 2>&1. ps aux | grep backup vérifie pendant l'exécution, kill 1234 demande l'arrêt poli, kill -9 seulement si le processus reste sourd.0 8 * * 1 sonne lundi à 8h, pas à minuit. crontab -r supprime toute la table sans confirmation : sauvegarde avant. cron s'exécute avec un PATH minimal, donc chemins absolus obligatoires. kill -9 en premier réflexe empêche le nettoyage et corrompt des fichiers : toujours SIGTERM d'abord.*/10 * * * * /usr/bin/check.sh ?Elle lance check.sh toutes les 10 minutes, toute la journée : */10 en position minute signifie tous les multiples de 10.
ps aux, SIGTERM vs SIGKILL, ordre des 5 champs cron (piege : minute AVANT heure), crontab -l/-e/-r, repertoires cron.daily vs crontab utilisateur, at = une seule fois.journalctl : journal centralise systemd (-b boot, -u service, -f suivi, -p err erreurs, --since/--until fenetre)./var/log/syslog (Debian) / /var/log/messages (RHEL) : messages generaux./var/log/auth.log (Debian) / /var/log/secure (RHEL) : authentifications SSH/sudo.dmesg : messages du noyau (materiel, pilotes).journalctl -p err -b
journalctl -u sshd --since "2026-01-12 08:00"
grep -i "failed\|error" /var/log/auth.log | tail
tail -f /var/log/syslog
dmesg | grep -i "ata\|usb\|error"
ss, sshd -t et journalctl -u sshd désignent le vrai coupable : une virgule dans sshd_config ou un authorized_keys en 644. La méthode remplace les hypothèses par des preuves.$?).df -h), permissions (ls -l), service actif (systemctl is-active), reseau (ip/ss/ping).journalctl -u du service fautif + auth.log si acces.cp sshd_config sshd_config.bak).systemctl status, test fonctionnel).# Exemple : SSH refuse
systemctl is-active sshd || sudo systemctl start sshd
ss -tlnp | grep :22
sudo sshd -t # teste la syntaxe de sshd_config
journalctl -u sshd -b
ls -ld ~/.ssh && ls -l ~/.ssh/authorized_keys
# 700 et 600 exiges, sinon la cle est ignoree
systemctl is-active sshd dit si le démon vit ; ss -tlnp | grep :22 prouve que le port écoute ; sudo sshd -t valide la syntaxe sans redémarrer ; journalctl -u sshd -b affiche l'erreur exacte avec l'heure ; ls -ld ~/.ssh et ls -l authorized_keys ferment l'enquête sur les droits. Chaque commande élimine une hypothèse jusqu'à la cause racine.sshd_config non testé aggrave la panne : mount -a, sshd -t et visudo -c se lancent toujours avant. dmesg parle du noyau et du matériel, pas des échecs d'authentification qui vivent dans auth.log.sshd_config. Quelle commande teste la syntaxe sans redémarrer ?sudo sshd -t : silence signifie syntaxe valide, message signifie ligne fautive à corriger avant tout restart. Complète avec journalctl -u sshd -b.
journalctl, dmesg = noyau, ordre de diagnostic (disque - droits - service - reseau - logs), tester la config avant de redemarrer (sshd -t, mount -a, visudo -c).Vous durcissez SSH et sudo, ecrivez des scripts bash robustes, planifiez avec cron, et depanpez avec methode via les journaux. Terminez par les missions 5 et 10, le quiz puis l'examen blanc.