Pipe + Screen = ... un petit problème...

Résolu/Fermé
Tchou-Tchou Messages postés 4 Date d'inscription mardi 26 août 2008 Statut Membre Dernière intervention 26 août 2008 - 26 août 2008 à 10:01
Tchou-Tchou Messages postés 4 Date d'inscription mardi 26 août 2008 Statut Membre Dernière intervention 26 août 2008 - 26 août 2008 à 14:41
Bonjour à tous.

Je désire renifler mon réseau pour connaître les différents flux qui s'y promènent. J'ai trouvé un petit outil trés sympathique qui se superpose à tcpdump afin de me fournir les infos dont j'ai besoin. L'outil en question est nstreams. Voici la commande qui permet de l'utiliser :
$> tcpdump -l -n | nstreams

Il s'agit donc d'un pipe qui récupère les infos fournis par tcpdump dans la console. Des paramètres à la suite de nstreams permettent de spécifier 2 fichiers de configuration et bien d'autre chose.

Ici se trouve la documentation en ligne de nstreams : https://www2.deloitte.com/fr/fr/pages/risque-compliance-et-controle-interne/articles/cyber-academy.html/ressources/outils/nstreams/presentation.html

Première difficulté : l'activité de nstreams génère un affichage dans la console. Pour plus de confort lors de l'analyse, je préfére récupérer un fichier. Aussi je redirige la sortie de nstreams dans un fichier ce qui me donne la commande suivante :
$> tcpdump -l -n | nstreams -c [fichier-config-service] -n [fichier-config-reseau] >> /var/log/fichier-nstreams.log

Je désire transformer cet excellent outil en daemon sur une plate-forme à base de CentOS v5.1. Je me suis inspiré des scripts de daemon déjà présent dans le répertoire ~/init.d afin d'obtenir quelque-chose de correct. Voici le résultat :


#################################################
#!/bin/sh
# description: Start/stop nStreams Daemon
# chkconfig: - 99 10
# pidfile: /var/run/nstreamsd.pid

# J'appelle la bibliothèque de fonction.
# Peut-être est-ce inutile ???
. /etc/rc.d/init.d/functions

RETVAL=0
# Initialisation du nom du fichier log en vue d'une journalisation
ladate=`date +"%Y-%m-%d"`
NAME_LOG_FILE="nstreamsd-$ladate"

start()
{
     # Vérification de l'existance du processus
     if [ -f /var/run/nstreamsd.pid ]; then

          # Le processus existe
          echo -n $"nStreams Deamon (pid $(pgrep -o nstreams)) is running."
     else

          # Le processus n'existe pas
          echo -n $"Starting nstreamsd :"

          # Verification de l'existance du fichier log
          if [ -f /var/log/$NAME_LOG_FILE.log ]; then

               # Le fichier log existe
               #Initialisation de la commande à lancer selon l'éxistance du fichier log
               SCREEN_APPS="tcpdump -l -n | nstreams -c /usr/local/etc/nstreamsd-services -n /usr/local/etc/nstreamsd-networks >> /var/log/$NAME_LOG_FILE.log"
          else

               # Le fichier log n'existe pas
               #Initialisation de la commande à lancer selon l'éxistance du fichier log
               SCREEN_APPS="tcpdump -l -n | nstreams -c /usr/local/etc/nstreamsd-services -n /usr/local/etc/nstreamsd-networks > /var/log/$NAME_LOG_FILE.log"
          fi

          # Lancement de la commande
          # Dans un screen
          screen -S nstreamsd -m -d $SCREEN_APPS >/dev/null 2>&1

          # Sans screen
          # $SCREEN_APPS >/dev/null 2>&1

          # Récupération du code retour du lancement du processus
          RETVAL=$?

          # Traitement de ce code
          if [ "$RETVAL" = "0" ]; then
               touch /var/lock/subsys/nstreamsd
               echo_success
          else
               echo_failure
          fi
     fi
     echo
}

stop()
{
     # Vérification de l'existance du fichier PID du processus
     if [ -f /var/run/nstreamsd.pid ]; then

          # Le fichier PID existe
          echo -n $"Stopping nStreams Daemon (pid $(pgrep -o nstreams)):"

          # Vérification de la possibilité de tuer le processus
          kill -0 $(pgrep -o nstreams) >/dev/null 2>&1

          # Récupération du code retour de la verification
          RETVAL=$?

          # Traitement du code retour
          if [ "$RETVAL" <> "0" ]; then

               # Suppression du processus
               kill $(pgrep -o nstreams)

               # Suppression des fichiers affairant au déroulement du processus
               rm -f /var/lock/subsys/nstreamsd
               rm -f /var/run/nstreamsd.pid
               echo_success
          else
               echo_failure
          fi
     else
          # Le fichier n'existe pas
          echo -n $"nStreams Deamon is stopped."
     fi
     echo
}

