Générer un bulletin de sécurité de votre passerelle ADSL
debian

Connectée en permanence à Internet, une passerelle ADSL subit en général de nombreuses attaques par jour, attaques qui ne sont en général pas perceptibles sans vérifier quotidiennement les journaux (logs) des différents services tournant sur la passerelle.

Dans ce document, nous expliquons comment générer un bulletin de sécurité quotidien qui fait la liste des attaques par service et envoie un mail quotidien de rapport de sécurité à une adresse spécifiée. Nous verrons aussi plusieurs manières d'automatiser son exécution.

Plan de ce document :

  1. Tour d'horizon et prérequis
  2. Automatisation de l'envoi de mail

Tour d'horizon et prérequis

Description du système :
Nous considérons que la passerelle ADSL propose les services suivants :

Les services écoutant les ports standards (le fait de changer le port d'écoute SSH de 22 à 6922 par exemple permet d'éliminer une bonne partie des tentatives d'attaques). Il est évidemment possible d'adapter le script pour lui ajouter la surveillance des journaux d'autres services (samba par exemple).

Nous allons écrire un script qui va chercher dans les fichiers de logs de ces services les traces d'erreur correspondant à une attaque malveillante, et correspondant au jour de l'exécution du script. Voici donc la liste des fichiers auxquels nous allons nous intéresser :

1 - Création du script

Créez le script suivant avec vi ou emacs, par exemple dans le fichier /root/scripts/makereport.sh. Remplaçez l'adresse email à laquelle est envoyée le rapport par une adresse email de préférence externe. Il faut ensuite rendre ce script exécutable en faisant un chmod +x /root/scripts/makereport.sh. Vous pouvez dès à présent tester si le script fonctionne en le lançant manuellement, en tapant /root/scripts/makereport.sh.

#!/bin/bash

# la date d'aujourd'hui
aujourdhui=`date +"%b %e"`

# au cas où les fichiers n'existent pas ?
touch /var/log/vsftpd.log
touch /var/log/auth.log
touch /var/log/apache/error.log

# Début du rapport
echo "Rapport de sécurité du $aujourdhui" > /tmp/report.txt
echo "-----------------------------" >> /tmp/report.txt

echo "" >> /tmp/report.txt
echo ".:: VSFTPD [port 21] ::." >> /tmp/report.txt

cat /var/log/vsftpd.log | grep "FAIL" | grep -i "$aujourdhui" >> /tmp/report.txt

echo "" >> /tmp/report.txt
echo ".:: SSHD [port 22] ::." >> /tmp/report.txt

cat /var/log/auth.log | grep "sshd" | grep "Failed" | grep -i "$aujourdhui" >> /tmp/report.txt
cat /var/log/auth.log | grep "sshd" | grep "Excess" | grep -i "$aujourdhui" >> /tmp/report.txt
cat /var/log/auth.log | grep "sshd" | grep "Invalid" | grep -i "$aujourdhui" >> /tmp/report.txt
cat /var/log/auth.log | grep "sshd" | grep "failure" | grep -i "$aujourdhui" >> /tmp/report.txt

echo "" >> /tmp/report.txt
echo ".:: HTTPD [port 80] ::." >> /tmp/report.txt

cat /var/log/apache/error.log | grep "error" | grep -i "$aujourdhui" >> /tmp/report.txt

echo "" >> /tmp/report.txt

echo ".:: DIVERS ::." >> /tmp/report.txt

cat /var/log/auth.log | grep "su" | grep "failure" | grep -i "$aujourdhui" >> /tmp/report.txt

echo "" >> /tmp/report.txt
echo "---------------" >> /tmp/report.txt
echo "Fin du rapport." >> /tmp/report.txt

# Mail du rapport
cat /tmp/report.txt | mailx -s "Rapport de securite" email.admin@serveur-exterieur.com

# Suppression du rapport
rm /tmp/report.txt

exit 0

Quelques remarques :

2 - Bugs et améliorations :

Selon la configuration de votre machine, il est possible que le script présente quelques bogues :

En effet, la date des fichiers de logs est (du moins dans mon cas) écrite en anglais (ex: 'Jul 26'). En revanche, la commande date renverra une date dans le format local (par exemple dans le cas fr_FR : 'juil 26'). Pour forcer le format US, il est nécessaire d'ajouter la commande suivante au début du script :

export LC_TIME=en_US

Dans mon cas, le bug était vicieux car quand le script était lancé manuellement, la date en_US était générée, alors que lorsque le cron l'exécutait, c'était le format fr_FR qui était pris en compte.

Automatisation de l'envoi de mail

Pour rendre ce script autonome, il faut en automatiser son exécution à l'aide du cron.

Le cron est un démon qui permet l'exécution de scripts à certains horaires. Chaque utilisateur a une table de cron qui lui permet de lancer de tels scripts en son nom même s'il n'est pas connecté à la machine. Nous allons modifier la table cron de root en tapant, en tant que root, crontab -e. Tapez alors :

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/

55 23 * * * /root/scripts/makereport.sh

Ceci permettra l'exécution du script tous les jours à 23h15. Ainsi, tous les événements suspects loggués le jour même seront récupérés. Cependant cette tactique peut ne pas être adaptée si par exemple votre passerelle n'est pas toujours allumée (c'est le cas notamment si vous utilisez le script d'extinction automatique présenté ailleurs sur ce site). Voici une méthode qui permet d'utiliser ce script en même temps que l'extinction automatique :

Premièrement, on ne place pas d'entrée dans la crontab mais on commande l'exécution de ce script au sein du script d'exécution automatique, juste avant l'appel de la commande poweroff.

Ensuite, on modifie le code du script pour la génération de la date de façon à ce que si la machine s'éteint juste après minuit, le rapport de la veille soit généré (ici, ce sera le cas jusqu'à 6 heures du matin, à vous d'adapter l'heure à vos habitudes) :

