Cours Ubuntu 26.04 / Construire un serveur et préparer sa transmission à l’exploitation

Un serveur Ubuntu est prêt à être transmis lorsqu’un autre administrateur peut y accéder, le contrôler et préparer sa récupération à partir d’un dossier fiable. Ce projet final associe une VM dédiée, l’administration SSH et un site Nginx sur le réseau local ; vous consignez les résultats réellement obtenus pour les accès, le redémarrage et la restauration.

Définir un périmètre et des preuves de réussite

Préparez une VM Ubuntu 26.04 LTS, sa console, un plan d’adresses, un client d’administration autorisé et un emplacement de sauvegarde indépendant. Le projet minimal fournit SSH et un site HTTP statique de laboratoire sur un réseau privé. N’y placez pas d’identifiants ou de données sensibles transmis en clair.

Ajoutez HTTPS public et son suivi de renouvellement uniquement avec un domaine contrôlé et un trajet de validation prévu. Samba et Docker restent des choix liés à un besoin réel. Installer tous les services des cours ne constitue pas un critère de réussite.

Objet Preuve attendue
Administration Nouvelle session SSH par clé depuis le client autorisé et refus constaté depuis le trajet exclu.
Site web Contenu attendu pour le bon nom, réponse prévue pour un nom inconnu et accès réseau limité.
Redémarrage Adresse, montages, services et accès revérifiés après un redémarrage planifié.
Sauvegarde Restauration séparée avec vérification du contenu, des droits et des fonctions utiles.
Transmission Responsables, politiques, commandes validées, preuves et tâches en attente documentés.

Construire en suivant les dépendances

  1. Depuis la console, relevez version, disques, heure et adresses, puis terminez les vérifications initiales et mises à jour, avec redémarrage lorsque nécessaire.
  2. Identifiez le gestionnaire réseau et appliquez les réglages d’adresse avec sauvegarde, console et essai contrôlé.
  3. Vérifiez une nouvelle connexion SSH par clé avant de resserrer l’authentification. Contrôlez le véritable port et son unité de service ou socket.
  4. Installez seulement les services retenus ; sauvegardez, validez et relisez leurs configurations. Limitez les sources et ports réellement nécessaires.
  5. Préparez la sauvegarde indépendante et sa restauration, les alertes et un état de référence avant l’essai de redémarrage.

En cas d’échec à une étape, examinez son changement et ses journaux avant d’en ajouter un autre. Changer simultanément le port, le mode d’authentification et le pare-feu rend difficile l’attribution d’une perte d’accès. Ouvrez réellement la console de secours au lieu de supposer qu’elle sera disponible le jour d’une panne.

Distinguer le site local du site accessible sur le LAN

Le laboratoire Nginx écoute sur 127.0.0.1:8080 ; la publication Docker utilise 8081. Depuis le serveur lui-même, vérifiez d’abord la page locale :

curl --noproxy '*' --fail --show-error --resolve alpha.example.test:8080:127.0.0.1 http://alpha.example.test:8080/

Le résultat attendu est alpha-site. Faire résoudre ce nom vers l’adresse LAN ne transforme pas une écoute sur la boucle locale en service LAN. --resolve ne vaut que pour cette commande curl, sans modifier le DNS ou le fichier hosts.

Pour le LAN, utilisez le réseau privé des cours avec serveur 192.168.56.20/24 et client Linux autorisé 192.168.56.10. Vérifiez que 8082 est libre, que la racine /srv/ubuntu-course-alpha contient la page prévue et que le nom de site ci-dessous est nouveau. Adaptez tous les paramètres si votre plan diffère.

Ce bloc complet crée deux serveurs Nginx sur 192.168.56.20:8082 : le site nommé et un repli explicite qui renvoie 404. Il garde les sites locaux précédents :

