Table des matières Page précédente Page suivante Version mono-page

III-9 Log (LOG / ULOG)

Jusqu'à présent, nous avons vu comment configurer nos règles avec Netfilter : définir les cibles par défaut, et supprimer des paquets. Mais à force de tout supprimer, il nous est difficile de connaître l'efficacité de notre firewall, et si il est intéressant de rajouter ou de supprimer des règles. D'où l'intérêt de logger certaines informations.

Dans ce qui suit, nous allons utiliser l'affreux anglicisme "logger" qui décrit l'action de stocker dans un "log" une certaine information.

III-9-1 LOG

C'est la méthode la plus standard pour logger des trames. Il s'agit simplement de créer une règle "iptables" dont la cible ("-j [cible]") n'est pas "ACCEPT" ou "DROP", mais tout simplement "LOG". Si nous reprenons le script "iptables-conntrack-1.sh", nous pouvons par exemple rajouter une dernière règle qui va logger tout ce qui na pas été accepté par la chaîne "INPUT". C'est très pratique, car ainsi nous serons avertis de tout ce qui tente d'accéder aux processus utilisateurs de notre système. Pour cela, nous rajoutons cette règle en temps que dernière règle de la chaîne "INPUT" :
[root@phoenix /]# iptables -t filter -A INPUT -j LOG
Téléchargez Vous pouvez télécharger ici un exemple de script utilisant la cible LOG. Comme Netfilter est un élément du Kernel, ses logs sont donc des logs de ce dernier. Et comme tout bon log Kernel, ils se retrouve dans le fichier "/var/log/messages". Ainsi, si pirate.internet.net fait un "nmap" sur les ports HTTP et HTTPS de Phoenix, nous aurons :
[intrus@pirate /]# nmap phoenix1.internet.net -p 80,443

Starting nmap V. 3.00 ( www.insecure.org/nmap/ )
Note: Host seems down. If it is really up, but blocking our ping probes, try -P0
Nmap run completed -- 1 IP address (0 hosts up) scanned in 30 seconds
[root@phoenix /]# tail -14 /var/log/messages
Jul  8 23:04:59 phoenix nmbd[2178]: [2003/07/08 23:04:59, 0] nmbd/nmbd_packets.c:send_netbios ...
Jul  8 23:04:59 phoenix nmbd[2178]:   send_netbios_packet: send_packet() to IP 10.255.255.255 ...
Jul  8 23:04:59 phoenix nmbd[2178]: [2003/07/08 23:04:59, 0] nmbd/nmbd_namequery.c:query_name(256) 
Jul  8 23:04:59 phoenix nmbd[2178]:   query_name: Failed to send packet trying to query name ...
Jul  8 23:07:03 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=28 TOS=0x00 PREC=0x00
                                TTL=38 ID=41593 PROTO=ICMP TYPE=8 CODE=0 ID=58020 SEQ=0 
Jul  8 23:07:03 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=40 TOS=0x00
                                TTL=39 ID=51459 PROTO=TCP SPT=53120 DPT=80 WINDOW=4096 ...
Jul  8 23:07:09 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=28 TOS=0x00
                                TTL=38 ID=2581 PROTO=ICMP TYPE=8 CODE=0 ID=58020 SEQ=256 
Jul  8 23:07:09 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=40 TOS=0x00
                                TTL=39 ID=27444 PROTO=TCP SPT=53121 DPT=80 WINDOW=4096 ...
Jul  8 23:07:15 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=28 TOS=0x00
                                TTL=38 ID=29887 PROTO=ICMP TYPE=8 CODE=0 ID=58020 SEQ=512 
Jul  8 23:07:15 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=40 TOS=0x00
                                TTL=39 ID=48409 PROTO=TCP SPT=53122 DPT=80 WINDOW=4096 ...
Jul  8 23:07:21 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=28 TOS=0x00
                                TTL=38 ID=37813 PROTO=ICMP TYPE=8 CODE=0 ID=58020 SEQ=768 
Jul  8 23:07:21 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=40 TOS=0x00
                                TTL=39 ID=17449 PROTO=TCP SPT=53123 DPT=80 WINDOW=4096 ...
