Aller au contenu
Réussir mon BTS SIO

Tape une notion, une commande ou le nom d'une épreuve.

Par exemple

Chapitre 1417 minIntermédiaire

Exercices corrigés de services Linux type E6 et E7 SISR

Par Josselyn C., prof de BTS SIO. Mis à jour le .

À la fin de ce chapitre, tu sauras

  • auditer une configuration de serveur web et la corriger ;
  • traduire une matrice de flux en règles nftables et en comptes MariaDB ;
  • analyser un incident dans les journaux et proposer des contre-mesures ;
  • préparer une réalisation E6 et sa recette.

5 exercices corrigés

Ce chapitre rassemble des cas de synthèse sur les services Linux, au format des épreuves du BTS SIO option SISR : lire et corriger une configuration, traduire une matrice de flux et d'habilitations, analyser des journaux après un incident, préparer une réalisation et sa recette pour l'épreuve E6, mener une tâche de la phase 2. Chaque cas mobilise plusieurs chapitres du cours ; les réponses sont rédigées comme on les attend d'un candidat. À l'écrit E7 SISR, on ne te demande pas de taper des commandes de mémoire, mais de lire une configuration, de repérer ce qui est dangereux et de proposer une correction justifiée : c'est l'esprit des cas 1, 2 et 3.

Cas 1 : auditer un serveur web

Exercice 1 sur 5 La configuration du prestataire Réussi À revoir

Avant la reprise du site de suivi par l'équipe de Sorbier, le prestataire qui l'avait installé fournit cette configuration de srv-web.

nginx
server {
    listen 80;
    server_name suivi.sorbier-logistique.fr;
    root /var/www/suivi;
    autoindex on;
    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.4-fpm.sock;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

Il précise aussi : « Les fichiers du site appartiennent à www-data. Le fichier /var/www/suivi/config.php contient la clé de l'API de srv-gestion. PHP affiche les erreurs pour faciliter le dépannage. Le dépôt Git est dans /var/www/suivi/.git. »

  1. Relève au moins six faiblesses de cette installation et, pour chacune, le risque concret.
  2. Propose le server block corrigé.
Voir la réponseMasquer la réponse de l'exercice 1

1. Les faiblesses.

FaiblesseRisque
Site en HTTP seulementDonnées des clients (numéros de colis, adresses) lisibles et modifiables sur le trajet
root /var/www/suivi (pas de dossier public)config.php et tous les fichiers de l'application sont joignables par une adresse web
autoindex onLa liste des fichiers de chaque dossier s'affiche : un visiteur découvre config.php, les sauvegardes oubliées, le dossier .git
.git dans la racine, aucun refus des fichiers cachésTéléchargement de tout le code source et de son historique, avec les secrets qui y ont été commités
Pas de vérification de l'existence du script PHP (try_files $fastcgi_script_name =404)Risque de faire exécuter comme du PHP un fichier qui n'en est pas
Fichiers propriété de www-dataUne faille de l'application permet de réécrire le site (défiguration, ajout d'une porte dérobée)
Pool PHP www partagé, sous www-dataAucune isolation avec les autres applications du serveur
Erreurs PHP affichéesChemins, requêtes, parfois identifiants exposés aux visiteurs
Clé d'API dans un fichier de la racineFuite de la clé, donc accès aux données de srv-gestion par l'API

2. Le server block corrigé, avec l'application déplacée pour que seul public/ soit servi, la configuration et le dépôt Git hors de la racine, un pool dédié et HTTPS :

nginx
server {
    listen 80;
    listen [::]:80;
    server_name suivi.sorbier-logistique.fr;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;
    server_name suivi.sorbier-logistique.fr;

    ssl_certificate     /etc/letsencrypt/live/suivi.sorbier-logistique.fr/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/suivi.sorbier-logistique.fr/privkey.pem;
    add_header Strict-Transport-Security "max-age=31536000" always;

    root /var/www/suivi/public;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.4-fpm-suivi.sock;
    }
    location ~ /\. {
        deny all;
    }
}

Et hors de Nginx : fichiers propriété de root, lisibles seulement par le compte du pool pour config.php (placé dans /var/www/suivi, au-dessus de public) ; display_errors = Off et journal des erreurs ; dépôt Git déployé ailleurs ou supprimé du serveur ; clé d'API renouvelée, puisqu'elle a pu être lue (chapitres 2, 4 et 6).

Tu avais trouvé ?

Cas 2 : flux, comptes et pare-feu de srv-glpi

Exercice 2 sur 5 De la matrice aux règles Réussi À revoir

La DSI de Sorbier valide ce tableau des accès à srv-glpi (192.168.10.184).

