--[ Fonctionnalités avancées (des règles) IP Filter ]-- (mis à jour le 28 juillet 2003) IP Filter est un des "firewall" les plus connus sous Unix. Il est disponible sous les systèmes BSD de façon native (Afin de ne froisser personne, signalons simplement qu'OpenBSD dispose de son propre filtre compatible avec IP Filter, qui s'appelle pf et dont certaines fonctionnalités diffèrent). Il est également de plus disponible sous Solaris, HP-UX, IRIX. Sa qualité de filtrage, sa syntaxe limpide et sa gestion des états (statefull) n'est plus à démontrer. Pour plus de détails si vous n'êtes pas déjà familier avec IP Filter, voir : http://www.ipfilter.org/ et http://www.obfuscation.org/ipf/ Nous allons nous intéresser ici à des mots-clefs méconnus ou trop peu souvent utilisés pour écrire les règles ipfilter - count - Il est possible d'utiliser count au lieu de pass ou block. Il s'agit de réaliser de l'ip accounting très fin, en fonction des adresses/ports source et destination par exemple, ou par interface. Le résultat est visible avec l'utilitaire ipfstat : root@shiva:~# ipfstat -aio 415070912 count out on ppp0 from any to any 131476203 count in on ppp0 from any to any Il est ensuite facile d'utiliser ces statistiques au moyen d'un script pour en faire des graphes MRTG ou RRD-Tools. - call - Il s'agit ici d'une fonction "pas tellement" documentée et difficile d'accès d'IP Filter. Elle n'est d'ailleurs pas présente dans le parseur. Il s'agit d'ap- peler un syscall directement si la règle est matchée, et provoquer ainsi une action dans le noyau. Ce peut être un reboot (c'est assez dangereux ;-) ou plus sérieusement des fonctions écrites spécifiquement en module. Pour s'en servir, prenez un grand bol de café, et plongez vous dans le code de Darren. - skip n - Si cette règle est matchée, les n règles suivantes sont oubliées par ipf. Ces règles sont utiles pour ouvrir un flux "à la demande" par exemple, mais de façon beaucoup moins efficace que les fonctions d'authentification, ou peut trouver des applications particulières. - auth - Le paquet est gardé un moment et est envoyé à un programme userland. IP Filter le laissera passer en fonction du retour de ce programme. Il peut alors demander une confirmation, un mot de passe, vérifier l'heure, lancer un programme spécial, etc. Avec la règle suivante : auth in quick proto tcp from 192.168.1.1/32 to 192.168.1.2/32 \ port = 6667 flags S/SA keep state Il faudra avant lancer un programme (ici qui demande simplement d'autoriser ou pas, disponible en exemple dans la distribution IP Filter ) : root@polom:~% ./userauth 192.168.1.1 port 1694 -> 192.168.1.2 port 6667 Allow packet through ? [y/n]answer = y (100a), id 33829 idx 0 y Un petit programme sans prétention permet d'accéder (ici dans cette exemple au service IRC) avec des heures prédéfinies : root@polom:~% ./checkhour 4 18 192.70.106.86 port 3092 -> 192.70.106.68 port 6667 heure : 17 => ok. (le programme uuencodé est disponible à la fin de cette brève) - preauth- Preauth a un fonctionnement assez similaire, mais tout se joue avec les règles. Une règle de ce type : preauth in log quick proto tcp from any to 192.168.106.98/32 port = 5000 keep state Demande au filtre de regarder dans la liste de règle d'authentification, laquelle est remplie de la même manière, avec par exemple : echo "pass in quick proto tcp from 192.168.1.1/32 to any port = 5000" | ipf -Pf - Notez bien le -P, qui indique à IP Filter de travailler sur le set de règles *temporaires* (visible avec ipfstat -Aio), c'est à dire sur /dev/ipauth. Le renseignement de cette règle peut être fait par un administrateur, avec son shell unix, comme avec Lock n' Key de Cisco. On peut imaginer également qu'un programme le remplisse en fonction de conditions extérieures, de la même manière qu'avec auth... Les règles entrées avec -P restent actives pendant un temps réglable (sysctl) : net.inet.ipf.fr_defaultauthage: 600 (beaucoup de paramètres sont réglables via sysctl, voir `sysctl -a | grep ipf`) - dup-to - copie des paquets sur une autre interface, avec changement d'adresse IP possible : pass in quick on ed0 dup-to rl0 proto tcp all flags S/SA Fait la fonction de "copie" vers l'interface rl0 où on place typiquement un sniffeur ou un système de détection d'intrusion. On sélectionne au moyen de règles les flux à utiliser pour réaliser la détection d'intrusion. pass in quick on ed0 dup-to rl0:10.0.1.134 proto tcp all flags S/SA Copie de tout les paquets vers l'adresse IP 10.0.1.134 sur l'interface rl0, par exemple une machine de centralisation de la journalisation où l'on désire garder des traces de flux réseaux. [Attention cette fonctionnalité semble causer des problèmes sur certains systèmes] - filtrage sur le TOS ou le TTL - Prenons un cas simple : Je refuse que les traceroute passent sur mon réseau, pour des raisons qui me sont personnelles et dont il n'est pas ici le lieu de discuter. J'ai déjà filtré les ICMP, et les ports UDP, sauf ceux dont j'ai besoin bien entendu. La méthode du traceroute par TCP par exemple, sur un port ouvert (typi- quement un service comme ... au hasard le Mail ou le Web) laissera le petit curieux découvrir mon réseau. Je peux alors, par excès de paranoïa (nécessaire parfois) bloquer tout les paquets dont le TTL est 1. Ainsi, tout les types de traceroute IP ou certains types d'at- taques avec TTL courts seront bloqués. block in log quick on ed2 ttl 1 --[ Journalisation ]-- Le mot clef "log" dans une règle provoque la journalisation du header du paquet matché par celle-ci. Une fonctionnalité intéressante d'ipfilter est que celui-ci n'est journalisé que si le device de journalisation (/dev/ipl) n'est pas trop occupé, c'est à dire si le programme de lecture de journalisation, indépendant du filtre (man 8 ipmon), est capable de récupérer le flux de données. Si celui-ci est trop important, le filtre continue de fonctionner mais plus la journalisation. Cette séparation est AMHA une fonctionnalité très importante d'IP Filter. Cependant, si la journalisation est indispensable, il est possible d'utiliser "log or-block". Une telle règle se transformera en "block" si la journalisation n'est plus possible. Deux autres fonctions peuvent révéler de l'intérêt : - log body - Journalise le "payload" du paquet, enfin, juste les 128 premiers octets. Ce peut être utile, mais cette opération est souvent mieux réalisée par des sniffers comme snort ou tcpdump. Si votre but est uniquement de justifier à votre patron la taille de votre partition /var, vous pouvez également jeter un coup d'oeil aux possibilités de journalisation "verbose" de postfix avec TLS ;-) Voici par exemple le dump de deux paquets correspondant à une connexion IRC : $ ps auxw | grep ipmon root 153 0.0 0.2 1084 69 ?? Ss 2Oct01 1:59.11 /sbin/ipmon -Dsx (note: les lignes de log ont été découpées pour une meilleure lecture) Oct 13 20:01:04 polom ipmon[62199]: 20:01:03.727088 ed1 @65535:0 p 192.168.1.1,1594 -> 192.168.1.2,6667 PR tcp len 20 76 -AP K-S IN Oct 13 20:01:04 polom ipmon[62199]: 45 00 4c 00 1a d7 00 40 40 06 9c 81 c0 a8 01 01 Oct 13 20:01:04 polom ipmon[62199]: c0 a8 01 02 06 3a 1a 0b 1d 60 13 19 68 c5 5a cf Oct 13 20:01:04 polom ipmon[62199]: 80 18 82 18 a1 12 00 00 01 01 08 0a 06 ab 9c 64 Oct 13 20:01:04 polom ipmon[62199]: 05 05 60 e1 50 52 49 56 4d 53 47 20 23 74 65 73 Oct 13 20:01:04 polom ipmon[62199]: 74 20 3a 6d 65 73 73 61 67 65 0d 0a t :message.. Oct 13 20:01:04 polom ipmon[62199]: 20:01:03.823946 ed1 @65535:0 p 192.168.1.2,6667 -> 192.168.1.1,1594 PR tcp len 20 52 -A K-S IN Oct 13 20:01:04 polom ipmon[62199]: 45 00 34 00 9b b2 00 40 40 06 00 00 c0 a8 01 02 Oct 13 20:01:04 polom ipmon[62199]: c0 a8 01 01 1a 0b 06 3a 68 c5 5a cf 1d 60 13 31 Oct 13 20:01:04 polom ipmon[62199]: 80 10 21 1c b2 a1 00 00 01 01 08 0a 05 05 63 2c Oct 13 20:01:04 polom ipmon[62199]: 06 ab 9c 64 ...d - log first - Il est conseillé d'utiliser "first" en même temps que keep. En effet, "first" a pour but de ne journaliser le premier paquet uniquement et pas ceux que le filtre laisse passer parce qu'il correspond à un état présent dans la table. avec une règle du type : pass in log quick proto tcp from 192.168.1.1/32 to 192.168.1.2/32 \ port = 6667 flags S/SA keep state Oct 13 20:04:11 polom ipmon[62207]: 20:04:10.945080 ed1 @0:1 p 192.168.1.1,1595 -> 192.168.1.2,6667 PR tcp len 20 60 -S K-S IN Oct 13 20:04:11 polom ipmon[62207]: 20:04:10.945518 ed1 @65535:0 p 192.168.1.2,6667 -> 192.168.1.1,1595 PR tcp len 20 60 -AS K-S IN Oct 13 20:04:11 polom ipmon[62207]: 20:04:10.946585 ed1 @65535:0 p 192.168.1.1,1595 -> 192.168.1.2,6667 PR tcp len 20 52 -A K-S IN Oct 13 20:04:11 polom ipmon[62207]: 20:04:10.947866 ed1 @65535:0 p 192.168.1.1,1595 -> 192.168.1.2,6667 PR tcp len 20 111 -AP K-S IN Oct 13 20:04:11 polom ipmon[62207]: 20:04:11.046869 ed1 @65535:0 p 192.168.1.2,6667 -> 192.168.1.1,1595 PR tcp len 20 52 -A K-S IN Oct 13 20:04:11 polom ipmon[62207]: 20:04:11.047994 ed1 @65535:0 p 192.168.1.1,1595 -> 192.168.1.2,6667 PR tcp len 20 62 -AP K-S IN etc, etc. avec maintenant : pass in log first quick proto tcp from 192.168.1.1/32 to 192.168.1.2/32 \ port = 6667 flags S/SA keep state Une seule ligne dans les journaux : Oct 13 20:05:43 polom ipmon[62207]: 20:05:42.902247 ed1 @0:1 p 192.168.1.1,1596 -> 192.168.1.2,6667 PR tcp len 20 60 -S K-S IN --[ Annexe : programme d'exemple ]-- begin 644 checkhour.c.gz M'XL("+U]V3L``V-H96-K:&]UK$2E1$!7$FN"V;[?^CU-3/N]Y7E M_=Q`]H*5YC^+/'$GUF4AZ-`9,P;CS(3((`BLKBQ<&"'>S,_@)+CA''IC2"IK M$FMX8N]MPK5R1EXGLLQEX81)E'`2_Q+H:>`KP6]7NC+?5WT>=)(`@E^DXD6% M&5]3%'=?"MM?#9_`5O-;X7;QG"M7[%.EYGNPRZ3>@PIYO8MM"I9J#T]DOHLY MN1:$!$D'5H)EPE@83WL7OG7`QK;44)8IU^N28?GA+HQ"[6&LYH3CT\>HIUL'/ M$@;0KC=SDTJ5Z]3AAE0-CJY@'FX(9>I:N.UWI>H-\1\6CYM42)XUBY)9BTN2 M!L.)4J,;OZ=W:^@XM!=2@A:JYHV`9PQ;"T?RH6B$ET)9E/`K(.P,>=&"94JZ M^_J(A9/8D0;P;`"_QH"]MTJ#9>11N+3L1L`)/+=P2ZW-!JF%*2]FZ62Y^'-Y MCEE:HK#B,&=\Y2FXB1)]XT8ZG/AFX*&DP#0H7FK/!XNZ;MQ/0O M)5DG`Q@,@6KP!WM#MT[IV6KZB'91&`)S6D;>55@FM-N`/(`GI^'U(][+3W'= M=WW+QX\=T&!'OK^F.,(&@^/?0GW;]R8^"1GG`HF94%)D'JL5(:'K$.3*/4M] M\9YZ\VYR^G:3%!X?.:[GZ="AZ6@^IS.'39[+_N&[/13J[?GY=+X8+;SU'^"@ M^6OFU>3]:'%Z2;RFN?U)G&TG\=FFYQ(?3FVB<$L)ZW'':6\DQ9\!Y'0A]$_L =`&^=W@;PWXB[B5"_G;WMU%.@A^!_6N31/(`'```` ` end -- Nicolas Jombart $Id: ipfilter.tip,v 1.7 2003/07/28 07:33:30 jombart Exp $