Les ports Linux et comment un service écoute
Un port aide un serveur à trier le trafic entrant vers le bon service. Apprenez à lire ce qui écoute avec ss et à distinguer un port local d'un port public.
Ce qu'est réellement un port
Un port est un numéro qui permet à un seul serveur de faire tourner plusieurs services en même temps sans que leur trafic se mélange. Votre VPS possède une seule adresse IP, mais il peut faire tourner un serveur web, un serveur SSH et une base de données en même temps. Quand un paquet arrive, le système d'exploitation doit savoir auquel de ces services il est destiné. Le numéro de port est la réponse. Le trafic web va vers le port 443, le SSH vers le port 22. L'adresse IP achemine le paquet jusqu'à votre serveur ; le port l'achemine vers le bon programme sur ce serveur.
Un port est un nombre sur 16 bits : 16 bits donnent de 0 à 65535, et 0 est réservé, donc en pratique les ports vont de 1 à 65535. Les ports en dessous de 1024 sont les ports « bien connus » et nécessitent root pour être ouverts, c'est pourquoi les services standards s'y trouvent : 22 pour SSH, 80 pour HTTP, 443 pour HTTPS, 53 pour DNS. Tout ce qui est au-dessus de 1024 est libre pour les programmes ordinaires.
Il en existe deux types, TCP et UDP, et un numéro de port dans l'un est distinct du même numéro dans l'autre. TCP est le protocole orienté connexion qu'utilisent la plupart des services, comme SSH, HTTP et les bases de données. UDP est sans connexion et sert à des choses comme le DNS et certains VPN. Quand vous ouvrez un pare-feu, vous précisez en général lequel, par exemple 22/tcp.
Écouter signifie qu'un programme attend sur un port
Un programme qui veut recevoir des connexions demande au noyau d'« écouter » sur un port. À partir de ce moment, le port est ouvert sur la machine et le programme répond à tout ce qui y arrive, sous réserve du pare-feu. Un port sur lequel rien n'écoute refuse simplement les connexions. La première question de tout contrôle de sécurité est donc : qu'est-ce qui écoute, et où.
La commande qui répond à cela est ss :
sudo ss -tlnpLes options signifient TCP (t), sockets en écoute uniquement (l), ports numériques (n, pour voir 22 et non ssh) et le processus propriétaire (p). Un résultat typique :
State Recv-Q Local Address:Port Process
LISTEN 0 0.0.0.0:22 sshd
LISTEN 0 127.0.0.1:5432 postgres
LISTEN 0 [::]:80 nginxLa colonne Process vous indique quel programme possède chaque port, ce qui vous permet de retrouver quelque chose que vous n'aviez pas l'intention de laisser tourner.
La colonne Local Address est la partie qui compte
Lisez attentivement l'adresse devant chaque port, car elle décide qui peut atteindre le service. Il y a trois cas que vous verrez en permanence.
0.0.0.0:22 signifie « écouter sur toutes les adresses IPv4 de cette machine », y compris son adresse publique. Le service est joignable depuis Internet en IPv4, si un pare-feu le permet.
[::]:80 signifie la même chose pour l'IPv6 : écouter sur toutes les adresses IPv6, publique comprise. Beaucoup de programmes s'y lient par défaut, et sous Linux une socket :: accepte souvent aussi l'IPv4.
127.0.0.1:5432 signifie « écouter uniquement sur la boucle locale ». 127.0.0.1 est l'adresse qu'une machine utilise pour se parler à elle-même, et elle n'est routable depuis nulle part ailleurs. Un service lié ici n'est joignable que depuis le même serveur, jamais depuis Internet, quoi que dise votre pare-feu. La ligne Postgres ci-dessus est sûre par construction.
La règle pratique en découle directement : une base de données, un cache ou un panneau d'administration que seules vos propres applications utilisent doit se lier à 127.0.0.1, et non à 0.0.0.0. S'il n'écoute jamais sur une adresse publique, il n'y a rien qu'un attaquant puisse atteindre.
Écouter n'est pas la même chose qu'être joignable
Une dernière distinction évite bien des confusions. Qu'un port soit ouvert sur la machine, c'est-à-dire qu'un programme écoute, est différent de ce port étant joignable depuis l'extérieur, c'est-à-dire que le pare-feu l'autorise. Les deux doivent être vrais pour qu'un client distant se connecte.
Il y a donc deux niveaux de contrôle. Vous décidez ce qui écoute, en réglant l'adresse de liaison de chaque service. Et vous décidez ce que le monde extérieur peut atteindre, avec un pare-feu. Un serveur bien géré utilise les deux : les services ne se lient que là où ils en ont besoin, et un pare-feu refuse tout ce que vous n'avez pas explicitement autorisé. Lire ce qui écoute avec ss est la première étape ; décider ce que le pare-feu autorise est la deuxième, traitée dans les bases du pare-feu avec UFW.
Il y a un piège subtil ici. IPv4 et IPv6 sont distincts, et un pare-feu qui ne couvre que l'IPv4 laisse les services [::] ouverts en IPv6. Ce piège précis a son propre article : le piège du pare-feu IPv6.
FAQ
Comment voir quels ports sont ouverts sur mon serveur Linux ?
Exécutez sudo ss -tlnp pour le TCP ou sudo ss -ulnp pour l'UDP. Cela liste chaque socket en écoute, le port, l'adresse locale à laquelle il est lié et le processus qui le possède. Lisez la colonne Local Address : 0.0.0.0 ou [::] signifie que le service est exposé au réseau, tandis que 127.0.0.1 signifie qu'il n'écoute que sur la machine elle-même.
Quelle est la différence entre 0.0.0.0 et 127.0.0.1 ?
0.0.0.0 signifie « écouter sur toutes les adresses IPv4 », y compris l'adresse publique, si bien que le service peut être atteint depuis le réseau. 127.0.0.1 est la boucle locale, l'adresse que la machine utilise pour se parler à elle-même, et elle n'est routable depuis nulle part ailleurs, donc un service qui y est lié n'est joignable que localement. Liez les services internes à 127.0.0.1 pour qu'ils ne soient jamais exposés.
Dois-je ouvrir un port dans le pare-feu pour qu'un service fonctionne ?
Seulement pour les services qui doivent être atteints depuis d'autres machines. Un service lié à 127.0.0.1 n'a besoin d'aucune règle de pare-feu, car rien d'extérieur ne peut l'atteindre de toute façon. Un service sur 0.0.0.0 ou [::] a besoin d'une règle de pare-feu pour autoriser le trafic, et devrait être refusé par défaut jusqu'à ce que vous en ajoutiez une.
Quelle est la différence entre un port TCP et un port UDP ?
TCP est orienté connexion et utilisé par la plupart des services, comme SSH, les serveurs web et les bases de données. UDP est sans connexion et utilisé par le DNS et certains VPN. Le même numéro en TCP et en UDP correspond à des ports distincts, donc 53/tcp et 53/udp sont différents. Quand vous écrivez des règles de pare-feu, vous nommez le protocole, par exemple 22/tcp.