Sécuriser le serveur dans la première heure

Du compte `debian` livré par OVH à ton propre compte admin avec une clé et un mot de passe sudo, SSH sur son propre port sans mot de passe ni root, un pare-feu, le bannissement du brute force, et des mises à jour de sécurité qui s'installent seules. Chaque verrou est testé avant de fermer l'ancienne porte.

intermédiaire~30 min de manipulation
#ssh#ufw#fail2ban#unattended-upgrades#debian#ovh#security

Pas encore validée de bout en bout — sois le premier.Signaler un problème

Brouillon — pas encore exécuté de bout en bout. Cette page est écrite mais son auteur ne l'a pas encore déroulée sur une vraie machine. Des commandes peuvent être fausses : lis avant de lancer, et dis-nous ce qui casse.

En un coup d'œilUne seule entrée, testée avant de fermer l'ancienne
Ton VPS
ssh vps22, refusedkey → session
Ton portablessh vps
Les robots d'internetroot / passwords on 22
Pare-feu/tcp only
sshdkeys only · no root
Ton compte · sudo

Seule ta clé atteint sshd, sur le port ${SSH_PORT}, à travers le pare-feu, et ouvre une session en ${USERNAME}. Les robots sur le port 22 trouvent porte close ; la console KVM reste le chemin du retour.

Le VPS répond sur le port 22 à tout internet, en debian, avec un sudo sans mot de passe. Cette page te fait passer sur ton propre compte, met SSH sur son propre port avec des clés uniquement, allume un pare-feu, bannit le brute force et fait s'installer seules les mises à jour de sécurité. L'ordre compte : chaque nouvelle porte est testée depuis un second terminal avant de fermer l'ancienne.

Avant de commencer

Vérifie que la connexion livrée marche et que debian a sudo sans mot de passe, puis connecte-toi en debian dans un premier terminal et restes-y : un second terminal sur ton portable teste chaque changement depuis l'extérieur.

Deux terminaux, et le badge de chaque bloc dit lequel :

  • Terminal A, badge serveur · debian : ta première session, ouverte maintenant. C'est ta bouée : ne la ferme pas avant que la page te le dise. Toutes les commandes sudo jusqu'à la bascule s'y tapent.
  • Terminal B, badge Mac : un terminal sur ton portable, pour les tests depuis l'extérieur.

ne prend la main qu'une fois la nouvelle porte testée (une troisième session, ssh vps). La clé du serveur est celle créée à la page 2, ~/.ssh/id_ed25519_vps.

Vérification
$ssh -i ~/.ssh/id_ed25519_vps -o IdentitiesOnly=yes debian@ sudo -n true && echo OK
Retour attendu
OK

Tout mettre à jour

Mets à jour, puis redémarre si Debian a laissé le fichier témoin qui dit qu'une mise à jour l'exige (un nouveau noyau, en général), et reconnecte-toi en debian :

Serveur·debian
Commande sensible — redémarre ou éteint la machine. Vérifie avant d'exécuter.
$sudo apt update && sudo apt full-upgrade -y
$sudo apt install -y vim
$[ -f /var/run/reboot-required ] && sudo reboot

Nom et horloge

Donne son nom au serveur, empêche cloud-init de remettre celui d'OVH, et règle le fuseau horaire. timedatectl doit ensuite afficher ton fuseau et System clock synchronized: yes.

Serveur·debian
$sudo hostnamectl set-hostname
$printf 'preserve_hostname: true\nmanage_etc_hosts: false\n' | sudo tee /etc/cloud/cloud.cfg.d/99-hostname.cfg
$sudo sed -i '/^127\.0\.1\.1[[:space:]]/d' /etc/hosts
$echo "127.0.1.1 " | sudo tee -a /etc/hosts
$sudo timedatectl set-timezone
$timedatectl

Ton propre utilisateur

Crée , dans le terminal A. adduser demande le mot de passe deux fois : tape celui rangé dans ton gestionnaire de mots de passe. Colle cette commande seule :

Serveur·debiante posera une question
$sudo adduser --gecos ""

Puis mets-le dans sudo et sshusers, et écris ta clé publique (la valeur du panneau, pas une copie du fichier de debian) dans son authorized_keys :

Serveur·debian
$sudo groupadd -f sshusers
$sudo usermod -aG sudo,sshusers
$sudo install -d -m 700 -o -g /home//.ssh
$echo '' | sudo tee /home//.ssh/authorized_keys >/dev/null
$sudo chown : /home//.ssh/authorized_keys
$sudo chmod 600 /home//.ssh/authorized_keys

Vérifie la clé avant d'aller plus loin : le fichier doit contenir une clé Ed25519 valide.

