Aller au contenu

Netcat (nc) : tester un port, écouter, transférer un fichier

Un guide pratique de netcat : utiliser la commande nc pour vérifier si un port TCP ou UDP est ouvert avec nc -zv, lancer un service d'écoute jetable, capturer une bannière, balayer une plage et déplacer un fichier — avec les différences de drapeaux entre les variantes de nc.

Pour vérifier si un port TCP est joignable, lancez nc -zv <host> <port> : -z établit la connexion sans envoyer de données, -v affiche le résultat, et vous obtenez une ligne qui dit succeeded ou Connection refused. Cette seule commande répond à la question « est-ce que le port est ouvert d’ici » plus directement que telnet, curl ou un navigateur, parce qu’elle se moque du protocole derrière le port. Le reste de netcat — lancer un service d’écoute, transférer un fichier, capturer une bannière, balayer une plage — se construit à partir du même modèle client/écoute, et ce qui déroute le plus les gens, c’est que les drapeaux diffèrent entre les divers programmes qui s’appellent tous nc.

Ce que vous allez accomplir

  • Vérifier si un port TCP ou UDP est ouvert depuis l’endroit où vous êtes, avec un signal clair de réussite ou d’échec.
  • Monter un service d’écoute jetable et s’y connecter pour prouver que deux hôtes peuvent se parler.
  • Capturer la bannière d’un service et balayer une petite plage de ports.
  • Déplacer un fichier entre deux hôtes quand rien de plus élaboré n’est disponible.
  • Savoir quelle variante de nc vous tenez, parce que -p, -e et -z ne sont pas les mêmes partout.

Prérequis

  • Un hôte Linux ou macOS avec nc dans le PATH. Lancez d’abord nc -h — il affiche la variante et ses drapeaux, et c’est cette sortie qui vous dit quel programme vous avez. Le nc d’OpenBSD (celui par défaut sur la plupart des distributions Linux actuelles et sur macOS) montre -z et -N; l’ancien nc GNU/traditionnel montre -e et exige -p avant le port sur un service d’écoute; ncat (du projet nmap) montre --ssl et --exec.
  • Pour la démo de transfert, deux hôtes qui peuvent se joindre sur un port choisi, ou deux terminaux sur une seule machine qui se parlent par localhost.
  • Rien n’est à installer pour tester un port vers un hôte que vous joignez déjà. Pour installer nc là où il manque : apt install netcat-openbsd, dnf install nmap-ncat (cela vous donne ncat) ou apk add netcat-openbsd.

Comment ça marche

Netcat a exactement deux modes. En mode écoute, un processus lie un port local et attend; en mode client, un autre processus se connecte à un hôte et un port. Une fois connecté, netcat branche sa propre entrée standard sur le socket et le socket sur sa sortie standard — donc tout ce que vous tapez (ou canalisez) part vers l’autre côté, et tout ce que l’autre côté envoie s’affiche. Voilà toute la conception : un tube avec un socket réseau au milieu, qui fonctionne dans les deux sens à la fois.

Un hôte lance nc -l sur un port pendant que l'autre s'y connecte; une fois établie, les octets tapés d'un côté apparaissent de l'autre, et la note oppose TCP et UDP

TCP est le mode par défaut. Comme TCP fait une vraie poignée de main, une connexion se complète, est refusée activement ou expire — trois issues distinctes et fiables. UDP (-u) est sans connexion : il n’y a pas de poignée de main, alors netcat ne peut souvent pas distinguer un port UDP ouvert d’un paquet silencieusement rejeté, et cette ambiguïté vaut la peine d’être retenue avant de faire confiance à un résultat UDP.

Étape par étape

Vérifier un seul port TCP. C’est la commande à prendre par réflexe. -z veut dire « balayer sans envoyer de données » (zéro E/S), -v affiche ce qui s’est passé :

nc -zv example.com 443
Connection to example.com 443 port [tcp/https] succeeded!

Un port fermé qui rejette activement la connexion est sans ambiguïté :

nc -zv example.com 444
nc: connect to example.com port 444 (tcp) failed: Connection refused

« Connection refused » veut dire que quelque chose a répondu et a dit non — l’hôte est en marche, rien n’écoute sur ce port (ou un pare-feu envoie un reset). C’est différent d’une expiration, plus bas.

Ajouter un délai pour qu’un port filtré échoue vite. Sans délai, un port qu’un pare-feu rejette en silence laisse nc pendu jusqu’à ce que le système d’exploitation abandonne. -w plafonne l’attente en secondes :

