tcpdump : créer le service

On a donc maintenant :

  • un premier script qui :
    • reçoit en entrée le nom de l’interface (je vais l’appeler tcpdetailtxt.sh)
    • reçoit en entrée le nom du fichier de dump à créer
    • créer le fichier texte de dump
    • lance dans un autre thread (avec nohup), le script qui remplit MySQL
  • un deuxième  (dumptomysql.sh) de remplissage de la table MySQL qui doit recevoir en entrées :
    • le nom de l’interface
    • le nom du fichier texte de dump

L’Objectif est de transformer tout cela en service. Donc un va créer un script maître (tcpdetail.sh) doit recevoir en entrée le nom de l’interface et lancer dans une boucle les 2 autres scripts. On peut faire une boucle infini (while true) moi, je n’aime pas ça, je préfère avoir toujours une condition de sortie. Je vais donc m’assurer que chaque étape se passe bien via un code retour en faisant comme ceci :

#!/bin/sh
# r est mon code d'erreur, initialisation à 0
r=0
# le script attend un paramètre : le nom de l'interface
iface="$1"
# le nombre de packet à traiter à chaque fois, on peut l'augmenter
nbpacket=500
#je m'assure que l'interface existe sinon je sors
ip=$(ifconfig "$iface" | grep inet | grep netmask | awk '{print $2}')
r=$?
if [ $r -ne 0 ]; then
   exit $r
fi
#boucle tant que le code retour vaut 0
while [ $r -eq 0 ]
do
    # chaque fichier de dump doit avoir un nom unique   
    dt=$(date +"%Y%m%d%H%M%S")
    ffile="/tmp/dump""$iface""$dt"".txt"
    # lancement du script de création du fichier de dump
    sh tcpdetailtxt.sh "$iface" "$nbpacket" "$ffile"
    r=$?
    # si pb je sors
    if [ $r -ne 0 ]; then
       echo $r
       exit $r
    fi 
    #lancement indépendant du fichier de remplissage de mysql
    nohup sh dumptomysql.sh "$iface" "$ffile"
    r=$?
    # si pb je sors
   if [ $r -ne 0 ]; then
      echo "Pb dumptomysql.sh ""$r"
      exit $r
   fi  
done   

C’est tcpdetail.sh avec en paramètre le nom de l’interface qui sera lancé en tant que service quelque soit le nom de l’interface et même s’il y en a plusieurs à surveiller.

Enregistrement du service dans le système

Je ne traiterai ici que le cas systemd car systemd se généralise de plus en plus, il est même présent sur les raspbian présent sur les RaspBerry Pi !

Pour cela il nous faut créer un fichier dans /lib/systemd/system/ dont le nom est le nom du service suivit de .service. Comme je veux un service par interface, je mettrai le nom de l’interface dans le nom du service.

Ce fichier doit contenir ceci :

[Unit]
Description=Nom du service, j'y mettrait le nom de l'interface

[Service]
Type=simple
Wants=network-online.target : je veux qu'au démarrage, les interfaces réseaux soient "online"
After=mysqld : je veux que mysqld tourne déjà avant qu'il ne démarre
User=root
Group=root
WorkingDirectory= le dossier de travail (celuiquicontient les scripts)
PIDFile=le nom du fichier qui contiendra le PID du processus
ExecStart=le script à lancer avec ces paramètres (tcpdetail.sh eth0 par exemple)

[Install]
WantedBy=multi-user.target

J’ai deux interfaces à suivre donc 2 fichiers à créer quasi identique à la différence du nom de l’interface. Pour ne pas me tromper, j’ai créer un script qui fait génère le fichier de description du service  qui se nomme instserv.sh  et qu’on lance en précisant l’interface.

iface="$1"
if [ "$iface" == "" ]; then
exit 1
fi
touch /lib/systemd/system/tcpdump$iface.service
echo "[Unit]" >> /lib/systemd/system/tcpdump$iface.service
echo "Description=Dump $iface service Daemon" >> /lib/systemd/system/tcpdump$iface.service
echo "" >> /lib/systemd/system/tcpdump$iface.service
echo "[Service]" >> /lib/systemd/system/tcpdump$iface.service
echo "Type=simple" >> /lib/systemd/system/tcpdump$iface.service
echo "Wants=network-online.target " >> /lib/systemd/system/tcpdump$iface.service 
echo "After=mysqld" >> /lib/systemd/system/tcpdump$iface.service
echo "User=root" >> /lib/systemd/system/tcpdump$iface.service
echo "Group=root" >> /lib/systemd/system/tcpdump$iface.service
echo "WorkingDirectory=/var/www/html/tcpstatmysql/bash/" >> /lib/systemd/system/tcpdump$iface.service
echo "PIDFile=//var/www/html/tcpstatmysql/bash/tcpdump$iface.pid" >> /lib/systemd/system/tcpdump$iface.service
echo "ExecStart=/var/www/html/tcpstatmysql/bash/tcpdetail.sh $iface" >> /lib/systemd/system/tcpdump$iface.service
echo "" >> /lib/systemd/system/tcpdump$iface.service
echo "[Install]" >> /lib/systemd/system/tcpdump$iface.service
echo "WantedBy=multi-user.target" >> /lib/systemd/system/tcpdump$iface.service

Donc je le lance pour mes 2 interfaces : enp2s0 et enp3s0
sh instserv.sh enp2s0
sh insrserv.sh enp3s0

Maintenant j’ai mes deux services qui sont prêt :

/lib/systemd/system/tcpdumpenp2s0.service et /lib/systemd/system/tcpdumpenp3s0.service

On peut les démarrer comme ceci :

systemctl start tcpdumpenp2s0.service

On peut les arrêter comme ceci :

systemctl stop tcpdumpenp2s0.service

Connaitre leur statut comme ceci :

systemctl status tcpdumpenp2s0.service

Les rendre démmarrable automatiquement comme ceci :

systemctl enable tcpdumpenp2s0.service

Les rendre inopérant au démarrage comme ceci :

systemctl disable tcpdumpenp2s0.service

Idem pour enp3s0

Impact sur les performances

Quand je suis parti à réaliser cela, j’avais bien conscience des impacts possibles sur les performances et j’étais prêt à arrêter ou à choisir une autre voie si cela impactait trop mon serveur. Comme je l’ai dis, j’ai été très agréablement surpris, pourtant, c’est loin d’être un foudre de guerre (8Go de DDR2, et un ancien processeur AMD bi coeur, il supporte 4 sites web, 10 bases de données Firebird, 4 bases de données MySQL, du ftp et un paquet de traitements en crontab)

J’ai pris une copie d’écran de top au moment ou le pire est à venir (le moment où on remplit la table MySQL), la voici, sh est le script de remplissage et mysqld, le service mysql

 

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.