status()
{
     # Recherche du fichier PID - c'est peut-être maladroit en cas de processus craché
     if [ -f /var/run/nstreamsd.pid ]; then
          echo "nStreams Daemon (pid $(pgrep -o nstreamsd)) is running"
          RETVAL=0
     else
          echo "nStreams Daemon is stopped"
          RETVAL=1
     fi
}

restart()
{
     stop
     start
}


case "$1" in
     start)
          start
          ;;

     stop)
          stop
          ;;

     restart)
          stop
          start
          ;;

     status)
          status
          ;;

     *)
          echo "Usage: $0 { start | stop | restart | status}"
          RETVAL=1
          ;;
esac
exit $RETVAL
#################################################



Après lancement du service pour test, aucuns fichier log n'est généré. Le pipe lancé directement ne s'execute pas et le service m'annonce un echec. Si j'utilise un screen, le screen s'exécute visiblement bien mais ne lance pas le pipe.
J'ai cherché sur internet de la documentation concernant screen, la programmation script, etc... mais pas d'info plus précise.

Je suis persuadé que ce n'est peut-être pas grand chose, une virgule, un point d'exclamation ou encore un "&" manquant. Mais pour l'instant, je sèche complètement.

Je vous remercie par avance de l'attention que vous porterez à mon problème.

@ Bientôt.
A voir également:

4 réponses

asevere Messages postés 13084 Date d'inscription lundi 28 janvier 2002 Statut Webmaster Dernière intervention 3 février 2022 426
26 août 2008 à 10:15
Bonjour,

Juste concernant le start:
start()
{
     # Vérification de l'existance du processus
     if [ -f /var/run/nstreamsd.pid ]; then

          # Le processus existe
          echo -n $"nStreams Deamon (pid $(pgrep -o nstreams)) is running."
     else

          # Le processus n'existe pas
          echo -n $"Starting nstreamsd :"

          # Verification de l'existance du fichier log
          if [ -f /var/log/$NAME_LOG_FILE.log ]; then

               # Le fichier log existe
               #Initialisation de la commande à lancer selon l'éxistance du fichier log
               SCREEN_APPS="tcpdump -l -n | nstreams -c /usr/local/etc/nstreamsd-services -n \
/usr/local/etc/nstreamsd-networks >> /var/log/$NAME_LOG_FILE.log"
          else

               # Le fichier log n'existe pas
               #Initialisation de la commande à lancer selon l'éxistance du fichier log
               SCREEN_APPS="tcpdump -l -n | nstreams -c /usr/local/etc/nstreamsd-services -n \
/usr/local/etc/nstreamsd-networks > /var/log/$NAME_LOG_FILE.log"
          fi

          # Lancement de la commande
          # Dans un screen
          screen -S nstreamsd -m -d $SCREEN_APPS >/dev/null 2>&1

          # Sans screen
          # $SCREEN_APPS >/dev/null 2>&1

          # Récupération du code retour du lancement du processus
          RETVAL=$?

          # Traitement de ce code
          if [ "$RETVAL" = "0" ]; then
               touch /var/lock/subsys/nstreamsd
               echo_success
          else
               echo_failure
          fi
     fi
     echo
}


Ton test sur l'existence d'un fichie ne sert à rien:
Soit le fichier exists et tu le completes (>>)
Soit le fichier n'existe pas et tu le crées (>)
alors que l'opérateur >> s'occupe de creer le fichier s'il n'existe pas.

Ensuite, pour la version sans screen, il manque effectivement un "&"

Si tu recode ta fonction start comme suit:
start()
{
     # Vérification de l'existance du processus
     if [ -f /var/run/nstreamsd.pid ]; then

          # Le processus existe
          echo -n $"nStreams Deamon (pid $(pgrep -o nstreams)) is running."
     else

          # Le processus n'existe pas
          echo -n $"Starting nstreamsd :"

         tcpdump -l -n | nstreams -c /usr/local/etc/nstreamsd-services -n \
/usr/local/etc/nstreamsd-networks >> /var/log/$NAME_LOG_FILE.log &

          # Récupération du code retour du lancement du processus
          RETVAL=$?

          # Traitement de ce code
          if [ "$RETVAL" = "0" ]; then
               touch /var/lock/subsys/nstreamsd
               echo_success
          else
               echo_failure
          fi
     fi
     echo
}