QuiDepuisBesoin
Salariés et agents d'inventaireVLAN 10 192.168.10.64/26GLPI en HTTPS
Techniciens de l'entrepôtVLAN 30 192.168.10.128/27GLPI en HTTPS
Équipe informatiqueVLAN 99 192.168.10.208/28GLPI en HTTPS, SSH
Grafanasrv-journaux 192.168.10.180Lecture des tables glpi_tickets et glpi_itilcategories
Script de sauvegardesrv-glpi lui-mêmeSauvegarde complète de la base glpi
  1. Pour chaque ligne, dis si le flux traverse le pare-feu pfSense.
  2. Écris la chaîne d'entrée nftables de srv-glpi.
  3. Écris les comptes MariaDB et leurs droits pour les deux dernières lignes. Le script de sauvegarde tourne en root sur le serveur.
Voir la réponseMasquer la réponse de l'exercice 2

1. Les VLAN 10, 30 et 99 sont d'autres réseaux que le VLAN 20 de srv-glpi : ces trois flux traversent pfSense, qui doit les autoriser (règles sur les interfaces des VLAN 10, 30 et 99). srv-journaux est dans le même VLAN 20 : son flux ne traverse pas pfSense, seul le pare-feu local le filtre. Le script de sauvegarde ne quitte pas la machine.

2.

text
chain entree {
    type filter hook input priority filter; policy drop;
    ct state established,related accept
    ct state invalid drop
    iif "lo" accept
    icmp type echo-request accept
    icmpv6 type { echo-request, nd-neighbor-solicit, nd-neighbor-advert, nd-router-advert } accept
    ip saddr { 192.168.10.64/26, 192.168.10.128/27, 192.168.10.208/28 } tcp dport { 80, 443 } accept
    ip saddr 192.168.10.208/28 tcp dport 22 accept
    ip saddr 192.168.10.180 tcp dport 3306 accept
    limit rate 10/minute log prefix "nft-refus: "
}

Un ensemble écrit entre accolades directement dans la règle (ensemble anonyme) peut contenir des réseaux : nftables le gère sans déclaration préalable. Un ensemble nommé, comme @admin au chapitre 13, devient utile dès qu'il sert dans plusieurs règles.

3.

sql
CREATE USER 'grafana_lecture'@'192.168.10.180' IDENTIFIED BY '…' REQUIRE SSL;
GRANT SELECT ON glpi.glpi_tickets TO 'grafana_lecture'@'192.168.10.180';
GRANT SELECT ON glpi.glpi_itilcategories TO 'grafana_lecture'@'192.168.10.180';

Le script de sauvegarde n'a pas besoin de compte : lancé en root sur le serveur, il se connecte au compte root@localhost de MariaDB par le socket Unix, sans mot de passe stocké nulle part (sudo mariadb-dump --single-transaction glpi). Côté serveur MariaDB : bind-address = 192.168.10.184 et require_secure_transport = ON pour que Grafana puisse se connecter en TLS (chapitre 5).

Tu avais trouvé ?

Cas 3 : analyser un incident dans les journaux

Exercice 3 sur 5 Une nuit agitée sur le site de suivi Réussi À revoir

