Netcat, créez votre serveur en BASH

25/06/2008

Bash est puissant, très puissant. Les commandes et utilisations sont vastes à tel point que vous pouvez aller jusqu’à créer un serveur complet en Bash… oui vous m’avez bien entendu: **en Bash**. Ceci est possible grâce à la commande **nc** communément appelée //netcat//. Son principe est simple comme bonjour. Tout comme “cat” peut lire un fichier et l’envoyer sur la sortie standard, “nc” va faire exactement la même chose mais depuis un port.

Netcat est un outil développé depuis des années, abandonné par son auteur puis redéveloppé et maintenu par la communauté. Il existe plusieurs implémentation de cette commande, mais la plus répandue est celle d’OpenBSD nommée GNUnetcat. Les différentes implémentations fonctionnent toutes quasiment de la même manière, seules les options peuvent changer. J’ai pour ma part la même version de netcat sur mon macOSX et ma Fedora 9. Je pense que les distributions actuelles sont à jour sur ce point. Il existe des implémentations Windows de netcat. Mais voyons maintenant ses capacités.

Je vais vous montrer comment utiliser netcat pour communiquer d’une machine à l’autre, transférer des fichiers,… et communiquer avec des serveurs existant (serveur WEB, serveur MAIL…). Puis nous verrons comment créer un véritable serveur communiquant avec le client grâce à des “backpipes” (tube FIFO).

Cas simple 1, communication standard

“nc” peut prendre différentes options, mais je vais vous donner seulement celles qui vont nous intéresser par la suite. --l demande à netcat de se mettre en écoute. C’est le mode **serveur** qui sera activé (“l” pour “listen”) --k après fermeture du clients, le serveur n’est pas coupé et peut attendre d’autres clients (“k” pour “keep alive”). Pour le moment je ne l’utilise pas, mais si vous souhaitez que le serveur tourne continuellement, ajoutez l’option à votre ligne de lancement server.

Si aucune option n’est donnée, nous n’allons pas écouter mais tenter de nous connecter à une machine, c’est à dire que nous utiliserons netcat comme **client**. Testons un cas simple: Ouvrez deux terminaux de commande pour commencer. Dans le premier tapez:

nc -l 3333

Vous venez de créer un serveur basique qui écoute sur le port 3333 de votre machine.

Dans le second terminal, tapez:

nc 127.0.0.1 3333

Cette fois, c’est le client qui est créé. Vous venez de vous connecter à votre propre machine (127.0.0.1 ou localhost) sur le port 3333. Toujours sur ce terminal, vous voyez que la commande n’est pas terminée. Effectivement, elle attend que l’on tape dans l’entrée standard. Tapez “Salut” par exemple puis sur la toucher “Entrée” et regardez dans la première fenêtre de terminal où nous avons créé notre serveur. Et oui, vous voyez que le serveur reçoit votre “Salut”.

Mais cela fonctionne dans l’autre sens, d’ailleurs, tapez “Hello” dans la première fenêtre de terminal où le serveur a été créé, et regardez la fenêtre cliente. Idem, vous recevez les données.

Dans la fenêtre “cliente” (la seconde) pressez CTRL+C. Le client se ferme mais et le serveur aussi. Nous verrons par la suite qu’il est possible de se mettre en attente d’autres connexions sans que le serveur s’éteigne.

Vous pouvez aussi transformer les donnée reçues, par exemple, créez ce serveur:

nc -l 3333 | sed "s/world/galaxy/"

Puis tapez dans un autre terminal:

echo "Hello the world" | nc 127.0.0.1 3333

Sur le serveur, vous devriez voir apparaitre “Hello the galaxy”. La redirection de sortie va être **très utile** par la suite, notamment pour traiter des données et répondre au client. Pour le moment, voyons un autre exemple.

Cas simple 2, transfère de fichier

Nous l’avons vu précédemment, netcat lit et écrit sur la sortie standard. Comme pour toutes les commandes bash, il est possible de rediriger les sorties. Voyons comment copier rapidement un fichier d’une machine à l’autre. D’abord, créons le serveur qui va lire les donnée envoyées et les enregistrer dans un fichier:

nc -l 3333 > /tmp/fichier.txt

Créez un fichier /tmp/transf.txt et mettez-y “Hello the world” à l’interieur. Ensuite faites:

nc 127.0.0.1 3333 < /tmp/transf.txt
   -- ou bien --
cat /tmp/transf.txt | nc 127.0.0.1 3333