Jul  8 23:07:27 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=28 TOS=0x00
                                TTL=38 ID=57294 PROTO=ICMP TYPE=8 CODE=0 ID=58020 SEQ=1024 
Jul  8 23:07:27 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=40 TOS=0x00
                                TTL=39 ID=64622 PROTO=TCP SPT=53124 DPT=80 WINDOW=4096 ...
Grâce au log, on voit que phoenix1.internet.net reçoit une série de commandes "ping" et de requêtes sur son port 80 de la part de pirate.internet.net. Évidement, comme Phoenix ne répond pas à ces requêtes, Pirate fait plusieurs essais, et finalement il ne testera même pas le port 443.

Un moyen pratique de suivre ses logs en temps réel est la commande, lancée en temps que root : "tail -f /var/log/messages". Cela affichera en permanence la fin de ce fichier de log. Pour l'arrêter, il suffit d'appuyer sur CTRL+C.

Mais ce fichier sert aussi (surtout !) à stocker tout les messages d'informations ou d'erreurs du Kernel. Il nous faut donc un moyen de retrouver ces messages de log Netfilter parmi tout les autres messages. On peut configurer avec le paramètre "--log-prefix [Message de log]" la règle de log afin qu'elle rajoute systématiquement des messages en début de log. Ainsi :
[root@phoenix /]# iptables -t filter -A INPUT -s 10.0.0.66 -j LOG --log-prefix "AttackPirate"
[root@phoenix /]# iptables -t filter -A INPUT -s 10.0.0.200 -j LOG --log-prefix "AttackWeb"
indiquera clairement les connexions faites par les machines pirate.internet.net et web.internet.net :
[intrus@pirate /]$ nmap -p 80 phoenix1.internet.net
[intrus@web /]$ nmap -p 80 phoenix1.internet.net
[root@phoenix /]# tail -f /var/log/messages
Jul  8 23:26:06 phoenix kernel: AttackPirate IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ...
Jul  8 23:26:06 phoenix kernel: AttackWeb IN=eth1 OUT= SRC=10.0.0.200 DST=10.0.0.1 ...
Jul  8 23:26:12 phoenix kernel: AttackPirate IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ...
Jul  8 23:26:12 phoenix kernel: AttackWeb IN=eth1 OUT= SRC=10.0.0.200 DST=10.0.0.1 ...
Jul  8 23:26:12 phoenix kernel: AttackPirate IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ...
Jul  8 23:26:12 phoenix kernel: AttackWeb IN=eth1 OUT= SRC=10.0.0.200 DST=10.0.0.1 ...
Jul  8 23:26:25 phoenix kernel: AttackPirate IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ...
Jul  8 23:26:28 phoenix kernel: AttackPirate IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ...
Jul  8 23:26:34 phoenix kernel: AttackPirate IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ...
Cependant, cette méthode de log a l'inconvénient que même avec des "--log-prefix", il reste difficile de séparer les messages de log de Netfilter des autres messages du Kernel. Comme en témoigne d'ailleurs le premier affichage du /var/log/message, où des messages de Samba (en début de log) sont mélangés aux messages de Netfilter.

