#1 Le 27/05/2010, à 21:07
- Tetsuo6995
Problème avec un "serveur netcat" simple.
Bonjour.
J'éprouve de grosses difficultés a modifier un script servant de serveur netcat très basique.
Le serveur (code à la suite) permet à un client de se connecter dessus et d'exécuter de manière distante des commandes diverses. C'est plus ou moins un shell distant très simple.
#! /bin/bash
# Ce script implémente un serveur.
# Le script doit être invoqué avec l'argument :
# PORT le port sur lequel le serveur attend ses clients
if [ $# -ne 1 ]; then
echo "usage: $(basename $0) PORT"
exit -1
fi
PORT="$1"
# Déclaration du tube
FIFO="/tmp/$USER-fifo-$$"
# Il faut détruire le tube quand le serveur termine pour éviter de
# polluer /tmp. On utilise pour cela une instruction trap pour être sur de
# nettoyer même si le serveur est interrompu par un signal.
function nettoyage() { rm -f "$FIFO"; }
trap nettoyage EXIT
# on crée le tube nommé
[ -e "FIFO" ] || mkfifo "$FIFO"
function accept-loop() {
while true; do
interaction < "$FIFO" | nc -v -l "$PORT" > "$FIFO"
done
}
# La fonction interaction lit les commandes du client sur entrée standard
# et envoie les réponses sur sa sortie standard.
#
# CMD arg1 arg2 ... argn
#
# alors elle invoque la fonction :
#
# commande-CMD arg1 arg2 ... argn
#
# si elle existe; sinon elle envoie une réponse d'erreur.
function interaction() {
local cmd args
while true; do
read cmd args || exit -1
fun="commande-$cmd"
if [ "$(type -t $fun)" = "function" ]; then
$fun $args
else
commande-non-comprise $fun $args
fi
done
}
# Les fonctions implémentant les différentes commandes du serveur
function commande-non-comprise () {
echo "Le serveur ne peut pas interpréter cette commande"
}
function commande-shutdown() {
shutdown -t 10
}
# Le "touch" me sert a avoir une trace coté serveur de la bonne réception d'une commande. Il ne sert a rien d'autre.
function commande-reponse() {
echo "reponse du serveur"
touch yahoo
}
function commande-convert() {
echo $1 | tr '[:lower:]' '[:upper:]'
}
# On accepte et traite les connexions
accept-loop
L'utilisation standard de ce serveur est la suivante :
Il suffit de donner en argument le port sur lequel le serveur netcat doit écouter et attendre une connexion.
Un client (en local pour l'exemple) peut ensuite venir se connecter en faisant:
nc localhost port
Mon objectif et mon plus gros problème est le suivant :
Une fois connecté il suffit alors de tapper la commande puis d'appuyer sur entrée pour que le serveur la traite. Seulement j'aimerais pouvoir envoyer une commande à ce serveur sans pour autant la taper manuellement coté client.
Pour ce faire j'ai essayé les méthodes :
echo -n "commande\r" | nc localhost 8080
nc localhost 8080 < testducat
cat testducat | nc localhost 8080
Avec un fichier texte "testducat" contenant la commande a envoyer.
Mais le serveur ne réagit absolument pas. Pourtant ce type de commande devrait imiter à la perfection une entrée au clavier non ?
De plus elle ressemble fortement à la commande d'exemple proposée dans le man de netcat...
Je suppose que le/la FIFO présente coté serveur empèche la réception de la chaîne de caractère envoyé par echo.
Étonnamment la seul fois où j'ai réussi à faire parvenir une commande sans la taper c'est de la manière suivante :
yes "reponse" | nc localhost 8080
Cette commande sature de "reponse" le serveur et celui-ci répond. Mais ce n'est évidemment pas très pratique étant donné que la commande coté serveur est exécutée une infinité de fois...
Sincèrement j'ai passé plusieurs heures cette après midi pour trouver une solution. Je vous prie de croire que ce n'est pas par fainéantise que je me permets d'appeler à l'aide Mais bien parce que je ne comprends pas où est le problème
Hors ligne
#2 Le 28/05/2010, à 09:25
- Totor
Re : Problème avec un "serveur netcat" simple.
Bonjour,
Pour envoyer des instructions à ton serveur, il faut utiliser l'option -c.
Ex : nc -c "echo reponse" localhost 8080
Dans ce contexte voici un script qui peut t'aider.
Maintenant, si tu utilises un FIFO, je pense (car je n'ai pas testé et je n'en ai pas les moyens au taf) qu'il faut l'alimenter avant de lancer ton backpipe.
Dans ton cas :
[...]
[ -e "FIFO" ] || mkfifo "$FIFO"
echo "reponse" > ${FIFO}
[...]
accept-loop
-- Lucid Lynx --
Hors ligne
#3 Le 28/05/2010, à 18:16
- Tetsuo6995
Re : Problème avec un "serveur netcat" simple.
Super ! Merci pour la réponse. Je n'avais pas trop compris l'utilité de l'option -c.
Je vais tester ça tout de suite.
Par contre je ne suis pas sûr de comprendre comment fonctionne la fifo.
Comme je fais mes tests en local, dois-je prendre une fifo différente de celle utilisé sur le serveur ? En effet ce client/serveur doit pouvoir fonctionner aussi de manière réellement distante.
Mais bon je vais commencer par tester si l'option -c fonctionne avant de me tourner vers une fifo en émission..
EDIT:
nc -c "echo reponse" localhost 8080
Je ne comprends pas trop la forme de cette commande. Ne serait-ce pas plutôt:
echo "reponse" | nc -C localhost 8080
Cela ne fonctionne pas. Je me tourne vers la fifo
Dernière modification par Tetsuo6995 (Le 28/05/2010, à 18:25)
Hors ligne
#4 Le 29/05/2010, à 14:02
- Totor
Re : Problème avec un "serveur netcat" simple.
Bonjour,
Je suis depuis peu sous Lucid et je m'aperçois que la version de netcat a bien changée. l'option -c n'existe plus.
Enfin bon, alors la forme à utiliser est la suivante :
nc localhost 8080 <<< reponse
# qui est un équivalent à echo reponse| nc localhost 8080
Cependant, cette forme n'attend pas la réponse du serveur, il faut donc feinter avec un autre backpipe (FIFO) :
reponseServeur="$({ nc localhost 8080 </tmp/bickpipeclient| { echo "ce que tu veux envoyer au serveur"; read reponse; echo "${reponse}" >&3; } >/tmp/bickpipeclient ; } 3>&1 )"
echo "${reponseServeur}"
Par contre, le serveur est à lancer avec l'option -k pour ne pas qu'il s'arrête à chaque demande client.
Dernière modification par Totor (Le 30/05/2010, à 13:02)
-- Lucid Lynx --
Hors ligne
#5 Le 01/06/2010, à 15:03
- Tetsuo6995
Re : Problème avec un "serveur netcat" simple.
Ah ! Merci !
Le triple chevron <<< marche très bien
En particulier si on ajoute une option -q 1 à nc.
Avec cette syntaxe je reçois bien la réponse du serveur.
Hors ligne