Alors que ce passe-t-il ? on se connecte à la machine 127.0.0.1 sur le port 3333 et on y envoie le contenu d’un fichier texte. Du coté serveur, on écoute sur le port local 3333 et on redirige ce que l’on reçoit vers le fichier /tmp/fichier.txt.

Vérifiez le contenu du fichier /tmp/fichier.txt, et oui ça a marché

Le droit de réponse, code boomerang

Pour le moment, nous n’avons put répondre au client qu’en tapant dans le terminal qui écoute. Le soucis c’est que nous aimerions pouvoir automatiser les réponses. L’idée est d’utiliser des “pipes” (ou “tube” en français) qui vont permettre de lire et écrire au fur dans les deux sens.

  • - Petit rappel:**

-un fichier FIFO (pipe FIFO) va se vider chaque fois qu’il est lut, et ce //ligne par ligne//. Il accumule les lignes chaque fois qu’on écrit dedans. La première ligne entrée dans le fichier sera la première à sortir. //FIFO = First In, First Out//. -Si vous exécutez une commande le flux standard se trouve dans le canal 1, les erreurs dans le canal 2. Par exemple sed “s/titi/toto/” < /tmp/fichier.txt | cat 1> /tmp/transform va faire ceci -envoyer le contenu du fichier dans la commande sed pour transformer les données -le flux de sortie va partir dans /tmp/transform sans les erreurs -Pour qu’un script Bash puisse lire l’entrée standard, il faut utiliser la commande read

  • - ATTENTION** Veillez à ce que le “1” soit **collé** au symbole “>” sinon Bash vous répondra qu’il ne connait pas le fichier “1”. Or nous voulons parler du canal 1.

Maintenant, lançons nous. Nous allons faire un //“boomerang”//, c’est à dire que tout ce que le client tapera sera retourné au client. Cet exemple vous montre comment lire et écrire dans netcat directement.

Coté serveur:

mkfifo /tmp/backpipe
nc -l 3333 < /tmp/backpipe | cat 1> /tmp/backpipe
</code>  


Je demande à netcat d'écouter le port 3333 et d'écrire le contenu de /tmp/backpipe (notre FIFO) au client. Tout ce que le client tapera sera aussi envoyé au backpipe... c'est pas génial ça ?

Allons y, tentons:
<code>
$ nc 127.0.0.1 3333
Hello
Hello

Je n’ai tapé qu’une seule fois “Hello” dans cet exemple, mais le serveur m’a retourné ce que j’ai tapé. Notre serveur lit et écrit. Nous allons pouvoir nous amuser un peu.

Pour le moment, je fais cat 1> /tmp/backpipe c’est à dire que tout ce que je reçois en sortie standard repars dans /tmp/backpipe. L’idée, c’est de ne plus utiliser cat mais notre propre serveur en bash, en perl, en ce que vous voulez. Tout ce qui importe c’est que votre serveur lise en continue **l’entrée standard** et écrive le résultat dans **la sortie standard**. En bash, nous utiliserons read pour lire STDIN, et echo pour écrire sur STDOUT. Vous pouvez tout aussi bien créer un service en perl, en python, en java…

Premier serveur en bash

Nous allons nous amuser à faire un petit serveur qui saura faire deux chose selon ce que le client demande.

-Si l’utilisateur tape “date” alors le serveur enverra la date -Si le client tape ping alors le serveur doit répondre par “pong”.

Voici notre script bash, que vous placerez dans /tmp/server1.sh: ` #! /bin/bash

tous ce que le client va m’envoyer se trouvera dans la variable “question”

while read question do if [[ “$question” == “date” ]]; then date fi

 if [[ "$question" == "ping" ]]; then
    echo pong
 fi

done

exit 0 `

Maintenant la ligne de bash qui va faire fonctionner le service:

mkfifo /tmp/backpipe
nc -l 3333 < /tmp/backpipe | bash /tmp/server.sh 1> /tmp/backpipe

Notre serveur est lancé; lancons un client:

patrice$ nc 127.0.0.1 3333
date
Mer 25 jui 2008 14:28:41 CEST
ping
pong

Il fonctionne… c’est pas merveilleux ? Vous pourriez aussi rendre la ligne un peu moins grosse en rendant /tmp/server1.sh executable:

chmod +x /tmp/serer1.sh

Ce qui vous donnera le lancement de serveur de cette manière:

