Première rédaction de cet article le 10 avril 2007
Dernière mise à jour le 19 décembre 2011
Aujourd'hui, il n'est plus pensable de connecter un serveur à Internet sans qu'il soit protégé par un coupe-feu. Shorewall est un moyen assez simple de configurer un coupe-feu sur Linux.
Il existe de nombreuses sortes de coupe-feu et de nombreuses façons de les configurer. Par exemple, sur Linux, le coupe-feu de base est Netfilter et se programme avec des commandes shell (iptables), pour lesquelles on dispose de toute la puissance de ce langage.
Mais ce système a des limites. Par exemple, certains souhaitent une interface graphique plus facile à utiliser et il en existe beaucoup. D'autres ont des routeurs de plusieurs modèles à gérer et ils souhaitent un langage qu'on puisse traduire automatiquement en Netfilter, IOS ou autre selon le modèle de routeur (actuellement, seul hlfl est sur ce créneau). D'autres ont un réseau un peu complexe, avec plusieurs points d'entrée, et souhaitent centraliser la politique de filtrage en un seul groupe de fichier, un programme de routage produisant ensuite les règles de filtrage pour chaque machine (seul netspoc occupe ce créneau). Le projet genice, de Vincent Archer, visait à répondre à ces deux dernières demandes mais n'a hélas pas débouché. J'ai gardé le code, si quelqu'un est intéressé.
Ma demande était plus modeste : protéger une machine Linux, un
serveur connecté à Internet derrière un routeur que je ne contrôle pas
et sur lequel je ne pouvais donc pas compter. J'aurai pu faire du
Netfilter à la main mais c'était l'occasion
d'utiliser Shorewall et c'est en effet très
simple. Avec seulement la configuration suivante (largement copiée du
fichier Samples/one-interface
livré avec
Shorewall), j'ai un coupe-feu filtrant qui marche.
# Zones : # On définit les zones entre lesquelles on filtre. Ici, le coupe-feu # lui-même et l'Internet, tout le reste. fw firewall net ipv4 # Interfaces : # Quelle interface connecte les deux zones ? Ici, eth0. Notez les # options à la fin. net eth0 detect norfc1918,routefilter,tcpflags,logmartians,nosmurfs # Policy: # Quelle politique par défaut. Notez le $FW, qui référence la zone # configurée plus tôt. Ici, par défaut, tout ce qui vient du coupe-feu # est accepté, tout ce qui y arrive est refusé. $FW net ACCEPT net $FW DROP info net all DROP info all all REJECT info # Rules: # Les exceptions à la politique par défaut. Le serveur/coupe-feu étant # un serveur HTTP, DNS et SMTP, on autorise ces protocoles. # SSH ACCEPT net fw tcp 22 # SMTP ACCEPT net fw tcp 25 # Web ACCEPT net fw tcp 80 ACCEPT net fw tcp 443 # DNS ACCEPT net fw tcp 53 ACCEPT net fw udp 53 # ping ACCEPT net fw icmp 8
(Note sur la syntaxe : on peut aussi utiliser des macros Shorewall qui permettent de
simplifier certaines définitions. Ainsi, Web/ACCEPT net
fw
utilise la macro Web
qui met
automatiquement deux règles, pour les ports 80 et 443.)
Le premier méchant attrapé a été enregistré :
Apr 10 16:09:04 munzer Shorewall:net2fw:DROP:IN=eth0 OUT= MAC=00:16:3e:29:6c:26:00:30:48:8b:84:35:08:00 SRC=55.X.Y.Z DST=208.X.Y.Z LEN=401 TOS=0x00 PREC=0x00 TTL=55 ID=34299 PROTO=UDP SPT=30757 DPT=1026 LEN=381
J'ai masqué son adresse IP car il s'agissait d'un paquet UDP, donc pas authentifié, même faiblement. Peut-être répondait-il tout simplement à un pirate qui usurpait mon adresse IP.
On peut ensuite regarder les statistiques, en demandant l'affichage
de la chaîne net2fw
(avec Netfilter, les règles
de filtrage sont regroupées en chaînes). Au bout de quelques jours sur
un petit serveur :
% sudo iptables -v -L net2fw Chain net2fw (1 references) pkts bytes target prot opt in out source destination 411K 163M ACCEPT all -- any any anywhere anywhere state RELATED,ESTABLISHED 12 720 ACCEPT tcp -- any any anywhere anywhere tcp dpt:6322 11477 588K ACCEPT tcp -- any any anywhere anywhere tcp dpt:smtp 1500 89572 ACCEPT tcp -- any any anywhere anywhere tcp dpt:imap2 296 17736 ACCEPT tcp -- any any anywhere anywhere tcp dpt:imaps 381 19432 ACCEPT tcp -- any any anywhere anywhere tcp dpt:pop3 2 112 ACCEPT tcp -- any any anywhere anywhere tcp dpt:pop3s 1259 165K ACCEPT icmp -- any any anywhere anywhere icmp echo-request 1196 68996 ACCEPT tcp -- any any anywhere anywhere tcp dpt:www 808 45296 ACCEPT tcp -- any any anywhere anywhere tcp dpt:https 4206 287K ACCEPT udp -- any any anywhere anywhere udp dpt:domain 11 664 ACCEPT tcp -- any any anywhere anywhere tcp dpt:domain 60921 7430K Drop all -- any any anywhere anywhere 1617 79082 LOG all -- any any anywhere anywhere LOG level info prefix `Shorewall:net2fw:DROP:'
Notez le nombre de paquets jetés sans être signalés (car tellement fréquents qu'ils rempliraient les journaux).
Shorewall permet aussi de gérer facilement des listes
noires. Ainsi, je peux mettre dans le fichier
blacklist
ces machines qui s'obstinent à utiliser
mon serveur HTTP comme relais :
89.149.208.216/29 94.75.221.71 78.25.59.4
, je vérifie que mon fichier interfaces
contient bien l'option blacklist
:
net eth0 detect norfc1918,routefilter,dhcp,tcpflags,logmartians,nosmurfs,blacklist
je fais un /etc/init.d/shorewall refresh
et ces trois machines (la première règle porte sur un réseau, donc plusieurs machines) sont
désormais complètement interdites d'accès, ce que je peux vérifier avec iptables :
% sudo iptables -n -v -L blacklst Chain blacklst (2 references) pkts bytes target prot opt in out source destination 81 3888 DROP all -- * * 89.149.208.216/29 0.0.0.0/0 57 2736 DROP all -- * * 94.75.221.71 0.0.0.0/0 159 7632 DROP all -- * * 78.25.59.4 0.0.0.0/0
Cela, c'était pour IPv4. En 2011, on veut
aussi se prémunir contre d'éventuelles attaques sur IPv6. Shorewall
permet également de générer des règles pour
ip6tables
. Cela se fait avec le
paquetage shorewall6 dont les fichiers de configuration sont quasiment
les mêmes qu'avec IPv4 (par contre, il n'existe pas de mécanisme pour
synchroniser les deux configurations, v4 et v6, c'est à vous de le
faire à la main). Parmi les différences :
norfc1918
,ipv6-icmp
(ou bien le nom qui figure dans votre
/etc/protocols
, ou encore la valeur numérique,
58). Et les types n'ont pas les mêmes valeurs en v4 et v6 (par
exemple, la demande
d'écho, utilisée par ping, vaut 8 en v4 et 128
en IPv6).Une fois shorewall6 lancé, vous pouvez voir les règles :
% sudo ip6tables -n -L net2fw|more Chain net2fw (1 references) target prot opt source destination blacklst all ::/0 ::/0 ctstate INVALID,NEW smurfs all ::/0 ::/0 ctstate INVALID,NEW tcpflags tcp ::/0 ::/0 ACCEPT all ::/0 ::/0 ctstate RELATED,ESTABLISHED ACCEPT tcp ::/0 ::/0 tcp dpt:9922 ACCEPT tcp ::/0 ::/0 tcp dpt:80 ACCEPT tcp ::/0 ::/0 tcp dpt:443 ...
Est-ce qu'un pare-feu IPv6 sert à quelque chose aujourd'hui ? L'examen des compteurs semble indiquer que non, pas pour l'instant. Après plusieurs heures :
% sudo ip6tables -v -n -L net2fw|more ... 1223 84896 ACCEPT tcp * * ::/0 ::/0 tcp dpt:80 ... 2 632 DROP all * * ::/0 ::/0
Deux tentatives de passer outre, alors qu'IPv4 en a vu 3958 dans le même temps !
Avec ces règles, mon serveur est désormais raisonnablement protégé. Il y a bien sûr d'autres règles dans les applications elles-mêmes (par exemple, la directive AllowUsers dans la configuration d'OpenSSH). Rappelez-vous que la sécurité ne repose pas sur un seul truc mais sur une politique cohérente, avec défense en profondeur (c'est-à-dire qu'un maillon qui casse ne doit pas entraîner l'ouverture complète des portes).
Version PDF de cette page (mais vous pouvez aussi imprimer depuis votre navigateur, il y a une feuille de style prévue pour cela)
Source XML de cette page (cette page est distribuée sous les termes de la licence GFDL)