Le lundi matin, Wazuh a levé plusieurs alertes pour srv-web1. Tu disposes de ces extraits (adresses d'Internet réservées à la documentation).

text
# Journal d'accès Nginx, transmis à srv-journaux
01:02:11  198.51.100.77  "GET /wp-login.php HTTP/1.1" 404
01:02:11  198.51.100.77  "GET /.env HTTP/1.1" 403
01:02:12  198.51.100.77  "GET /phpmyadmin/ HTTP/1.1" 404
…  (1 240 requêtes de ce type en 6 minutes)
02:15:40  203.0.113.5    "POST /connexion.php HTTP/1.1" 200
…  (3 800 requêtes POST sur /connexion.php entre 02:15 et 02:58, depuis 214 adresses différentes)
03:20:05  203.0.113.61   "GET /suivi.php?colis=<valeur contenant une apostrophe et des mots-clés SQL> HTTP/1.1" 500
# Journal d'erreurs PHP du pool suivi
03:20:05  PHP Fatal error: Uncaught PDOException: SQLSTATE[42000]: Syntax error or access violation …
  1. Identifie les trois activités et nomme-les.
  2. Pour chacune, dis si elle a pu réussir d'après ces traces, et ce qu'il faut vérifier.
  3. Propose des contre-mesures, en distinguant le serveur, l'application et l'architecture.
Voir la réponseMasquer la réponse de l'exercice 3

1. Les trois activités.

  • 01:02 : un balayage automatisé (reconnaissance) : un robot teste en rafale des chemins connus d'applications vulnérables (WordPress, phpMyAdmin, fichiers .env).
  • 02:15–02:58 : une attaque sur les mots de passe du formulaire de connexion, distribuée sur 214 adresses : force brute, ou bourrage d'identifiants (credential stuffing, essai de couples identifiant-mot de passe volés ailleurs).
  • 03:20 : une tentative d'injection SQL : la valeur du paramètre colis contient de la syntaxe SQL, et l'application la recopie dans sa requête, puisque la base renvoie une erreur de syntaxe.

2. Réussite et vérifications.

  • Balayage : réponses 404 et 403, rien de trouvé. Rien à faire, sinon vérifier qu'aucune requête de la série n'a reçu 200.
  • Mots de passe : les réponses 200 ne disent pas si la connexion a réussi (la page de connexion répond 200 même en cas d'échec). Il faut lire les journaux de l'application : y a-t-il eu des connexions réussies pendant la fenêtre, et depuis quelles adresses ? Si oui, réinitialiser les mots de passe concernés et prévenir les clients.
  • Injection : l'erreur 500 et l'exception PDO prouvent que la requête est construite par concaténation : la faille existe, même si cette tentative a échoué. Chercher dans les journaux d'autres requêtes de la même adresse ou du même type ayant reçu 200 (une injection réussie ne produit pas d'erreur), et vérifier dans la base les droits du compte de l'application et les données lisibles par lui.

3. Contre-mesures.

NiveauMesure
ApplicationRequêtes préparées pour toute valeur venue de l'utilisateur (cours PHP et MySQL) ; validation du format du numéro de colis ; limitation du nombre d'essais de connexion par compte, verrouillage temporaire, double authentification pour les comptes sensibles
Serveurdisplay_errors = Off (déjà le cas, l'erreur n'est que dans le journal) ; fail2ban sur les 404 en rafale ; limitation de débit dans Nginx (limit_req) sur /connexion.php ; compte de base de données aux droits minimaux
ArchitectureLe serveur est en DMZ et ne joint srv-gestion que par l'API : vérifier les journaux de l'API sur la période ; un pare-feu applicatif (WAF) devant les répartiteurs filtrerait une partie de ces attaques ; la supervision Wazuh a joué son rôle et doit déclencher une procédure de gestion d'incident (cours Cybersécurité des infrastructures)

Tu avais trouvé ?

Cas 4 : préparer une réalisation pour l'E6 SISR

Exercice 4 sur 5 Un intranet en HTTPS, hautement disponible Réussi À revoir

Pour ta seconde réalisation professionnelle, tu dois répondre au besoin suivant de Sorbier : « Publier pour les salariés un intranet (une application PHP avec sa base), accessible en HTTPS avec le compte Windows de chacun, qui reste disponible si un serveur tombe, et dont les incidents sont détectés. »

  1. Propose l'architecture (serveurs, adresses, services) en restant dans le plan d'adressage de Sorbier.
  2. Rattache chaque élément à une exigence de l'environnement technologique de l'E6 SISR.
  3. Rédige la liste des tests de la recette (au moins huit), avec le résultat attendu.
Voir la réponseMasquer la réponse de l'exercice 4

1. Architecture (dans le VLAN 21 APPLIS 192.168.21.0/24, passerelle 192.168.21.254) :

ÉlémentAdresseRôle
Adresse virtuelle intranet.ad.sorbier.example192.168.21.20Portée par le répartiteur actif (keepalived)
srv-intra1192.168.21.21HAProxy, keepalived (priorité 150), Nginx et PHP-FPM
srv-intra2192.168.21.22HAProxy, keepalived (priorité 130), Nginx et PHP-FPM
Base MariaDB192.168.21.23Base de l'intranet, sauvegardée chaque nuit vers srv-partages

Le VLAN 20 192.168.10.176/28 n'a plus qu'une adresse libre, .187 : .182 à .186 sont pris par srv-collecte, le NAS, srv-glpi, srv-partages et le serveur de déploiement, .188 et .189 par les deux pare-feu en cluster (Pare-feu pfSense). Les quatre adresses vont donc dans le VLAN 21 APPLIS, ouvert pour les applications internes ; le pare-feu filtre les flux des postes vers ce VLAN comme vers le VLAN 20.

Pour limiter le nombre de machines, répartiteur et serveur web sont réunis sur chaque machine : HAProxy écoute en HTTPS sur l'adresse virtuelle et répartit vers les deux Nginx, qui écoutent sur un autre port (8080). L'authentification passe par l'annuaire en LDAPS ; le certificat vient de Sorbier-AC ; les journaux partent vers srv-journaux (rsyslog et agent Wazuh). La base reste un point unique de panne, à signaler comme limite (une réplication MariaDB la supprimerait, cours Haute disponibilité).

2. Rattachement à l'environnement exigé (liste complète) : service d'authentification (annuaire en LDAPS) ; SGBD (MariaDB) ; service rendu à l'utilisateur avec contraintes de sécurité et de haute disponibilité (l'intranet) ; accès sécurisé à un service interne (reverse proxy HTTPS) ; tolérance de panne (deux serveurs, adresse virtuelle VRRP) ; répartition de charge (HAProxy) ; supervision avec remontée d'alertes (Wazuh, et la supervision de l'adresse virtuelle) ; solution de sauvegarde (sauvegarde de la base) ; deux serveurs sur des systèmes différents, dont un libre (Debian ici, Windows Server pour l'annuaire).

3. Recette.

N°TestRésultat attendu
1curl -sI http://intranet.ad.sorbier.example301 vers HTTPS
2Ouvrir l'intranet sur un poste du domaineCadenas, émetteur Sorbier-AC, aucun avertissement
3Connexion avec jlefevreAccès accordé ; refus avec un mauvais mot de passe
4Connexion avec un compte désactivé dans l'annuaireRefusée
5Page de statistiques de HAProxyLes deux serveurs web à l'état UP
6Arrêter Nginx sur srv-intra1Le site répond toujours ; web1 passe DOWN dans les statistiques
7Éteindre srv-intra1L'adresse virtuelle passe sur srv-intra2 (ip -br address) en quelques secondes ; le site répond
8Rallumer srv-intra1L'adresse revient sur lui (préemption), aucune coupure visible
9Capture sur le port 636 pendant une connexionÉchanges TLS, aucun mot de passe lisible
10Cinq échecs de connexion SSH depuis une adresse de testAlerte dans Wazuh, adresse bloquée par fail2ban
11Restaurer la sauvegarde de la nuit dans une base de testBase complète, l'intranet démarre sur la copie

Chaque test est accompagné d'une capture ou d'une sortie de commande dans le dossier : c'est ce qui prouve, pendant l'entretien, que la solution fonctionne.

Tu avais trouvé ?

Cas 5 : une tâche de la phase 2 de l'E6

Exercice 5 sur 5 Un nouveau site en une heure Réussi À revoir

Pendant la phase 2 de l'épreuve E6, la commission te demande : « Le service commercial veut publier, sur srv-web, un site statique de présentation, www.sorbier-logistique.fr, en HTTPS, avec des journaux séparés transmis au serveur central. Le nom public pointe déjà vers l'adresse du pare-feu, qui redirige les ports 80 et 443 vers srv-web. » Décris les étapes dans l'ordre, avec les commandes, puis les vérifications que tu montres à la commission.

Voir la réponseMasquer la réponse de l'exercice 5

Étapes.

  1. Créer la racine et une page : sudo mkdir -p /var/www/www/public puis une page index.html (fichiers propriété de root).
  2. Écrire /etc/nginx/sites-available/www : un server block sur le port 80 avec server_name www.sorbier-logistique.fr;, root /var/www/www/public;, des journaux www.access.log et www.error.log, et le refus des fichiers cachés (chapitre 2).
  3. Activer : sudo ln -s /etc/nginx/sites-available/www /etc/nginx/sites-enabled/, sudo nginx -t, sudo systemctl reload nginx.
  4. Obtenir le certificat et passer en HTTPS : sudo certbot --nginx -d www.sorbier-logistique.fr, qui ajoute HTTPS et la redirection ; ajouter ensuite HSTS avec une durée courte pendant la recette.
  5. Vérifier que les nouveaux journaux sont transmis : avec le motif /var/log/nginx/*.access.log de la configuration rsyslog (chapitre 12), rien à modifier ; ajouter le fichier au bloc localfile de l'agent Wazuh s'il est déclaré fichier par fichier, puis redémarrer l'agent.
  6. Mettre à jour la documentation : fichier de site, certificat, date d'expiration supervisée.

Vérifications montrées.

  • curl -sI http://www.sorbier-logistique.fr : 301 vers HTTPS.
  • curl -sI https://www.sorbier-logistique.fr : 200, en-tête Strict-Transport-Security.
  • openssl s_client -connect www.sorbier-logistique.fr:443 -servername www.sorbier-logistique.fr </dev/null | openssl x509 -noout -subject -issuer -dates : certificat Let's Encrypt pour ce nom, dates valides.
  • sudo certbot renew --dry-run : renouvellement simulé réussi.
  • curl -sI https://suivi.sorbier-logistique.fr : le site existant fonctionne toujours (on n'a rien cassé).
  • Une requête sur le nouveau site, puis sa ligne retrouvée sur srv-journaux.

Ce que la commission observe aussi : nginx -t avant chaque rechargement, une sauvegarde de la configuration avant modification, et la capacité à expliquer chaque directive.

Tu avais trouvé ?

Chapitre terminé !

Fais les 5 exercices avant de passer à la suite : c'est en t'entraînant que tout se fixe.

chapitres
–
de série
–
du cours
–
Chapitre suivant : Aide-mémoire : fichiers, commandes et ports des services LinuxRevoir le sommaire du cours