TP – LAMP, SSH par clés et sauvegarde avec cron
BTS SIO SISR 1re année – Bloc 2 – S13
Note
But. Situation : Comment automatiser la création de 30 comptes, héberger un site web et administrer un serveur sans quitter son bureau ?
Comment ce TP fonctionne. Avant de manipuler, tu écris ce que tu anticipes (« J'anticipe »). Puis tu testes et tu notes ce que tu constates. Tu comprends ce que fait chaque commande (« Je comprends »). Un bilan de compétences clôt la séance. Les parties de services (Linux, Windows Server) se font sur des machines virtuelles réelles ; le simulateur réseau ou Packet Tracer servent aux manipulations d'équipements réseau.
Contexte
SimIO SARL vous confie la mise en place de son serveur applicatif interne. Ce TP est structuré en 4 parties progressives, chacune s'appuyant sur la précédente : - A : Installer et valider la pile LAMP - B : Exercices Bash sur les boucles - C : Configurer SSH par clés et sécuriser l'accès - D : Script de sauvegarde automatisée planifié avec cron
PARTIE A — Installation de la Pile LAMP
A1 — Mise à Jour du Système
A2 — Installation d'Apache
# Installer Apache
sudo apt install apache2 -y
# Vérifier qu'Apache fonctionne
sudo systemctl status apache2
# S'assurer qu'il démarre au boot
sudo systemctl enable apache2
Test : Ouvrir un navigateur sur la VM cliente et taper l'adresse IP du serveur. La page par défaut Apache ("Apache2 Default Page") doit s'afficher.
Capturer cette page : Capture A1.
A3 — Installation de MariaDB
# Installer MariaDB
sudo apt install mariadb-server -y
# Démarrer et activer au boot
sudo systemctl enable --now mariadb
# Vérifier le statut
sudo systemctl status mariadb
Sécuriser l'installation MariaDB :
Répondre aux questions comme suit :
| Question | Réponse recommandée |
|---|---|
| Set root password ? | Yes — définir un mot de passe fort |
| Remove anonymous users ? | Yes |
| Disallow root login remotely ? | Yes |
| Remove test database ? | Yes |
| Reload privilege tables ? | Yes |
Test : Se connecter à MariaDB
sudo mysql -u root -p
# Taper le mot de passe défini ci-dessus
# Résultat attendu : prompt "MariaDB [(none)]>"
Capturer le prompt MariaDB : Capture A2. Puis EXIT;
J'anticipe. Pourquoi lance-t-on mysql_secure_installation ? Cite deux choses qu'il corrige. ______________________
Éléments de réponse
Il durcit une installation par défaut : définition du mot de passe de root, suppression des utilisateurs anonymes, interdiction de la connexion de root à distance, suppression de la base de test.
A4 — Installation de PHP
# Installer PHP et le module Apache + connecteur MariaDB
sudo apt install php libapache2-mod-php php-mysql -y
# Vérifier la version installée
php -v
A5 — Créer une Page de Test PHP
Contenu du fichier :
<?php
echo "<h1>PHP fonctionne sur le serveur SimIO !</h1>";
echo "<p>Version PHP : " . phpversion() . "</p>";
echo "<p>Date et heure serveur : " . date('d/m/Y H:i:s') . "</p>";
phpinfo();
?>
Sauvegarder et tester depuis le navigateur : http://[IP_SERVEUR]/test.php
Capturer la page phpinfo : Capture A3.
# [ATTENTION] SUPPRIMER le fichier de test après validation (règle de sécurité)
sudo rm /var/www/html/test.php
A6 — Créer une Base de Données et un Utilisateur Dédié
Dans le prompt MariaDB :
-- Créer la base de données pour l'application
CREATE DATABASE siosarl_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- Créer un utilisateur dédié (ne jamais utiliser root pour l'application)
CREATE USER 'webuser'@'localhost' IDENTIFIED BY 'SioSarl!Web2024';
-- Accorder les droits nécessaires
GRANT ALL PRIVILEGES ON siosarl_db.* TO 'webuser'@'localhost';
-- Recharger les droits
FLUSH PRIVILEGES;
-- Vérifier
SHOW DATABASES;
SELECT user, host FROM mysql.user;
EXIT;
Capturer les résultats de SHOW DATABASES et SELECT user : Capture A4.
A7 — Créer une Page PHP de Connexion BDD
<?php
$serveur = "localhost";
$login_bdd = "webuser";
$mdp_bdd = "SioSarl!Web2024";
$base = "siosarl_db";
try {
$pdo = new PDO(
"mysql:host=$serveur;dbname=$base;charset=utf8mb4",
$login_bdd,
$mdp_bdd
);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "<h2 style='color:green'>Connexion à MariaDB réussie !</h2>";
echo "<p>Base de données : <strong>$base</strong></p>";
echo "<p>Serveur : <strong>$serveur</strong></p>";
} catch (PDOException $e) {
echo "<h2 style='color:red'>Erreur de connexion</h2>";
echo "<p>" . htmlspecialchars($e->getMessage()) . "</p>";
}
?>
Tester dans le navigateur : http://[IP_SERVEUR]/connexion_bdd.php
Capturer le message de succès : Capture A5.
PARTIE B — Exercices Bash : Boucles
B1 — Inventaire des Services LAMP
Créer /home/user/scripts/verif_lamp.sh :
#!/bin/bash
# ═══════════════════════════════════════════════════
# Script : verif_lamp.sh
# Rôle : Vérifier l'état des services de la pile LAMP
# ═══════════════════════════════════════════════════
echo "================================================="
echo " VÉRIFICATION DE LA PILE LAMP — SimIO SARL"
echo " $(date '+%d/%m/%Y à %H:%M:%S')"
echo "================================================="
echo ""
SERVICES=("apache2" "mariadb" "php8.2-fpm")
TOUS_OK=true
for SERVICE in "${SERVICES[@]}"
do
# Vérifier si le paquet est installé
if ! dpkg -l "$SERVICE" > /dev/null 2>&1
then
echo " [N/A] $SERVICE — Non installé"
continue
fi
# Vérifier si le service est actif
if systemctl is-active --quiet "$SERVICE"
then
echo " [OK] $SERVICE est ACTIF"
else
echo " [KO] $SERVICE est INACTIF !"
TOUS_OK=false
fi
done
echo ""
if [ "$TOUS_OK" = true ]
then
echo "[OK] Pile LAMP opérationnelle."
else
echo "[ATTENTION] Un ou plusieurs services LAMP sont inactifs. Vérifiez les logs !"
fi
B2 — Analyse de Fichier : Extraire les Utilisateurs Système
Créer /home/user/scripts/liste_users.sh :
#!/bin/bash
# ═══════════════════════════════════════════════════
# Script : liste_users.sh
# Rôle : Lister les utilisateurs avec shell valide
# ═══════════════════════════════════════════════════
echo "=== Utilisateurs avec un shell valide ==="
echo ""
COMPTEUR=0
while IFS=: read -r LOGIN MDPH ID_USER ID_GROUPE INFO REP_HOME SHELL_USER
do
# Ne lister que les utilisateurs avec un shell interactif
if [ "$SHELL_USER" = "/bin/bash" ] || [ "$SHELL_USER" = "/bin/sh" ]
then
COMPTEUR=$(( COMPTEUR + 1 ))
echo " $COMPTEUR. Login: $LOGIN | UID: $ID_USER | Home: $REP_HOME | Shell: $SHELL_USER"
fi
done < /etc/passwd
echo ""
echo "Total : $COMPTEUR utilisateur(s) avec shell interactif."
PARTIE C — SSH par Clés Publique/Privée
Configuration : La VM cliente (poste depuis lequel vous vous connectez) et la VM serveur LAMP doivent être sur le même réseau virtuel. Notez l'IP de la VM serveur :
_______________
C1 — Générer une Paire de Clés SSH sur la VM Cliente
Sur la VM cliente (pas le serveur LAMP) :
# Générer une paire de clés Ed25519 (algorithme moderne recommandé)
ssh-keygen -t ed25519 -C "admin@siosarl.local"
# À la question "Enter file in which to save the key" : appuyer sur Entrée (chemin par défaut)
# À la question "Enter passphrase" : laisser vide (pour le TP) ou saisir une passphrase
# Vérifier les clés générées
ls -la ~/.ssh/
# → id_ed25519 (privée, permissions 600) et id_ed25519.pub (publique)
# Afficher la clé publique
cat ~/.ssh/id_ed25519.pub
Capturer la sortie de ls -la ~/.ssh/ : Capture C1.
C2 — Copier la Clé Publique sur le Serveur
# Méthode automatique (recommandée)
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@[IP_SERVEUR]
# → Entrer le mot de passe habituel une dernière fois
# Vérifier que la clé a bien été ajoutée sur le serveur
ssh user@[IP_SERVEUR] "cat ~/.ssh/authorized_keys"
C3 — Tester la Connexion par Clé
# Se connecter sans mot de passe
ssh user@[IP_SERVEUR]
# → La connexion doit s'établir SANS demander de mot de passe
Capturer la connexion sans mot de passe : Capture C2.
C4 — Sécuriser le Serveur SSH
Sur la VM serveur :
# Sauvegarder la configuration avant modification
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup
# Modifier la configuration
sudo nano /etc/ssh/sshd_config
Modifier/vérifier les lignes suivantes :
# Vérifier la syntaxe avant de redémarrer (évite de se bloquer dehors !)
sudo sshd -t
# Redémarrer SSH
sudo systemctl restart ssh
# Tester depuis la VM cliente que la connexion par clé fonctionne toujours
ssh user@[IP_SERVEUR]
Capturer le résultat de sudo sshd -t (doit être silencieux = OK) : Capture C3.
J'anticipe. Tu désactives l'authentification par mot de passe avant d'avoir testé la connexion par clé. Que risques-tu ? ______________________
Éléments de réponse
De te verrouiller dehors : plus aucun moyen de te connecter si la clé ne fonctionne pas. On teste la clé dans une seconde session, en gardant la première ouverte, avant de recharger SSH.
PARTIE D — Script de Sauvegarde Automatisée avec Cron
Contexte
SimIO SARL vous demande de mettre en place une sauvegarde nocturne automatique du site web (/var/www/html) et de la configuration Apache (/etc/apache2). Cette sauvegarde doit :
- Être exécutée tous les jours à 2h00
- Créer une archive compressée horodatée
- Conserver les 7 dernières sauvegardes seulement
- Journaliser chaque opération avec horodatage
- Envoyer un compte-rendu lisible (succès ou échec de chaque étape)
D1 — Préparer l'Environnement
# Créer le répertoire de sauvegardes
sudo mkdir -p /var/backups/siosarl
# Créer le répertoire des scripts d'administration
sudo mkdir -p /usr/local/bin/siosarl
# Créer quelques fichiers de test dans le site web
echo "<h1>Page d'accueil SimIO</h1>" | sudo tee /var/www/html/index.html
echo "<?php echo 'App SimIO'; ?>" | sudo tee /var/www/html/app.php
sudo mkdir -p /var/www/html/assets
D2 — Écrire le Script de Sauvegarde
#!/bin/bash
# ═══════════════════════════════════════════════════════════════════════
# Script : sauvegarde.sh
# Auteur : [Votre nom]
# Date : [Date]
# Version : 1.0
# Rôle : Sauvegarde automatique du serveur web SimIO SARL
# - Sauvegarde /var/www/html et /etc/apache2
# - Archives horodatées compressées en .tar.gz
# - Conservation des 7 dernières sauvegardes (rotation)
# - Journalisation complète dans /var/log/sauvegarde_siosarl.log
# Usage : preuve pour une fiche de réalisation (E6) – B2.2, B2.3
# ═══════════════════════════════════════════════════════════════════════
# ─── VARIABLES DE CONFIGURATION ────────────────────────────────────────
REPERTOIRES_SOURCE=("/var/www/html" "/etc/apache2")
REPERTOIRE_BACKUP="/var/backups/siosarl"
FICHIER_LOG="/var/log/sauvegarde_siosarl.log"
NB_SAUVEGARDES_MAX=7
PREFIXE="backup_siosarl"
DATE=$(date "+%Y-%m-%d_%H-%M-%S")
NOM_ARCHIVE="${PREFIXE}_${DATE}.tar.gz"
CHEMIN_ARCHIVE="${REPERTOIRE_BACKUP}/${NOM_ARCHIVE}"
STATUT_GLOBAL=0 # 0 = succès, 1 = échec
# ─── FONCTIONS ──────────────────────────────────────────────────────────
# Fonction d'écriture dans le log
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$FICHIER_LOG"
}
# Fonction de vérification du code retour
verifier() {
if [ $? -eq 0 ]
then
log "[OK] $1"
else
log "[ERREUR] $1 : échec"
STATUT_GLOBAL=1
fi
}
# ─── DÉBUT DU SCRIPT ─────────────────────────────────────────────────────
log "========================================================"
log " DÉBUT DE SAUVEGARDE — SimIO SARL"
log " Archive : $NOM_ARCHIVE"
log "========================================================"
# ─── VÉRIFICATION DU RÉPERTOIRE DE BACKUP ────────────────────────────────
if [ ! -d "$REPERTOIRE_BACKUP" ]
then
log "Création du répertoire de backup : $REPERTOIRE_BACKUP"
mkdir -p "$REPERTOIRE_BACKUP"
verifier "Création répertoire backup"
fi
# ─── VÉRIFICATION DES SOURCES ────────────────────────────────────────────
log "Vérification des répertoires sources..."
for SOURCE in "${REPERTOIRES_SOURCE[@]}"
do
if [ -d "$SOURCE" ]
then
TAILLE=$(du -sh "$SOURCE" | cut -f1)
log "[OK] Source : $SOURCE ($TAILLE)"
else
log "[ATTENTION] Source absente ou vide : $SOURCE — Ignoré."
fi
done
# ─── CRÉATION DE L'ARCHIVE ────────────────────────────────────────────────
log "Création de l'archive : $NOM_ARCHIVE"
tar -czf "$CHEMIN_ARCHIVE" \
"${REPERTOIRES_SOURCE[@]}" \
2>> "$FICHIER_LOG"
verifier "Création archive tar.gz"
# ─── VÉRIFICATION DE L'ARCHIVE CRÉÉE ─────────────────────────────────────
if [ -f "$CHEMIN_ARCHIVE" ]
then
TAILLE_ARCHIVE=$(du -sh "$CHEMIN_ARCHIVE" | cut -f1)
log "Archive créée avec succès : $CHEMIN_ARCHIVE ($TAILLE_ARCHIVE)"
# Vérifier l'intégrité de l'archive
tar -tzf "$CHEMIN_ARCHIVE" > /dev/null 2>&1
verifier "Vérification intégrité de l'archive"
else
log "[ERREUR] Critique : l'archive n'a pas été créée !"
STATUT_GLOBAL=1
fi
# ─── ROTATION DES SAUVEGARDES ────────────────────────────────────────────
log "Rotation des sauvegardes (conservation des $NB_SAUVEGARDES_MAX dernières)..."
NB_ARCHIVES=$(ls -1 "${REPERTOIRE_BACKUP}/${PREFIXE}_"*.tar.gz 2>/dev/null | wc -l)
log " Nombre d'archives présentes : $NB_ARCHIVES"
if [ "$NB_ARCHIVES" -gt "$NB_SAUVEGARDES_MAX" ]
then
NB_A_SUPPRIMER=$(( NB_ARCHIVES - NB_SAUVEGARDES_MAX ))
log " Suppression des $NB_A_SUPPRIMER archive(s) les plus anciennes..."
ls -1t "${REPERTOIRE_BACKUP}/${PREFIXE}_"*.tar.gz \
| tail -n "$NB_A_SUPPRIMER" \
| while read -r ANCIENNE_ARCHIVE
do
rm -f "$ANCIENNE_ARCHIVE"
log "[INFO] Supprimé : $(basename $ANCIENNE_ARCHIVE)"
done
else
log " Aucune rotation nécessaire."
fi
# ─── RAPPORT FINAL ────────────────────────────────────────────────────────
NB_ARCHIVES_FINAL=$(ls -1 "${REPERTOIRE_BACKUP}/${PREFIXE}_"*.tar.gz 2>/dev/null | wc -l)
log "========================================================"
if [ $STATUT_GLOBAL -eq 0 ]
then
log "[OK] SAUVEGARDE TERMINÉE AVEC SUCCÈS"
else
log "[ERREUR] SAUVEGARDE TERMINÉE AVEC DES ERREURS — Consultez le log"
fi
log " Archives conservées : $NB_ARCHIVES_FINAL / $NB_SAUVEGARDES_MAX maximum"
log " Espace backup utilisé : $(du -sh $REPERTOIRE_BACKUP | cut -f1)"
log "========================================================"
log ""
exit $STATUT_GLOBAL
D3 — Rendre le Script Exécutable et le Tester
# Rendre exécutable
sudo chmod +x /usr/local/bin/siosarl/sauvegarde.sh
# Tester manuellement (toujours tester avant de planifier !)
sudo /usr/local/bin/siosarl/sauvegarde.sh
# Vérifier le résultat
ls -lh /var/backups/siosarl/
cat /var/log/sauvegarde_siosarl.log
Capturer la liste des archives créées : Capture D1. Capturer le contenu du log : Capture D2.
D4 — Tester la Rotation
Simuler plusieurs sauvegardes pour tester la rotation :
# Relancer le script 3 fois de suite pour créer plusieurs archives
for i in $(seq 1 3)
do
echo "=== Exécution $i ==="
sudo /usr/local/bin/siosarl/sauvegarde.sh
sleep 2 # Attendre 2 secondes pour avoir des horodatages différents
done
# Vérifier que la rotation fonctionne (au-delà de 7 archives)
ls -lh /var/backups/siosarl/
D5 — Planifier avec Cron
Ajouter la ligne suivante :
# Sauvegarde quotidienne du serveur web SimIO SARL à 2h00
0 2 * * * /usr/local/bin/siosarl/sauvegarde.sh >> /var/log/sauvegarde_siosarl.log 2>&1
Capturer la sortie de sudo crontab -l : Capture D3.
Je comprends. Que signifie 30 2 * * 1-5 ? Pourquoi un script lancé par cron doit-il utiliser des chemins absolus ? ______________________
Éléments de réponse
« à 2 h 30, du lundi au vendredi ». cron s'exécute avec un environnement minimal (pas ton répertoire courant ni ton PATH) : un chemin relatif ou une commande non trouvée fait échouer le script silencieusement.
D6 — Vérifier la Planification (Test Immédiat)
Pour vérifier que cron exécute bien le script, on peut temporairement modifier l'heure de planification pour qu'elle se déclenche dans 2 minutes :
# Connaître l'heure actuelle
date
# Modifier le crontab pour un test dans 2 minutes (exemple : si 10h15, mettre 10 17)
# 17 10 * * * /usr/local/bin/siosarl/sauvegarde.sh ...
# Après l'exécution, vérifier le log
cat /var/log/sauvegarde_siosarl.log
# Remettre la planification à 2h00
sudo crontab -e
# Corriger : 0 2 * * * ...
Capturer la dernière entrée du log après exécution automatique : Capture D4.
ANNEXE — FICHE DE DOCUMENTATION LAMP & SAUVEGARDE
(À compléter et verser au portfolio — Preuve pour la fiche de réalisation (E6))
Nom : _________________________ Prénom : _________________________ Date : _________
1. Configuration du Serveur LAMP
Informations Système
| Paramètre | Valeur |
|---|---|
| Distribution Linux | |
Version du noyau (uname -r) |
|
| Adresse IP du serveur | |
Nom d'hôte (hostname) |
Composants LAMP Installés
| Composant | Version | Port | Statut | Démarrage auto |
|---|---|---|---|---|
| Apache | 80/443 | |||
| MariaDB | 3306 | |||
| PHP | N/A |
Base de Données Créée
| Paramètre | Valeur |
|---|---|
| Nom de la base | siosarl_db |
| Utilisateur applicatif | webuser |
| Hôte autorisé | localhost |
| Droits accordés | ALL PRIVILEGES |
2. Configuration SSH
| Paramètre | Valeur |
|---|---|
| Type de clé générée | Ed25519 |
| Emplacement clé privée | ~/.ssh/id_ed25519 |
| Emplacement clé publique | ~/.ssh/id_ed25519.pub |
| Fichier authorized_keys serveur | ~/.ssh/authorized_keys |
| PermitRootLogin | no |
| PasswordAuthentication | no |
3. Configuration du Script de Sauvegarde
| Paramètre | Valeur configurée |
|---|---|
| Chemin du script | /usr/local/bin/siosarl/sauvegarde.sh |
| Répertoires sauvegardés | /var/www/html, /etc/apache2 |
| Répertoire de destination | /var/backups/siosarl |
| Fichier de log | /var/log/sauvegarde_siosarl.log |
| Nombre de sauvegardes conservées | 7 |
| Format du nom d'archive | backup_siosarl_YYYY-MM-DD_HH-MM-SS.tar.gz |
4. Planification Cron
| Paramètre | Valeur |
|---|---|
| Expression cron | 0 2 * * * |
| Signification | Tous les jours à 2h00 |
| Utilisateur | root |
| Redirections | >> /var/log/sauvegarde_siosarl.log 2>&1 |
Coller ici le résultat de sudo crontab -l :
5. Tests de Validation
| Test | Commande utilisée | Résultat | Capture N° |
|---|---|---|---|
| Apache actif | systemctl status apache2 |
Oui / Non | |
| Page web accessible | Navigateur → IP serveur | Oui / Non | |
| PHP fonctionnel | php -v |
Oui / Non | |
| MariaDB actif | systemctl status mariadb |
Oui / Non | |
| Connexion BDD via PHP | http://IP/connexion_bdd.php |
Oui / Non | |
| SSH clé sans MDP | ssh user@IP |
Oui / Non | |
| Script sauvegarde manuel | sudo ./sauvegarde.sh |
Oui / Non | |
| Archive créée | ls /var/backups/siosarl/ |
Oui / Non | |
| Rotation (>7 archives) | Exécution x8 + vérification | Oui / Non | |
| Planification cron | sudo crontab -l |
Oui / Non |