nc -zv -w 3 example.com 8080
nc: connect to example.com port 8080 (tcp) failed: Operation timed out

Une expiration (plutôt qu’un « refused ») est la signature d’un pare-feu qui rejette les paquets en silence : rien n’a envoyé de reset, alors netcat a attendu les trois secondes complètes. Refusé contre expiré est la distinction la plus utile que netcat vous donne.

Tester un port UDP. Ajoutez -u. Lisez le résultat avec méfiance :

nc -zvu -w 3 dns.example.com 53
Connection to dns.example.com 53 port [udp/domain] succeeded!

Ce « succeeded » veut seulement dire qu’aucun ICMP port-unreachable n’est revenu dans le délai. Un port UDP silencieusement filtré est identique à un port ouvert. Traitez un « ouvert » UDP comme « pas prouvé fermé », et confirmez avec une vraie sonde de protocole (pour le DNS, dig @dns.example.com example.com) quand ça compte.

Lancer un service d’écoute. Sur l’hôte qui doit recevoir la connexion, liez un port et attendez. Avec le nc d’OpenBSD :

nc -l 9000

Laissez ça tourner. Depuis un second terminal ou l’autre hôte, connectez-vous et tapez une ligne :

nc 127.0.0.1 9000

Tout ce que vous tapez dans le client apparaît dans le terminal d’écoute, et tout ce que vous tapez dans l’écoute apparaît dans le client — c’est le tube à double sens du schéma. Faites Ctrl-C ou Ctrl-D pour fermer. Notez la différence de drapeau : le nc traditionnel/GNU veut le port après -p, sous la forme nc -l -p 9000, tandis que le nc d’OpenBSD prend le port comme simple argument. Si nc -l 9000 échoue, vous êtes probablement sur la variante traditionnelle.

Capturer une bannière. Bien des services s’annoncent à la connexion, ou répondent à une requête minimale. Canalisez une requête et laissez netcat afficher la réponse. printf (pas echo) garde les fins de ligne correctes pour HTTP :

printf 'HEAD / HTTP/1.0\r\nHost: example.com\r\n\r\n' | nc -w 3 example.com 80
HTTP/1.0 200 OK
Server: nginx
Content-Type: text/html

Pour un service en texte clair comme SMTP, se connecter suffit — le serveur vous accueille avec sa bannière. Utilisez -w pour que netcat ferme après la réponse au lieu de rester ouvert.

Balayer une petite plage. Le nc d’OpenBSD accepte une plage de ports sous la forme debut-fin, et combiné à -z -v il rapporte chaque port. Envoyez le bruit à grep pour ne garder que les ports ouverts :

nc -zv example.com 20-25 2>&1 | grep succeeded
Connection to example.com 22 port [tcp/ssh] succeeded!

Netcat écrit ses résultats -v sur la sortie d’erreur standard, d’où le 2>&1. C’est correct pour une poignée de ports sur un hôte qui vous appartient; ce n’est pas un vrai balayeur (voir la dernière section).

Transférer un fichier. Démarrez le récepteur en premier pour que le port écoute, puis lancez l’émetteur. Sur l’hôte récepteur :

nc -l -p 9000 > out.bin

Sur l’hôte émetteur, pointez-le vers le récepteur et redirigez le fichier dans l’entrée de netcat :

nc <receiver-host> 9000 < in.bin

Quand le fichier d’entrée se termine, l’émetteur ferme la connexion et les deux commandes se terminent. Le -p devant le port d’écoute est la forme du nc traditionnel; avec le nc d’OpenBSD, nc -l 9000 > out.bin marche aussi. Si le service d’écoute reste ouvert après le transfert, ajoutez -N (nc d’OpenBSD) du côté émetteur pour qu’il ferme à moitié le socket quand son entrée standard se termine, ce qui permet au récepteur de voir la fin de fichier et de se terminer.

Le récepteur lance nc -l en redirigeant le socket vers un fichier pendant que l'émetteur canalise un fichier dans nc; la note prévient qu'il n'y a ni chiffrement ni authentification

Valider que ça marche

Netcat ne vous donne ni barre de progression ni somme de contrôle, alors vérifiez le transfert vous-même. Hachez le fichier aux deux bouts et comparez. Sur l’émetteur :

sha256sum in.bin
9f2c...e1a4  in.bin

Sur le récepteur :

sha256sum out.bin
9f2c...e1a4  out.bin