(
set -euo pipefail
site=/etc/nginx/sites-available/ubuntu-course-lan
enabled=/etc/nginx/sites-enabled/ubuntu-course-lan
sudo test -f /srv/ubuntu-course-alpha/index.html
if ! ip -4 -o address show | grep -Fq ' 192.168.56.20/24 '; then
    printf 'Configure the verified server lab address first.\n' >&2; exit 1
fi
for path in "$site" "$enabled"; do
    if sudo test -e "$path" || sudo test -L "$path"; then
        printf 'Existing lab site: inspect before changing.\n' >&2; exit 1
    fi
done
backup_dir=$(sudo mktemp -d /root/nginx-before-lan.XXXXXX)
sudo cp -a /etc/nginx "$backup_dir/"
sudo sh -c 'set -C; cat > "$1"' sh "$site" <<'EOF'
server {
    listen 192.168.56.20:8082 default_server;
    server_name _;
    return 404;
}
server {
    listen 192.168.56.20:8082;
    server_name course-lab.example.test;
    root /srv/ubuntu-course-alpha;
    index index.html;
    location / {
        try_files $uri $uri/ =404;
    }
}
EOF
sudo ln -sT "$site" "$enabled"
sudo nginx -t
sudo systemctl reload nginx
sudo ss -lntp
printf 'LAN site backup: %s\n' "$backup_dir"
)

La sauvegarde est privée et les collisions arrêtent le script. Si nginx -t échoue, ne rechargez pas en ignorant l’erreur ; examinez les fichiers et retirez uniquement le nouveau lien si vous annulez cette activation. Un reload réussi doit être suivi d’un contrôle de réponse.

La sélection par Host et le serveur par défaut suivent les règles de traitement des requêtes Nginx. Ici le repli vient de default_server sur cette adresse et ce port ; le caractère _ n’a pas de pouvoir spécial. Cette sélection de nom ne remplace ni l’authentification ni le pare-feu.

Contrôler le bon client et un trajet exclu

Avec la politique d’entrée par défaut restrictive et l’accès SSH préservé du cours UFW, ajoutez cette autorisation seulement si les adresses sont bien celles du laboratoire :

sudo ufw allow from 192.168.56.10 to 192.168.56.20 port 8082 proto tcp
sudo ufw status numbered

Inspectez toutes les règles : une autorisation générale antérieure sur 8082 annule l’intérêt de cette restriction. Vérifiez aussi l’hyperviseur et le pare-feu externe, et ne transférez pas ce port de laboratoire vers Internet. Le guide de pare-feu Ubuntu accompagne l’examen des règles, sans remplacer les essais de connexion.

Depuis le client .10, faites ces deux requêtes nouvelles :

curl --noproxy '*' --fail --show-error --connect-timeout 5 --max-time 10 --resolve course-lab.example.test:8082:192.168.56.20 http://course-lab.example.test:8082/
curl --noproxy '*' -i --connect-timeout 5 --max-time 10 --resolve unknown.example.test:8082:192.168.56.20 http://unknown.example.test:8082/

Attendez alpha-site pour la première et HTTP 404 pour la seconde. La requête 404 n’utilise pas --fail, afin de lire sa réponse ; un code de sortie curl nul ne signifie pas toujours HTTP 200.

Depuis un client exclu, par exemple l’hôte .1 si son adresse réelle est bien .1 et s’il est exclu de la politique, la connexion nouvelle vers 8082 ne doit pas atteindre le site. Une temporisation seule ne localise pas le filtre : comparez le trajet, la source et les règles. Ne confondez pas le refus d’un nom sur un client autorisé avec le blocage réseau d’un autre client.

Créer et éprouver un contrôle HTTP simple

Enregistrez le script complet suivant dans ~/check-web-lab.sh. Il nécessite Bash, curl, grep et les outils de base. Il attend HTTP 200 et la présence littérale d’un texte ; le troisième argument optionnel fournit une correspondance de résolution pour curl, sans modifier hosts :

set -eu
if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then
    printf 'Usage: bash check-web-lab.sh URL EXPECTED_TEXT [HOST:PORT:ADDRESS]\n' >&2
    exit 2
fi
url=$1
expected=$2
case "$url" in
    http://*|https://*) ;;
    *) printf 'Use an HTTP or HTTPS URL.\n' >&2; exit 2 ;;
esac
if [ -z "$expected" ]; then
    printf 'Expected text must not be empty.\n' >&2
    exit 2
fi
curl_args=(--noproxy '*' --fail --silent --show-error --connect-timeout 5 --max-time 10)
if [ "$#" -eq 3 ]; then
    curl_args+=(--resolve "$3")
fi
body_file=$(mktemp)
trap 'rm -f -- "$body_file"' EXIT
if ! status=$(curl "${curl_args[@]}" "$url" -o "$body_file" --write-out '%{http_code}'); then
    printf 'FAIL: request or TLS verification failed\n' >&2
    exit 1
fi
if [ "$status" != 200 ]; then
    printf 'FAIL: expected HTTP 200, received %s\n' "$status" >&2
    exit 1
