Créer et durcir sa machine virtuelle
Ce que vous allez construire
Ce que vous allez construire : une VM joignable uniquement en SSH par clé, derrière un pare-feu qui refuse tout le reste.
PDF vectorielÉtape 0 : préparer le poste hôte (15 min)
-
Vérifiez que la virtualisation matérielle est active :
- Linux
- Windows
egrep -c '(vmx|svm)' /proc/cpuinfo # doit afficher un nombre > 0Gestionnaire des tâches → Performance → CPU → « Virtualisation : activée ». Sinon, activez VT-x/AMD-V dans le BIOS/UEFI.
-
Installez VirtualBox ≥ 7.0 (version exacte : voir le guide d'installation de la semaine 1).
-
Récupérez l'ISO Ubuntu Server 24.04 LTS (amd64) (~2,7 Go) : depuis releases.ubuntu.com/24.04, téléchargez le fichier
ubuntu-24.04.x-live-server-amd64.iso(« Server install image »), ou prenez-le sur le miroir local de l'école. Tout le monde doit utiliser la même version : les corrections et les pannes injectées sont préparées dessus.
Étape 1 : créer la VM (15 min)
Dans VirtualBox, créez une machine avec ces paramètres :
| Paramètre | Valeur | Pourquoi |
|---|---|---|
| Nom | listify-s1 | Convention du cours : rôle + semestre |
| Type / Version | Linux / Ubuntu (64-bit) | Active les bons pilotes paravirtualisés |
| RAM | 2048 Mo | Assez pour Nginx + Gunicorn + PostgreSQL (ch. 1, §1.2) |
| CPU | 2 vCPU | Permet de raisonner le dimensionnement des workers (ch. 4) |
| Disque | VDI, 20 Go, alloué dynamiquement | « Dynamique » : le fichier ne grossit qu'à l'usage réel |
| Réseau, carte 1 | NAT | Sortie Internet immédiate ; entrée par redirections (ch. 3, §4) |
Configurez tout de suite la redirection de port SSH : Configuration → Réseau → Carte 1 → Avancé → Redirection de ports, puis cliquez sur l'icône « + » et renseignez exactement cette règle (les six colonnes) :
| Nom | Protocole | IP hôte | Port hôte | IP invité | Port invité |
|---|---|---|---|---|---|
| ssh | TCP | 127.0.0.1 | 2222 | (laisser vide) | 22 |
L'IP hôte 127.0.0.1 restreint la redirection à votre propre poste : personne d'autre sur le réseau de la salle ne pourra tenter de se connecter à votre VM.
Étape 2 : installer Ubuntu Server 24.04 (30 min)
Démarrez la VM sur l'ISO. Au menu GRUB, choisissez « Try or Install Ubuntu Server ». L'installateur Subiquity se déroule en une série d'écrans (naviguez au clavier : flèches, Tab, Entrée). Points de décision, tout le reste par défaut :
- Langue / clavier : à votre convenance (le serveur, lui, parlera anglais dans ses logs : c'est très bien).
- Type d'installation : choisissez « Ubuntu Server » (l'option standard, pas « minimized » qui retire des outils utiles au TP).
- Réseau : laissez la configuration automatique (DHCP). L'interface obtient
10.0.2.15/24sur le réseau NAT de VirtualBox (ch. 3, §4). - Proxy et miroir : laissez vides / par défaut.
- Stockage : « Use an entire disk », puis confirmez le résumé du partitionnement (l'installateur écrit sur le disque : lisez l'avertissement, il est normal). Le partitionnement fin est un vrai sujet d'admin, hors périmètre du cours.
- Profile setup : nom complet libre ; nom du serveur
listify-s1; identifiantdeploy; mot de passe robuste (il servira poursudo). - Ubuntu Pro : « Skip for now ».
- SSH Setup : cochez « Install OpenSSH server ». C'est l'étape la plus importante de l'installation : sans elle, pas de connexion à distance. Ne cochez pas « Import SSH identity » (nous déposerons la clé nous-mêmes à l'étape 4, pour bien comprendre le mécanisme).
- Featured server snaps : n'en sélectionnez aucun. Notre serveur n'installe que ce dont il a besoin.
L'installation se lance, puis propose « Reboot Now ». Au redémarrage, retirez l'ISO si VirtualBox ne l'a pas fait (Périphériques → Lecteurs optiques → Retirer le disque), et vous obtenez une console de login en mode texte.
Connectez-vous en deploy dans la console VirtualBox une seule fois pour vérifier, puis n'y revenez qu'en secours : à partir de maintenant, tout se fait en SSH, comme sur un vrai serveur.
Point de contrôle n° 1 : votre première session
Dans la console VM, vérifiez et notez dans le runbook :
ip -brief addr # l'IP de la VM : 10.0.2.15/24 (réseau NAT VirtualBox)
sudo whoami # doit répondre "root" (deploy a bien sudo, sans mot de passe root)
systemctl status ssh # sshd doit être "active (running)"
Si systemctl status ssh répond « Unit ssh.service could not be found » : vous avez oublié de cocher « Install OpenSSH server » à l'étape 8. Réparez sans réinstaller : sudo apt update && sudo apt install -y openssh-server.
Étape 3 : première connexion SSH et création du dépôt (20 min)
Depuis un terminal du poste hôte :
Trois choses se passent, à comprendre et consigner :
- La question
The authenticity of host ... can't be established+ empreinte : c'est la vérification de l'hôte (ch. 5, §1.3). Répondezyes; l'empreinte part dans~/.ssh/known_hosts. - Le mot de passe demandé est celui de
deploysur la VM (authentification par mot de passe, que nous allons précisément supprimer). - Vous êtes sur la VM : le prompt affiche
deploy@listify-s1. Le trafic a suivi : terminal → 127.0.0.1:2222 → NAT VirtualBox → 10.0.2.15:22.
Créez maintenant le dépôt de travail du semestre sur votre poste hôte :
mkdir listify && cd listify && git init
# Récupérez le code de l'application depuis la page "Application fil rouge"
# (archive fournie sur le Moodle du cours), puis :
printf '# Runbook TP1 : création et durcissement de la VM\n\n' > RUNBOOK.md
git add -A && git commit -m "Code initial de Listify + runbook TP1"
Étape 4 : authentification par clés (30 min)
4.1 Générer votre paire de clés (poste hôte)
Si vous n'avez pas déjà une clé ed25519 :
# Emplacement : défaut (~/.ssh/id_ed25519)
# Passphrase : OBLIGATOIRE dans ce cours (protège la clé privée sur disque)
Observez ce qui a été créé :
ls -l ~/.ssh/id_ed25519*
# -rw------- id_ed25519 : clé PRIVÉE, permissions 600, ne quitte jamais ce poste
# -rw-r--r-- id_ed25519.pub : clé PUBLIQUE, celle qu'on distribue
4.2 Déposer la clé publique sur la VM
# (dernier usage du mot de passe !)
# pas le mot de passe du serveur
Sur la VM, regardez ce que ssh-copy-id a réellement fait : votre clé publique est une ligne dans ~/.ssh/authorized_keys, et les permissions sont strictes (700 sur ~/.ssh, 600 sur le fichier), sans quoi sshd refuserait de s'en servir.
4.3 Se simplifier la vie : ~/.ssh/config (poste hôte)
Host listify-s1
HostName 127.0.0.1
Port 2222
User deploy
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
Désormais : ssh listify-s1. Ce fichier est aussi une documentation de votre parc : Ansible saura le lire au bloc 3.
Les deux dernières lignes règlent définitivement le problème « Too many authentication failures » : IdentityFile désigne la clé à utiliser et IdentitiesOnly yes interdit à ssh de proposer les autres clés de votre agent. Sans elles, si vous avez beaucoup de clés, la bonne peut être offerte trop tard (après les 6 essais autorisés) et le serveur coupe. C'est aussi une bonne pratique de sécurité : ne présenter à chaque serveur que la clé qui le concerne.
Point de contrôle n° 2
ssh listify-s1vous connecte en demandant la passphrase de la clé (ou rien si un agent SSH tourne), pas le mot de passe deploy.- Dans
journalctl -u ssh -n 20sur la VM, la ligne de votre connexion indiqueAccepted publickey for deploy.
Étape 5 : durcissement de sshd (30 min)
Sur la VM, créez le fichier de durcissement (on ne modifie pas sshd_config directement : les fichiers de sshd_config.d/ sont inclus et survivent mieux aux mises à jour du paquet). Le préfixe 00- du nom est important, on explique pourquoi juste après :
sudo tee /etc/ssh/sshd_config.d/00-hardening.conf > /dev/null <<'EOF'
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
AllowUsers deploy
EOF
sudo sshd -t # test de syntaxe : AUCUNE sortie = OK
sudo systemctl reload ssh
Vérifiez ensuite depuis le second terminal du poste hôte :
ssh listify-s1 # doit fonctionner (clé)
ssh -p 2222 -o PubkeyAuthentication=no \
# doit échouer : "Permission denied (publickey)"
# Si vous obtenez au contraire l'invite "password:", c'est le piège ci-dessus :
# revérifiez le nom 00-hardening.conf et la sortie de sshd -T.
ssh -p 2222 -o PubkeyAuthentication=no \
# doit échouer : "Permission denied" (c'est PermitRootLogin no qui bloque)
# Astuce : sans ces deux options et si vous avez plusieurs clés dans l'agent,
# vous verriez "Too many authentication failures" -- root est refusé quand même,
# mais le message est moins parlant. Les options forcent un motif clair.
Ces tests négatifs vont dans le runbook : prouver qu'une porte est fermée fait partie du travail, pas seulement prouver que la vôtre est ouverte.
Étape 6 : pare-feu ufw (20 min)
ufw (Uncomplicated Firewall) est développé par Canonical pour Ubuntu : il est déjà installé, simplement inactif. Une commande de moins que sur d'autres distributions.
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp # AVANT enable : ne pas s'enfermer dehors (ch. 3, §5.1)
sudo ufw enable
sudo ufw status verbose
La sortie attendue de status verbose : politique deny (incoming), allow (outgoing), et l'unique règle 22/tcp ALLOW IN Anywhere. Aux TP 2 et 3, nous ouvrirons 80 et 443 au moment où nous en aurons besoin, jamais avant.
Étape 7 : hygiène de base du système (20 min)
# Tout mettre à jour (ch. 5 : la majorité des compromissions exploitent du déjà-corrigé)
sudo apt update && sudo apt upgrade -y
# Correctifs de sécurité automatiques : préinstallés et actifs sur Ubuntu Server,
# on se contente de VÉRIFIER (le paquet est déjà là : apt le confirmera)
sudo apt install -y unattended-upgrades
systemctl status unattended-upgrades # doit être active
# Fuseau horaire cohérent (des logs datés juste, ça compte au TP 4)
sudo timedatectl set-timezone Europe/Paris
timedatectl # vérifier que NTP est actif ("synchronized: yes")
Enfin, prenez votre premier snapshot : VM éteinte (sudo poweroff), VirtualBox → Instantanés → « Prendre » → nom tp1-durci. C'est votre point de restauration pour tout le bloc.
Point de contrôle final : la grille d'auto-évaluation
À cocher (et faire vérifier par l'enseignant en fin de séance) :
-
ssh listify-s1fonctionne par clé, avec passphrase - La connexion par mot de passe est refusée (test négatif consigné)
- La connexion root est refusée
-
sudo ufw status: deny incoming + 22/tcp uniquement -
sudo ss -tlnpne montre que sshd en écoute non-locale, et vous savez justifier chaque ligne -
unattended-upgradesactif, NTP synchronisé - Snapshot
tp1-durcipris -
RUNBOOK.mdcommitté : toutes les commandes, les deux tests négatifs, l'explication de la redirection NAT 2222→22
Pour aller plus loin (bonus)
- fail2ban : installez-le, provoquez 5 échecs de connexion et observez le bannissement (
sudo fail2ban-client status sshd). Pourquoi est-il moins crucial maintenant quePasswordAuthentication noest posé ? - Agent SSH : configurez
ssh-agent(ou celui de votre bureau) pour ne taper la passphrase qu'une fois par session. Quel nouveau risque introduit un agent avec forwarding activé ? (Réponse au ch. 5 du cours de S2 sur les rebonds.) - Bannière légale : ajoutez un avertissement pré-connexion avec la directive
Bannerde sshd. Dans quel cadre juridique une bannière a-t-elle un intérêt réel ?
Questions de compréhension (à préparer pour le TD)
- Expliquez le trajet complet d'un paquet lors de
ssh listify-s1, en nommant chaque traduction d'adresse et de port. - Pourquoi
PasswordAuthentication norend-il fail2ban largement redondant pour SSH ? Quel service futur (TP 3) remettra fail2ban dans la discussion ? - Un camarade a perdu la passphrase de sa clé. Peut-il la récupérer ? Que doit-il faire, étape par étape, pour retrouver l'accès à sa VM sans la réinstaller ?
ufw default deny incoming: pourquoi cette politique n'empêche-t-elle pasaptde fonctionner, alors que les réponses des miroirs Ubuntu sont bien des paquets entrants ? (Indice : pare-feu à états.)