Vérification
$sudo ssh-keygen -lf /home//.ssh/authorized_keys | grep -o '(ED25519)'
Retour attendu
(ED25519)

Depuis le terminal B (Mac), connecte-toi avec le nouvel utilisateur par la clé seulement (encore sur le port 22) et lis ses groupes. Les options interdisent le mot de passe : si ça passe, la clé marche.

Vérification
$ssh -i ~/.ssh/id_ed25519_vps -o IdentitiesOnly=yes -o PasswordAuthentication=no -o BatchMode=yes @ 'id -nG | grep -qw sudo && id -nG | grep -qw sshusers && echo groups OK'
Retour attendu
groups OK

Durcir SSH

Écris le fichier complémentaire : copie la commande et colle-la dans le terminal A.

Serveur·debianécrit un fichier/etc/ssh/sshd_config.d/00-hardening.conf
Port
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
AllowGroups sshusers

Teste la syntaxe, puis lis les valeurs effectives. sshd -t n'affiche rien quand la syntaxe est bonne ; la seconde commande doit afficher une seule ligne port, avec , no pour les trois réglages suivants, et allowgroups sshusers.

Serveur·debian
$sudo sshd -t
$sudo sshd -T | grep -Ei '^(port|permitrootlogin|passwordauthentication|kbdinteractiveauthentication|allowgroups) '

Pare-feu et bascule

Installe ufw, refuse tout en entrée, et ouvre le nouveau port et le 22 pour l'instant. ufw enable prévient qu'il peut perturber les connexions SSH ; réponds y. Le 22 reste ouvert pour que la session dans laquelle tu tapes survive, et pour qu'un retour arrière (supprimer le fichier complémentaire, redémarrer) te ramène sur un port que le pare-feu accepte.

Serveur·debian
Commande sensible — peut couper ton propre accès (pare-feu). Vérifie avant d'exécuter.
$sudo apt install -y ufw
$sudo ufw default deny incoming && sudo ufw default allow outgoing
$sudo ufw allow /tcp && sudo ufw allow 22/tcp
$sudo ufw enable

Avant le redémarrage, donne à ton portable le raccourci vps, avec la clé du serveur, dans le terminal B. Si ~/.ssh/config contient déjà un bloc Host vps, n'en ajoute pas un second : modifie-le avec ${EDITOR} ~/.ssh/config pour qu'il ait les mêmes lignes (ssh prend la première correspondance).

Mac
$touch ~/.ssh/config && chmod 600 ~/.ssh/config
$grep -q '^Host vps$' ~/.ssh/config || printf '\nHost vps\n HostName \n Port \n User \n IdentityFile ~/.ssh/id_ed25519_vps\n IdentitiesOnly yes\n AddKeysToAgent yes\n UseKeychain yes\n' >> ~/.ssh/config
Serveur·debian
$sudo systemctl restart ssh

Dans le terminal B, teste la nouvelle porte avec le raccourci. ssh redemande de confirmer la clé d'hôte : c'est la même clé, rangée sous un nouveau nom ([IP]:port), donc réponds yes.

Vérification
$ssh -o BatchMode=yes vps echo connected
Retour attendu
connected
Si la nouvelle connexion échoue

Ton premier terminal est toujours connecté : rien n'est perdu. Regarde, dans cet ordre :

  • sudo sshd -T | grep '^port ' : doit donner .
  • sudo ss -tlnp | grep sshd : sshd doit écouter sur , en IPv4 (0.0.0.0) et en IPv6 ([::]).
  • sudo ufw status : /tcp doit être en ALLOW.
  • systemctl is-active ssh.socket : s'il répond active, c'est l'unité socket qui tient le port, pas sshd ; lance sudo systemctl daemon-reload && sudo systemctl restart ssh.socket. Par défaut Debian utilise ssh.service (Ubuntu, le socket) : vérifie avec systemctl is-enabled ssh.socket ssh.service.
  • Le Network Firewall d'OVH (espace client → ton IP → Network Firewall), si tu l'as activé : il filtre avant que les paquets n'atteignent le VPS ; ajoute une règle pour .
  • Pour revenir en arrière en dix secondes : sudo rm /etc/ssh/sshd_config.d/00-hardening.conf && sudo systemctl restart ssh. Tu es de nouveau sur le port 22, toujours ouvert.
  • Première session perdue elle aussi : connecte-toi sur la console KVM en avec ton mot de passe et lance les mêmes commandes.

Le nouveau port marche : ferme le 22, dans le terminal A.

Serveur·debian
$sudo ufw delete allow 22/tcp

Retirer le compte debian

Ouvre ta propre session depuis le Mac et vérifie que sudo accepte ton mot de passe :

Mac
$ssh vps
Serveur·te posera une question
$sudo true && echo SUDO OK