fi
if ! grep -Fq -- "$expected" "$body_file"; then
    printf 'FAIL: expected text missing\n' >&2
    exit 1
fi
printf 'PASS: %s %s\n' "$(date -u +%FT%TZ)" "$url"

Depuis le serveur pour le site local, puis depuis .10 pour le site LAN, utilisez respectivement :

bash "$HOME/check-web-lab.sh" http://alpha.example.test:8080/ alpha-site alpha.example.test:8080:127.0.0.1
bash "$HOME/check-web-lab.sh" http://course-lab.example.test:8082/ alpha-site course-lab.example.test:8082:192.168.56.20

Exécutez chaque ligne dans le contexte indiqué, pas les deux indistinctement depuis n’importe quelle machine. Si vous omettez le troisième argument, le nom doit déjà être correctement résolu par le client. Les options --resolve, --noproxy et --write-out sont définies dans le manuel curl. Le script ne suit pas les redirections et conserve la vérification TLS normale pour une URL HTTPS.

Le succès affiche PASS et renvoie 0 ; une erreur de requête, TLS, code HTTP ou contenu renvoie 1 ; un nombre d’arguments incorrect, un schéma refusé ou un texte attendu vide renvoie 2. Passez volontairement une chaîne absente pour vérifier le chemin d’échec. Une sous-chaîne présente ne prouve pas l’intégrité de toute la page, et ce contrôle ne couvre ni une connexion utilisateur ni une écriture en base.

N’incluez pas de secret dans l’URL, car elle apparaît dans les résultats. Un contrôle périodique doit transmettre ses échecs à une personne ou un système d’alerte et surveiller sa propre exécution. Le simple stockage d’un message PASS ancien ne constitue pas une surveillance active.

Consigner les essais de redémarrage et de restauration

Planifiez le redémarrage, conservez l’état initial et assurez-vous de la console. Après retour, revérifiez adresse, route, montages, port SSH et site web depuis les véritables clients admis et exclus. Réutiliser une connexion déjà ouverte ne prouve pas que de nouvelles sessions sont possibles.

Restaurez la sauvegarde dans un emplacement vide ou une machine séparée et comparez contenu, propriétaires, permissions et comportement applicatif. Ne remplacez pas les fichiers actifs pour « tester » une archive. Les systèmes externes et clés de déchiffrement nécessaires font partie du plan.

Une ligne de preuve doit contenir date, contexte du client, commande ou scénario, résultat attendu, résultat obtenu et emplacement de la trace. Si une opération n’a pas été réalisée, inscrivez-la comme en attente avec son responsable. Ne recopiez pas les résultats attendus du cours comme s’il s’agissait de mesures.

Si vous retirez le laboratoire LAN, comparez les objets au journal de changement, retirez seulement son lien de site et sa règle UFW créés ici, puis validez et relisez Nginx. Préservez les autres services. Les sources et sauvegardes peuvent être conservées jusqu’à la revue finale.

Rédiger une transmission fondée sur les valeurs observées

Utilisez cette trame pour un fichier d’exploitation. Remplacez les crochets par les valeurs vérifiées et indiquez la référence d’un coffre approuvé au lieu de recopier des secrets :

Système : [nom, fonction, responsable]
Plate-forme : [version Ubuntu, noyau, hôte VM, accès console]
Réseau : [interface, moteur, adresse, passerelle, DNS]
Administration : [clients admis, écoute SSH réelle, référence des clés]
Services : [versions, fichiers, commandes de validation et de relecture]
Exposition : [écoutes, règles UFW, pare-feu externe, ports Docker]
TLS : [noms, renouvellement, contrôle des échecs et de l’expiration]
Sauvegarde : [périmètre, support indépendant, rétention, référence des clés]
Restauration : [date, destination, contenu, droits et résultats applicatifs]
Acceptation : [scénario, client, résultat attendu/obtenu, trace]
Retour : [limite du changement, état conservé, procédure de reprise]
En attente : [essai absent, problème, responsable, échéance]

Faites relire le dossier par la personne qui reprend le serveur : elle doit pouvoir préparer un accès, interpréter un échec et retrouver le matériel de restauration sans dépendre de votre mémoire. Précisez les destinataires des alertes et les responsabilités pour les mises à jour, certificats, sauvegardes et tâches restantes. Une transmission utile contient aussi les limites connues, pas seulement la liste des réussites.