Certains liens de cette page sont des liens d'affiliation : si vous vous inscrivez via ces liens, ce site touche une commission, sans surcoût pour vous. Les prix et les recommandations ne changent pas.

Quelqu’un vous remet le mot de passe root d’une machine qui tourne depuis des années. Elle sert des sites réels, personne ne se souvient comment elle a été configurée, et la personne qui l’a configurée est partie.

La tentation est de s’attaquer d’abord à la grosse tâche : la reconstruire, la migrer, la containeriser. Faites d’abord la petite tâche. Une heure, cinq questions, et vous saurez si la machine est un désagrément ou une urgence.

Voici l’audit que nous avons mené sur exactement une telle machine la semaine dernière, avec ce qu’il a réellement révélé. Chaque constat ci-dessous est réel, et aucun n’était visible depuis l’extérieur.

1. Qu’est-ce qui écoute, et qu’en pense le pare-feu ?

Ces deux réponses se comparent toujours, ne se lisent jamais séparément. La première est la vérité sur la machine ; la seconde est ce que quelqu’un a un jour voulu.

ss -tlnp                     # tous les sockets TCP en écoute, avec le processus
iptables -L INPUT -n --line-numbers

Notre constat, et c’est celui à retenir de cet article : le pare-feu avait une liste blanche soignée pour le port du panneau d’admin, trois sous-réseaux de confiance, écrite par quelqu’un qui savait ce qu’il faisait. Quatre lignes au-dessus se trouvait un ACCEPT générique pour ce même port depuis 0.0.0.0/0, ajouté plus tard.

iptables évalue dans l’ordre et s’arrête à la première correspondance. La liste blanche n’avait jamais, depuis le moment où cette ligne avait été ajoutée, restreint quoi que ce soit en deçà de tout le monde. La connexion admin était ouverte sur internet depuis des années, derrière une règle qui ressemblait, à première vue, à une restriction.

Lisez vos règles de haut en bas, avec les numéros de ligne, et demandez-vous laquelle correspond en premier. Une liste de règles est un programme, pas un ensemble.

2. Qui utilise réellement la chose que vous allez fermer ?

L’habitude la plus utile de l’audit. Avant de fermer un accès, lisez son journal d’accès et comptez les utilisateurs réels.

# principaux visiteurs d'un chemin donné, 10 000 dernières lignes
grep -h 'phpmyadmin' /var/log/nginx/*access* | awk '{print $1}' \
  | sort | uniq -c | sort -rn | head

Deux de nos constats sont sortis directement de là :

  • Un phpMyAdmin de 2017, accessible depuis internet, sur un serveur web dont le PHP n’avait plus aucun correctif en amont. Le journal montrait 201 requêtes depuis une adresse et 38 depuis une autre, deux scanners parcourant une liste de mots. Pas une seule session humaine sur la période observée.
  • proftpd qui tournait, en clair, sans TLS. xferlog était vide depuis juin. Les seules connexions étaient des tentatives de login anonymous venant d’un botnet.

Les deux ont été fermés en quelques minutes, sans risque de casser le travail de quiconque, parce que les journaux prouvaient qu’il n’y avait aucun travail en cours. Si les journaux avaient montré des sessions quotidiennes depuis une adresse IP de bureau, la réponse aurait été une liste blanche et une conversation, pas une fermeture.

La règle : ne jamais fermer un service parce qu’on croit que personne ne l’utilise. Le fermer sur la preuve que personne ne l’utilise. Les deux se ressemblent, jusqu’au jour où le service facturation appelle.

3. Ne vous verrouillez pas vous-même à la porte

Tout ce qui suit est du travail sur le pare-feu, effectué sur une machine à laquelle vous n’accédez que via ce pare-feu. Deux précautions, toutes deux peu coûteuses.

Armez un retour en arrière automatique avant de valider quoi que ce soit. Une tâche qui restaure le jeu de règles connu-bon dans dix minutes, annulée à la main une fois que vous avez confirmé que vous pouvez toujours entrer :

iptables-save > /root/iptables.good
echo 'iptables-restore < /root/iptables.good' | at now + 10 minutes

Appliquez votre changement, ouvrez une toute nouvelle session SSH depuis ailleurs, et ce n’est qu’alors que vous annulez la tâche avec atrm. Tester sur la session que vous avez déjà ouverte ne prouve rien : une connexion établie survit à des règles qui bloquent les nouvelles connexions.

Ensuite, assurez-vous que ça survit à un redémarrage, ce qui est une étape séparée et celle que tout le monde oublie :

service iptables save          # ou : netfilter-persistent save
systemctl is-enabled iptables

La nôtre redémarrait selon une programmation hebdomadaire dont nous ignorions l’existence. Le durcissement était toujours là après coup, parce que les règles avaient été sauvegardées, et nous le savions parce que nous avons vérifié après le redémarrage plutôt que de le supposer.

4. Qu’est-ce qui se renouvelle vraiment, et qu’est-ce qui le semble seulement ?

Le tueur silencieux. Sur cette machine, le renouvellement TLS était une tâche à l’intérieur d’un panneau de contrôle dont la licence avait expiré deux mois plus tôt. Le cron de renouvellement est mort avec la licence. Quatre sites échouaient déjà leur handshake TLS depuis cinq jours avant que l’audit ne le découvre, et sept autres étaient programmés pour expirer dans les trois semaines suivantes.

# toutes les tâches planifiées de la machine, en un seul passage
crontab -l; ls -l /etc/cron.*/ /etc/cron.d/; systemctl list-timers --all

