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