Cela fonctionne t-il mieux ?

A plus
0
Tchou-Tchou Messages postés 4 Date d'inscription mardi 26 août 2008 Statut Membre Dernière intervention 26 août 2008
26 août 2008 à 11:02
Bonjour Asevere.

J'ai testé ta solution trés pertinante. Malheureusement, elle ne fonctionne pas.
Le système m'indique que la commande nstreams du pipe n'a pas pu être trouvé. Ensuite, il lance trés bien le tcpdump mais l'arrête aussitot en m'indiquant trés peu de paquets capturés. Le fichier log est bien généré mais n'est pas alimenté. De plus, le système ne me rend pas la main après le lancement de la commande.

Il semblerait que le système interprete le pipe dans l'autre sens : d'abord le nstreams, puis le tcpdump. Car la première erreur affiché provient de nstreams, puis il indique les paquets capturés de tcpdump. Enfin, il laisse 'dormir' le prompt a l'issue.

Autre indication : le message d'affichage "Starting nstreamsd :" n'apparait pas. Mais le '[OK]' en vert est bien présent.

Peut-être dois-je me passer de la gestion de sortie avec /dev/null...


Merci tout de même de t'être penché sur mon cas.

@ Bientôt.
0
asevere Messages postés 13084 Date d'inscription lundi 28 janvier 2002 Statut Webmaster Dernière intervention 3 février 2022 426
26 août 2008 à 12:28
Alors... pour les commande, il est préférable de donner le chemin complet de la commande (/usr/bin/nstreams par exemple)

Ensuite, tcpdump buffurise sa sortie, en rajoutant l'option -c 10 au lancement de tcpdump (attendre 10 paquets) cela change t-il quelque chose ?

++
0
jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020 4 894
26 août 2008 à 12:30
buffurise
Très joli, je rajoute à mon dico si tu le permets ;-))
0
asevere Messages postés 13084 Date d'inscription lundi 28 janvier 2002 Statut Webmaster Dernière intervention 3 février 2022 426 > jipicy Messages postés 40842 Date d'inscription jeudi 28 août 2003 Statut Modérateur Dernière intervention 10 août 2020
26 août 2008 à 12:43
Grrrr :o)

Alors a prioris pour le problème qui nous interesse, c'est la libc C qui en detectant que la sortie est un pipe, buffurise celle çi...

A prioris, ça doit donc marcher pour peut qu'il n'y ait plus d'erreur sur les commandes, mais il faut être patient avant que le fichier de log ne se remplisse...
0
Tchou-Tchou Messages postés 4 Date d'inscription mardi 26 août 2008 Statut Membre Dernière intervention 26 août 2008
26 août 2008 à 13:30
Donc je reprends le code de la portion start :

start()
{
	# Vérification de l'existance du processus
	if [ -f /var/run/nstreamsd.pid ]; then

		# Le processus existe
		echo -n $"nStreams Deamon (pid $(pgrep -o nstreams)) is running."
	else
		# Le processus n'existe pas
		echo -n $"Starting nstreamsd :"

		# Lancement du pipe
		/usr/sbin/tcpdump -l -n -c 10 | /usr/local/bin/nstreams -c /usr/local/etc/nstreamsd-services -n /usr/local/etc/nstreamsd-networks >> /var/log/$NAME_LOG_FILE.log &

		# Récupération du code retour du lancement du processus
		RETVAL=$?

		# Traitement de ce code
		if [ "$RETVAL" = "0" ]; then
			touch /var/lock/subsys/nstreamsd
			echo_success
		else
			echo_failure
		fi
	fi
	echo
}


Les commandes sont bien executées, il n'y a plus d'erreur de ce coté là. Mais... Au bout de 10 paquets, tcpdump s'arrête et le processus ne semble pas me rendre la main. En appuyant sur 'Entrée', le système me rend le prompt. En consultant le fichier log de sortie, je vois bien qu'il a été remplis, mais il ne continue pas puisque tcpdump s'est arrété.


En fait, je viens de trouver une solution partielle : j'avais à l'origine un problème de chemin pour les commandes. L'option '-c 10' arrete la capture de tcpdump à 10 paquets. Il suffit de ne pas rajouter cette option pour que la capture continue.


Un autre problème maintenant : le traitement du code retour. Le pipe tourne bien puisque je le vois dans le résultat de la commance 'ps -aux'. Mais lorque j'interroge le service (avec la commande 'service nstreamsd status'), il m'annonce que le service est arrété. Et c'est normal, puisque je lance 2 processus.