Lisez tout, y compris les lignes commentées, car elles indiquent ce qui tournait autrefois. Et cherchez les doublons : nous avons désactivé un cron de renouvellement et n’avons trouvé qu’au second passage un deuxième, la même tâche, à une heure différente, quatre lignes plus bas.

Reprendre le renouvellement en main est un travail rapide même sur une distro en fin de vie - nous l’avons détaillé dans acme.sh sur un serveur où certbot refuse de s’installer.

5. Qu’est-ce qui est installé mais que rien n’utilise ?

Les machines anciennes accumulent les runtimes. La nôtre avait onze versions de PHP distinctes, remontant jusqu’à la 5.2. La question intéressante n’est pas ce qui est installé mais ce qui est réellement branché :

grep -rhoE 'php[0-9]+' /etc/nginx/conf.d/*.conf /etc/httpd/conf.d/*.conf \
  | sort | uniq -c | sort -rn

Huit sites tournaient en 7.4, trois en 8.0, et chaque version plus ancienne était du poids mort. Cette seule commande a changé le plan de migration : une machine qui semble avoir besoin d’une plateforme d’hébergement supportant PHP 5.2 a en réalité besoin de 7.4 et de 8.x, c’est-à-dire de n’importe quoi de moderne.

Un audit ne sert pas seulement à savoir quoi fermer. Il sert aussi à découvrir que la partie effrayante du travail n’existe pas.

Ce qu’une heure a rapporté

Quatre constats sur une seule machine : une liste blanche qui laissait passer tout le monde, un outil d’admin de neuf ans exposé aux scanners, un démon FTP qui ne servait personne, et un renouvellement de certificat mort depuis deux mois avec déjà quatre sites en panne.

Rien de tout cela n’a nécessité de reconstruction. Rien n’a nécessité de fenêtre de maintenance. Trois des quatre constats ont été corrigés dans l’heure, et le quatrième - la distro elle-même en fin de vie - est le seul constat honnête qu’on ne peut pas corriger par un patch, et c’est exactement pour ça qu’il appartient au plan de migration plutôt qu’au travail du jour.

Si cet audit vous pousse à chercher une machine de remplacement, nous avons comparé les options avec des prix réels dans Meilleur VPS pour l’auto-hébergement en 2026, et détaillé quatre années chez un même fournisseur dans notre avis sur Hetzner Cloud.