Des hachages identiques veulent dire que chaque octet est arrivé intact. S’ils diffèrent, la connexion s’est fermée trop tôt — la cause la plus courante est un service d’écoute qui s’est terminé avant que les derniers octets ne soient vidés, ce que -N du côté émetteur évite.

Pour une vérification de port, confirmez que l’état correspond à ce que vous attendez en regardant le service d’écoute depuis l’hôte récepteur avec ss :

ss -ltnp | grep 9000
LISTEN 0  1  0.0.0.0:9000  0.0.0.0:*  users:(("nc",pid=4821,fd=3))

Si nc -zv dit qu’un port est ouvert mais que ss ne montre rien en écoute localement, vous joignez un autre hôte que vous ne le pensez, ou un répartiteur de charge répond à sa place. Pour le côté processus-et-socket de cette question, voyez lsof : trouver ce qui tient un fichier ou un port ouvert.

Dépannage

  • nc -l 9000 échoue, ou -z n’est pas reconnu. Vous êtes sur la variante traditionnelle/GNU, pas le nc d’OpenBSD. Utilisez nc -l -p 9000 pour un service d’écoute là-bas, et notez que certaines de ces variantes (le nc GNU en particulier) n’ont pas de -z; testez un port avec nc -vz seulement sur le nc d’OpenBSD ou ncat, ou repliez-vous sur nc -w 3 host port </dev/null. Lancez nc -h pour confirmer quel programme vous avez avant de faire confiance à un drapeau.
  • « Connection refused » contre un blocage ou une expiration. Refused veut dire que l’hôte est joignable et a rejeté activement le port — rien n’écoute, ou un pare-feu a renvoyé un reset. Un blocage (ou une expiration avec -w) veut dire que les paquets sont rejetés en silence, ce qui est la signature classique d’une règle DROP de pare-feu entre vous et l’hôte. Ce sont deux problèmes différents; ne les traitez pas pareil.
  • Un port UDP rapporte « ouvert » mais rien ne marche. UDP n’a pas de poignée de main, alors nc -zvu déclare un port ouvert dès qu’aucun rejet ICMP ne revient — y compris quand un pare-feu rejette la sonde en silence. Ne concluez jamais qu’un service UDP est en marche à partir de netcat seul; envoyez une vraie requête de protocole et cherchez une vraie réponse.
  • -e pour exécuter un programme n’existe pas. La classique passerelle nc -e /bin/sh n’est que dans le nc traditionnel et dans ncat (comme --exec/--sh-exec); le nc d’OpenBSD a retiré -e délibérément parce que c’est un piège de shell distant. S’il vous le faut, utilisez ncat --exec, et comprenez que vous avez ouvert un shell sans authentification à quiconque se connecte.
  • Le service d’écoute ne libère pas le port. Un service d’écoute qui reste ouvert après la déconnexion d’un client tient le port; arrêtez-le avec Ctrl-C. Si un nouveau service d’écoute rapporte « Address already in use », le socket précédent est en TIME_WAIT — attendez qu’il passe, choisissez un autre port, ou confirmez ce qui le tient avec ss -ltnp.

Quand c’est la mauvaise approche

Netcat est un outil de diagnostic, pas un mécanisme de livraison. Son transfert de fichier n’a ni chiffrement ni authentification — quiconque est sur le chemin peut lire les octets, et quiconque peut joindre le port peut se connecter à votre service d’écoute. Pour tout transfert qui quitte un réseau de confiance, utilisez scp ou rsync sur ssh, qui vous donnent le chiffrement, l’authentification et (pour rsync) les vérifications d’intégrité et la reprise gratuitement. Pour quoi que ce soit au-delà d’un rapide « est-ce que ce port est ouvert », prenez nmap, qui fait une vraie détection de service et de version, gère correctement les grandes plages et distingue honnêtement les états ouvert, fermé et filtré. Et quand vous avez vraiment besoin du comportement de tube de netcat avec TLS — parler à la main à un port HTTPS ou SMTPS — utilisez ncat --ssl plutôt que le nc simple, qui ne parle qu’en clair. Pour la version couche DNS de « est-ce que ce nom résout vers ce que j’attends », voyez dépanner le DNS avec dig. La référence de drapeaux qui fait autorité est la page de manuel de nc d’OpenBSD et, pour la variante nmap, la documentation de Ncat.

Si c’est le genre de travail que vous préféreriez ne plus jamais porter, c’est le quotidien d’Opérations Cloud — réservez une revue d’infrastructure.