Je vais étudier la chose. Cependant, je suis à l'écoute de vos piste d'étude pour la gestion PID de ce service.


Merci encore pour votre promptitude.

@bientôt.
0
asevere Messages postés 13084 Date d'inscription lundi 28 janvier 2002 Statut Webmaster Dernière intervention 3 février 2022 426
26 août 2008 à 13:37
Pour le pid, c'est normal, tu te bases sur l'existence du fichier: /var/run/nstreamsd.pid mais tu ne cré jamais ce fichier...
Il faudrait le rajouter dans le start a ce niveau là:
         # Traitement de ce code
          if [ "$RETVAL" = "0" ]; then
               touch /var/lock/subsys/nstreamsd
               touch /var/run/nstreamsd.pid
0
Tchou-Tchou Messages postés 4 Date d'inscription mardi 26 août 2008 Statut Membre Dernière intervention 26 août 2008
26 août 2008 à 14:41
Bonjour à tous.

Donc, pour les quelques uns qui pourraient être intéressés, voici le script final qui fonctionne. Seul un bug d'affichage relatif à tcpdump persiste.

#!/bin/sh
# description: Start/stop nStreams Daemon
# chkconfig: - 99 10

# J'appelle la bibliothèque de fonction.
# Peut-être est-ce inutile ???
. /etc/rc.d/init.d/functions

RETVAL=0
# Initialisation du nom du fichier log en vue d'une journalisation
ladate=`date +"%Y-%m-%d"`
NAME_LOG_FILE="nstreamsd-$ladate"

start()
{
	# Vérification de l'existance du processus
	if [ -f /var/run/nstreamsd.pid  ]; then

		# Le processus existe
		echo -n $"nStreams Deamon (pid $(pgrep -o nstreams)+$(pgrep -o tcpdump)) is running."
	else
		# Le processus n'existe pas
		echo -n $"Starting nstreamsd :"

		/usr/sbin/tcpdump -l -n | /usr/local/bin/nstreams -c /usr/local/etc/nstreamsd-services -n /usr/local/etc/nstreamsd-networks >> /var/log/$NAME_LOG_FILE.log &

		# Récupération du code retour du lancement du processus
		RETVAL=$?

		# Traitement de ce code
		if [ "$RETVAL" = "0" ]; then
			pgrep -o tcpdump >> /var/run/nstreamsd.pid
			pgrep -o nstreams >> /var/run/nstreamsd.pid
			touch /var/lock/subsys/nstreamsd
			echo_success
		else
			echo_failure
		fi
	fi
	echo
}

stop()
{
	# Vérification de l'existance du fichier PID du processus
	if [ -f /var/run/nstreamsd.pid  ]; then

		# Le fichier PID existe
		echo -n $"Stopping nStreams Daemon (pid $(pgrep -o nstreams)+$(pgrep -o tcpdump)):"

		# Vérification de la possibilité de tuer le processus
		kill -0 $(pgrep -o nstreams) $(pgrep -o tcpdump) >/dev/null 2>&1

		# Récupération du code retour de la verification
		RETVAL=$?

		# Traitement du code retour
		if [ "$RETVAL" <> "0" ]; then

			# Suppression du processus
			kill $(pgrep -o nstreams) $(pgrep -o tcpdump)

			# Suppression des fichiers affairant au déroulement du processus
			rm -f /var/lock/subsys/nstreamsd
			rm -f /var/run/nstreamsd.pid
			echo_success
		else
			echo_failure
		fi
	else
		# Le fichier n'existe pas
		echo -n $"nStreams Deamon is stopped."
	fi
	echo
}

status()
{
	# Recherche du fichier PID - c'est peut-être maladroit en cas de processus craché
	if [ -f /var/run/nstreamsd.pid  ]; then
		echo "nStreams Daemon (pid $(pgrep -o nstreams)+$(pgrep -o tcpdump)) is running"
		RETVAL=0
	else
		echo "nStreams Daemon is stopped"
		RETVAL=1
	fi
}

restart()
{
	stop
	start
}


case "$1" in
start)
	start
	;;

stop)
	stop
	;;

restart)
	stop
	start
	;;

status)
	status
	;;

*)
	echo "Usage: $0 { start | stop | restart | status}"
	RETVAL=1
	;;
esac
exit $RETVAL



Je vous remercie tous de l'attention que vous avez porté à mon problème.

@ Bientôt.
0