Une fois SUDO OK revenu, ferme le terminal A (exit). Puis, dans la session ssh vps. userdel affiche mail spool (/var/mail/debian) not found : c'est normal.

Serveur·
Commande sensible — suppression récursive ou forcée (rm). Vérifie avant d'exécuter.
$sudo pkill -KILL -u debian
$sudo userdel -r debian
$sudo rm -f /etc/sudoers.d/90-cloud-init-users

Depuis ton portable, vérifie que debian est refusé ; la réponse doit se terminer par Permission denied (publickey).

Mac
$ssh -p -o BatchMode=yes debian@ true

Bannir le brute force

Avec les mots de passe refusés, deviner ne sert à rien, mais les robots frappent quand même. fail2ban lit le journal de SSH et bannit une adresse après trois échecs.

Serveur·
$sudo apt install -y fail2ban python3-systemd

Puis la prison, en un seul fichier :

Serveur·écrit un fichier/etc/fail2ban/jail.d/sshd.local
[DEFAULT]
bantime.increment = true
[sshd]
enabled = true
port =
backend = systemd
maxretry = 3
findtime = 10m
bantime = 1h
Serveur·
$sudo systemctl enable fail2ban && sudo systemctl restart fail2ban
Vérification
$sudo fail2ban-client status sshd | head -1
Retour attendu
Status for the jail: sshd
Si tu te bannis toi-même

Trois fautes de frappe depuis ta propre adresse et tu es dehors pour une heure. Pour ne jamais bannir une adresse fixe à la maison, ajoute ignoreip = 127.0.0.1/8 ::1 suivi de ton adresse () sous [DEFAULT] avec sudo ${EDITOR} /etc/fail2ban/jail.d/sshd.local, et redémarre fail2ban. Pour te débannir, depuis une autre connexion (partage de connexion du téléphone) ou la console KVM :

Serveur·
$sudo fail2ban-client set sshd unbanip

Mises à jour de sécurité automatiques

Serveur·
$sudo apt install -y unattended-upgrades apt-listchanges
$printf 'APT::Periodic::Update-Package-Lists "1";\nAPT::Periodic::Unattended-Upgrade "1";\n' | sudo tee /etc/apt/apt.conf.d/20auto-upgrades

Autorise un redémarrage à quand une mise à jour en a besoin :

Serveur·écrit un fichier/etc/apt/apt.conf.d/52unattended-upgrades-local
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "";
Vérification
$apt-config shell UU APT::Periodic::Unattended-Upgrade
Retour attendu
UU='1'

Vérifier l'IPv6

La page suivante publie l'adresse IPv6 dans le DNS ; une adresse morte envoie les visiteurs IPv6 dans des délais d'attente. Sur le serveur, l'adresse globale doit être et doit atteindre internet :

Serveur·
$ip -6 addr show scope global
$ping -6 -c 3 2001:4860:4860::8888

Note le résultat : si ping -6 répond, la page 4 publie l'adresse IPv6 (enregistrement AAAA) ; sinon, elle n'en publie pas.

Faire un snapshot de l'état propre (facultatif, payant)

Dans l'espace client OVH, ouvre ton VPS : sur son onglet d'accueil, l'option Snapshot propose de la commander ; une fois active, prends un snapshot au même endroit. Sans l'option, tu as quand même la sauvegarde automatique incluse (un jour de rétention). Les libellés des menus bougent : le guide OVH « Utiliser les snapshots sur un VPS » sur docs.ovhcloud.com donne le chemin actuel.

Terminé

QuoiAvantAprès cette page
Qui se connectedebian, sudo sans mot de passe, clé uniquement, sudo avec mot de passe
Port SSH22
Root, mots de passeroot coupé, mots de passe peut-être actifs (cloud-init)refusés tous les deux par ton propre fichier
Trafic entranttout/tcp seulement
Brute forceessais illimités3 essais, puis banni
Mises à jour de sécuritéà la mainquotidiennes, automatiques, redémarrage à

Désormais, tu te connectes avec ssh vps. Page suivante : Pointer le domaine vers le serveur (DNS Infomaniak). Elle publie et dans la zone DNS Infomaniak de , pour que le nom mène à cette machine avant que Caddy ne demande un certificat.

Tout a fonctionné ?

Si tu as suivi cette page jusqu'au bout sur une vraie machine, dis-le. Ta validation est datée et enregistre ta stack : le prochain lecteur sur le même chemin sait que ça marche toujours.

Cette copie est en lecture seule. Pour dire que ça marche, ou que ça ne marche pas, ouvre une issue

Seuls tes choix de stack sont enregistrés, jamais tes valeurs. Le pseudo reste sur ce navigateur.