mkfifo /tmp/backpipe
nc -l 3333 < /tmp/backpipe | /tmp/server.sh 1> /tmp/backpipe
Notes

J’ai passé un moment à chercher pourquoi seulement “cat 1> /tmp/backpipe” fonctionnait très bien, mais pas les commandes tr, sed, etc… en fait il semblerait que c’est simplement parce que ces commandes ne savent pas lire en boucle STDIN. Notre script Bash lit continuellement STDIN (boucle while read…) et ne pose pas de soucis.

Run basic server

Sur la base de ce ticket, j’ai créé un petit scipt appelé RBS ou Run Basic Sever. Il est opensource et sous licence GPL. Voici comment elle fonctionne:

rbs monserver.sh 3333

Et j’ai aussi pensé à l’option “-k” pour garder le serveur actif après fermeture du client:

rbs -k monserver.sh 3333

Il existe aussi les options -h pour avoir de l’aide, et -v pour avoir la version du script. Je vous laisse récupérer mon script rbs-0.0.1.tar.gz.

Vous pouvez tester le serveur de notre tutoriel:

./rbs -k /tmp/server1.sh 3333

Vous pouvez copier le fichier rbs.sh dans /usr/bin pour qu’il soit accessible directement:

cd /tmp
wget http://www.metal3d.org/tools/rbs-0.0.1.tar.gz
tar zxvf rbs-0.0.1.tar.gz
cp rbs-0.0.1/rbs.sh /usr/bin/rbs
chmod +x /usr/bin/rbs
rbs -v

Vous devriez avoir le numéro de version de RBS qui s’affiche à la fin de ces commandes. Si c’est le cas, c’est que rbs est installé, sinon, dites mois où vous coincez.

Dans tous les cas, laissez moi des commentaires c’est toujours sympa d’avoir des retours.

Références

Gnu Netcat: http://netcat.sourceforge.net/\\ Man page: http://www.openbsd.org/cgi-bin/man.cgi?query=nc\\ Run Basic Server: http://www.metal3d.org/tools/rbs-0.0.1.tar.gz

Ça peut vous intéresser aussi


Sauvegarde automatisé en Bash

On m’a demandé hier soir sur un canal IRC ...


OpenOffice en mode serveur

Il est parfois compliqué de créer des documents dignes de ...


xinetd ou la création de service facile

Création d’un serveur avec xinetd


Optimisons un peu notre Linux en limitant les accès disques

Que vous ayez un SSD ou non, je pense que ...

Merci de m'aider à financer mes services

Si vous avez apprécié cet article, je vous serai reconnaissant de m'aider à me payer une petite bière :)

Si vous voulez en savoir plus sur l'utilisation de flattr sur mon blog, lisez cette page: Ayez pitié de moi

Commentaires

Ajouter un commentaire

Caledonien - 21/09/2008

Hello,

Merci pour ton explication sur netcat, je ne savais pas qu’il était possible de créer un serveur aussi rapidement, on imagine très rapidement l’étendu que cela apporte :)

Merci && Bonne journée :)

Metal3d - 22/09/2008

Mais de rien :)

En fait, le système de service peut très bien se faire avec un xinetd, mais netcat est une solution tellement sympa. Ce qui me dérange c’est qu’il est peu utilisé et oublié de pas mal d’administrateur, utilisant (à mauvais escient) telnet…

Netcat est un véritable interlocuteur de sockets alors que telnet utilise un protocole. Netcat est donc plus propre pour des tests de serveurs.

test - 16/03/2010

netcat en local : ok

mais comment faire en avec une ip public

j’arrive pas a me connecter a mon server ex: nc 80.255.xx.xx 1234 ou meme en telnet, je n’est pas accès.

faut il ouvre le port sur le routeur ?

merci

web-site-creation - 08/11/2010

Effectivement pour que votre serveur web soit disponible publiquement, vous devez ouvrir un port sur votre pare feu si vous utilisez par exemple une *box, sinon vous aurez accès uniquement en réseau local…

Cela dit, netcat c’est bien pour dépanner et faire des tests, mais vous devriez rester en local, c’est pas fait pour de la production.

Ajouter un commentaire

(*) Votre e-mail ne sera ni revendu, ni rendu public, ni utilisé pour vous proposer des mails commerciaux. Il n'est utilisé que pour vous contacter en cas de souci avec le contenu du commentaire, ou pour vous prévenir d'un nouveau commentaire si vous avez coché la case prévue à cet effet.