Une autre méthode est de définir un "niveau de log" ("log level" en anglais), qui rajoute une autre information aux log, ce qui permet au demon de log (un programme appelé "syslogd") de stocker ces log dans un autre fichier. Par exemple, sur une Mandrake, on peut utiliser (voir "man syslogd", "man syslog.conf", "less /usr/include/sys/syslog.h" pour avoir plus d'informations sur ces commandes) :
[root@phoenix /]# iptables -t filter -A INPUT -j LOG --log-level 4
[root@phoenix /]# less /usr/include/sys/syslog.h
#define LOG_WARNING     4       /* warning conditions */
[root@phoenix /]# less /etc/syslog.conf
kern.=warn                     -/var/log/kernel/warnings
[intrus@pirate /]$ nmap -p 80 phoenix1.internet.net

Starting nmap V. 3.00 ( www.insecure.org/nmap/ )
Note: Host seems down. If it is really up, but blocking our ping probes, try -P0
Nmap run completed -- 1 IP address (0 hosts up) scanned in 60 seconds
[root@phoenix /]# tail -10 /var/log/kernel/warnings
Jul  8 18:55:43 phoenix kernel: MSDOS FS: Using codepage 850
Jul  8 19:26:34 phoenix kernel: i2c-amd756.o version 2.7.0 (20021208)
Jul  8 19:26:34 phoenix kernel: i2c-amd756.o: AMD768 bus detected and initialized
Jul  8 19:28:37 phoenix kernel: UDF-fs: No VRS found
Jul  8 23:53:58 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ...
Jul  8 23:54:01 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ...
Jul  8 23:54:07 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ...
Jul  8 23:54:10 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ...
Jul  8 23:54:13 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ...
Jul  8 23:54:19 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ...
Comme on le voit, bien que les log de Netfilter soient isolés dans un fichiers à part (/var/log/warnings), ce fichier n'en est pas moins partagé avec d'autres modules du Kernel, qui utilisent eux aussi le log Kernel de niveau 4 <=> Warning. Dans le précédent log, on voit notamment des logs de "MSDOS FS" et "i2c-amd756.0" qui n'ont rien à voir avec Netfilter.

On pourrait s'imaginer utiliser une autre entrée du syslog, afin de vraiment séparer ces log. Le seul problème, c'est que les log de Netfilter sont des log du Kernel, et qu'à ce titre, on sera toujours obligé de les déclarer en temps que "kern." dans le "/etc/syslog.conf".

Alors ? Stocker ces logs à part est vraiment une chose impossible sous Linux ? Non, heureusement que non ! La solution s'appelle ULOG, et nous allons la voir tout de suite.

III-9-2 ULOG

ULOG est un module du Kernel dont le développement a été fait par http://www.gnumonks.org/projects/. Il a été spécialement conçu pour recevoir les log de Netfilter. Il y a certaines (petites) contraintes à son utilisation :
  • Kernel récent : il faut un Kernel >= 2.4.18-pre8 pour pouvoir utiliser ce module.
  • Option de compilation : il faut que votre kernel soit compilé avec l'option CONFIG_IP_NF_TARGET_ULOG=m.
  • Une fois compilé, le module ipt_ULOG.o doit se trouver sur votre disque dur (/lib/modules/[version du kernel]/kernel/net/ipv4/netfilter/ipt_ULOG.o.gz par exemple) :
    [root@phoenix /]# find /lib/modules/`uname -r`/ -iname "*ULOG*"
    /lib/modules/2.4.21-0.13mdksmp/kernel/net/ipv4/netfilter/ipt_ULOG.o.gz
    
    Sur une distribution "Mandrake 9.1", tout ceci est fait par défaut.
  • Vous devez récupérer et installer le demon "ulogd" sur votre machine. Personnellement, j'ai téléchargé la version 1.21, et je l'ai compilé et installé dans mon "/usr/local/".
  • Téléchargez Il faut configurer le demon ulogd. Pour cela, il faut éditer son fichier de configuration. Vous pouvez utiliser le mien.
    Les 3 informations importantes sont :
    • de spécifier qu'ULOG doit stocker ses logs dans un fichier texte. Il faut pour cela utiliser le "plugin" "ulogd_LOGEMU.so" :
      # load the plugin
      plugin /usr/local/lib/ulogd/ulogd_LOGEMU.so
      
      ULOG peut aussi sauver les logs dans des bases de données MySQL (plugin "ulogd_MYSQL.so") ou PostgreSQL (plugin "ulogd_PGSQL.so"). Voir, il peut carrément sauver les paquets IP complets dans un fichier binaire (plugin "ulogd_OPRINT.so") afin par exemple de pouvoir les analyser à posteriori.
    • d'indiquer dans quel fichier ces logs doivent êtres stockés. Par défaut, il s'agit de "/var/log/ulogd.syslogemu" :
      # where to write to
      syslogfile /var/log/ulogd.syslogemu
      
    • Téléchargez Le demon ULOG ("ulogd") doit tourner sur votre machine. L'idéal est de le lancer au démarrage, en même temps que les autres demons de votre machine. A toute fin utile, voici le script de démarrage du demon ULOG que j'ai écris (un script similaire est fournit avec les sources du demon ULOG). Il se place dans le "/etc/init.d/". Pour le démarrer systématiquement, il faut créer un lien symbolique du "/etc/rc.d/rc3.d/S[un nombre]ulogd" ou du "/etc/rc.d/rc5.d/S[un nombre]ulogd" vers "/etc/init.d/ulog". Exemple :
      [root@phoenix scripts]# ls -la /etc/init.d/ulogd
      -rwxr--r--    1 root     root  1821 jui  9 00:30 /etc/init.d/ulogd
      [root@phoenix scripts]# ls -la /etc/rc.d/rc5.d/S10ulogd
      lrwxrwxrwx    1 root     root    15 mai  4 21:02 /etc/rc.d/rc5.d/S10ulogd -> ../init.d/ulogd
      
Une fois que tout ceci est mis en place :
  • Démarrez le demon ulog . Par exemple :
    [root@phoenix /]# /etc/rc.d/rc5.d/S10ulogd start
    
  • Vérifiez que le démon fonctionne correctement :
    [root@phoenix /]# cat /var/log/ulogd.log
    Wed Jul  9 00:50:27 2003 <3> ulogd.c:474 ulogd Version 1.00 starting
    Wed Jul  9 00:50:27 2003 <5> ulogd.c:688 initialization finished, entering main loop
    
  • Configurez Netfilter pour qu'il utilise la cible ULOG au lieu de la cible LOG. Ici, on log tout ce qui va être supprimé par la chaîne "INPUT" :
    [root@phoenix /]# iptables -t filter -A INPUT -p all -j ULOG --ulog-prefix DefaultDrop
    
    Téléchargez Téléchargez ici un exemple de script utilisant la cible ULOG.
  • Et attendez qu'un intrus vienne se frotter à votre Netfiler :
    [root@phoenix /]# tail -f /var/log/ulogd.syslogemu
    Jul  8 20:24:22 phoenix DefaultDrop IN=ppp0 OUT= MAC= SRC=xx.xx.xx.xx DST=62.147.74.21 LEN=61
                    TOS=00 PREC=0x00 TTL=60 ID=0 DF PROTO=UDP SPT=53 DPT=32796 LEN=41 
    Jul  8 20:24:22 phoenix DefaultDrop IN=ppp0 OUT= MAC= SRC=xx.xx.xx.xx DST=62.147.74.21 LEN=40
                    TOS=00 PREC=0x00 TTL=251 ID=0 DF PROTO=TCP SPT=110 DPT=33108 SEQ=0
                    ACK=1355878989 WINDOW=0 ACK RST URGP=0 
    Jul  8 20:24:32 phoenix DefaultDrop IN=ppp0 OUT= MAC= SRC=xx.xx.xx.xx DST=62.147.74.21 LEN=61
                    TOS=00 PREC=0x00 TTL=60 ID=0 DF PROTO=UDP SPT=53 DPT=32797 LEN=41 
    Jul  8 20:24:54 phoenix DefaultDrop IN=ppp0 OUT= MAC= SRC=xx.xx.xx.xx DST=62.147.74.21
                    LEN=61 TOS=00 PREC=0x00 TTL=60 ID=0 DF PROTO=UDP SPT=53 DPT=32799 LEN=41 
    Jul  8 20:25:04 phoenix DefaultDrop IN=ppp0 OUT= MAC= SRC=xx.xx.xx.xx DST=62.147.74.21
                    LEN=61 TOS=00 PREC=0x00 TTL=60 ID=0 DF PROTO=UDP SPT=53 DPT=32800 LEN=41 
    Jul  8 20:25:22 phoenix DefaultDrop IN=ppp0 OUT= MAC= SRC=xx.xx.xx.xx DST=62.147.74.21
                    LEN=78 TOS=00 PREC=0x00 TTL=104 ID=36090 PROTO=UDP SPT=1034 DPT=137 LEN=58 
    Jul  8 20:25:28 phoenix DefaultDrop IN=ppp0 OUT= MAC= SRC=xx.xx.xx.xx DST=62.147.74.21
                    LEN=40 TOS=00 PREC=0x00 TTL=251 ID=0 DF PROTO=TCP SPT=110 DPT=33220 SEQ=0
                    ACK=1428948021 WINDOW=0 ACK RST URGP=0 
    Jul  8 20:25:34 phoenix DefaultDrop IN=ppp0 OUT= MAC= SRC=xx.xx.xx.xx DST=62.147.74.21
                    LEN=61 TOS=00 PREC=0x00 TTL=60 ID=0 DF PROTO=UDP SPT=53 DPT=32802 LEN=41 
    Jul  8 20:25:38 phoenix DefaultDrop IN=ppp0 OUT= MAC= SRC=xx.xx.xx.xx DST=62.147.74.21
                    LEN=61 TOS=00 PREC=0x00 TTL=60 ID=0 DF PROTO=UDP SPT=53 DPT=32803 LEN=41 
    
    Ceci n'est qu'une simple portion de mon log de Netfilter, lors d'une connexion en RTC le 8 Juillet 2003. Remarquez le temps plutôt faible entre les accès. Il s'agit en fait de plusieurs "port scan" effectués par plusieurs machines... Et encore, mon Netfilter est configuré pour ne pas afficher les logs des requêtes P2P qui, bien que je n'aie aucun client P2P, inondent régulièrement ma machine...
Tout comme la cible LOG, la cible ULOG a des options intéressantes :
  • --ulog-prefix : préfixe des log. Même chose que pour "--log-prefix" de la cible LOG
  • --ulog-nlgroup : similaire à "--log-level" de la cible LOG
Conclusion : si vous voulez avoir des logs bien exploitables de votre Netfilter, utilisez ULOG plutôt que LOG. Ce n'est finalement pas si compliqué à installer, et c'est très pratique. Enfin, pour les maniaques de la sécurité qui ont plein de place disque et du CPU à revendre, vous pouvez spécifier au demon "ulogd" de stocker les paquets non pas dans un fichier, mais dans une base de donnés MySQL ou PostgreSQL.

III-9-3 Analyse des log

TODO

III-9-4 Une petite histoire le LOG, à lire au coin d'un mur de flammes...

... ou comment faire une belle boulette.

Avant de commencer, et pour bien clarifier la situation, le CRANS n'est nullement responsable de ce que je vais vous conter. L'histoire commence le 29 juin 2003, un dimanche après-midi ou je m'active sur mon Xemacs afin de terminer dans les temps la préparation de la conférence sur la sécurité et le firewall sous Linux que je dois présenter le mecredi suivant. J'en suis à l'explication de la commande "traceroute", et pour illustrer l'utilisation de cette commande, j'ai besoin d'utiliser une adresse IP d'une machine se trouvant sur Internet. Le hasard à voulu qu'à ce momment je jette un oeil sur les logs de mon firewall, et que je me dis que ce serait une bonne idée que d'utiliser l'adresse IP d'un des petit plaisantin qui s'est amusé à se frotter à ma machine. Je parcours brièvement mes logs, et je trouve ceci :
Jun 29 10:38:01 phoenix DefaultDrop IN=ppp0 OUT= MAC= SRC=138.231.136.6 DST=62.147.73.252 LEN=1500 TOS=00
PREC=0x00 TTL=53 ID=27588 DF PROTO=TCP SPT=80 DPT=32911 SEQ=3917595680 ACK=2040264177 WINDOW=6432 ACK URGP=0 
Jun 29 10:38:11 phoenix DefaultDrop IN=ppp0 OUT= MAC= SRC=138.231.136.6 DST=62.147.73.252 LEN=1500 TOS=00
PREC=0x00 TTL=53 ID=52061 DF PROTO=TCP SPT=80 DPT=32912 SEQ=3921241330 ACK=2054038667 WINDOW=6432 ACK URGP=0 
TODO

Table des matières Page précédente Page suivante Version mono-page
Valid XHTML 1.0! Valid CSS!
Site de référence : http://olivieraj.free.fr/ Last modified: Sun Jul 10 01:15:46 CEST 2005