# on génère le rapport du bon jour en fonction
# de l'heure d'éxécution du script.
if [ `date +"%H"` -gt 6 ]; then
	aujourdhui=`date +"%b %e"`
else
	aujourdhui=`date --date=yesterday +"%b %e"`
fi

Voici finalement à quoi ressemble le script :

#!/bin/bash

# pour avoir le format de date anglais correct
export LC_TIME=en_US

# on génère le rapport du bon jour en fonction
# de l'heure d'éxécution du script.
if [ `date +"%H"` -gt 6 ]; then
	aujourdhui=`date +"%b %e"`
else
	aujourdhui=`date --date=yesterday +"%b %e"`
fi

# au cas où les fichiers n'existent pas ?
touch /var/log/vsftpd.log
touch /var/log/auth.log
touch /var/log/apache/error.log

# Début du rapport
echo "Rapport de sécurité du $aujourdhui" > /tmp/report.txt
echo "-----------------------------" >> /tmp/report.txt

echo "" >> /tmp/report.txt
echo ".:: VSFTPD [port 21] ::." >> /tmp/report.txt

cat /var/log/vsftpd.log | grep "FAIL" | grep -i "$aujourdhui" >> /tmp/report.txt

echo "" >> /tmp/report.txt
echo ".:: SSHD [port 22] ::." >> /tmp/report.txt

cat /var/log/auth.log | grep "sshd" | grep "Failed" | grep -i "$aujourdhui" >> /tmp/report.txt
cat /var/log/auth.log | grep "sshd" | grep "Excess" | grep -i "$aujourdhui" >> /tmp/report.txt
cat /var/log/auth.log | grep "sshd" | grep "Invalid" | grep -i "$aujourdhui" >> /tmp/report.txt
cat /var/log/auth.log | grep "sshd" | grep "failure" | grep -i "$aujourdhui" >> /tmp/report.txt

echo "" >> /tmp/report.txt
echo ".:: HTTPD [port 80] ::." >> /tmp/report.txt

cat /var/log/apache/error.log | grep "error" | grep -i "$aujourdhui" >> /tmp/report.txt

echo "" >> /tmp/report.txt

echo ".:: DIVERS ::." >> /tmp/report.txt

cat /var/log/auth.log | grep "su" | grep "failure" | grep -i "$aujourdhui" >> /tmp/report.txt

echo "" >> /tmp/report.txt
echo "---------------" >> /tmp/report.txt
echo "Fin du rapport." >> /tmp/report.txt

# Mail du rapport
cat /tmp/report.txt | mailx -s "Rapport de securite" email.admin@serveur-exterieur.com

# Suppression du rapport
rm /tmp/report.txt

exit 0