Configuration de iptables pour une passerelle

bonsoir, après avoir lu quelques posts sur iptables, et le ‘truc et astuces pour les nuls’ j’ai donc essayé d’installer une passerelle sur mon réseau.

-> desactivation de la fonction routeur de la freebox.
-> installation d’un pc (P3 800Mhz - 500Mo SDRAM) avec trois cartes réseau entre la freebox et le switch.
-> debian etch - 2.6.18-6-686
-> cette machine fera office dans un premier temps de routeur, pare-feu, proxy (avec filtrage), apt-proxy, et NTP
-> ensuite j’y migrerai aussi les services DNS & DHCP qui sont deja installés sur une autre machine.
-> j’ai utilisé le script de fran.b pour lancer la config au démarage de la machine.
-> et j’ai donc pondu ma config pour iptables qui a l’air de marcher, mais je voulais savoir si vous n’y voyez pas un trou de sécurité ou une annerie grosse comme moi.

#
#	CONFIGURATION IPTABLES POUR LE FIREWALL
#
#	serveur de mail 	: hébergé sur le LAN (192.168.100.002) - smtp & https doivent être accessible depuis internet
#	serveur web    		: hébergé sur le LAN (192.168.100.004) - http doit être accessible depuis internet
#	
#	serveur dns      	: hébergé sur le LAN (192.168.100.001) mais à migrer sur le firewall	
#	serveur dhcp    	: hébergé sur le LAN (192.168.100.001) mais à migrer sur le firewall	
#	serveur ntp     	: hébergé sur le firewall	
#	serveur proxy   	: hébergé sur le firewall	
#	serveur apt-proxy	: hébergé sur le firewall	
#
#	eth0 : connectée sur le LAN - 192.168.100.254/24 
#	eth1 : connectée sur la freebox
#	eth2 : pas encore en service
#

# activation de l'ip forwarding
echo "1" > /proc/sys/net/ipv4/ip_forward

# MASQUERADE
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE

# par defaut tout est ferme
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

# la machine locale est sure
iptables -A INPUT  -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# anti scan	
iptables -X SCANS
iptables -N SCANS
iptables -A SCANS -p tcp --tcp-flags FIN,URG,PSH FIN,URG,PSH -j DROP
iptables -A SCANS -p tcp --tcp-flags ALL ALL                 -j DROP
iptables -A SCANS -p tcp --tcp-flags ALL NONE                -j DROP
iptables -A SCANS -p tcp --tcp-flags SYN,RST SYN,RST         -j DROP
iptables -A INPUT -j SCANS

# paquets des connexions existantes autorisees
iptables -X KEEP_STATE
iptables -N KEEP_STATE
iptables -A KEEP_STATE -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A KEEP_STATE -m state --state INVALID -j DROP
iptables -A INPUT -j KEEP_STATE
iptables -A OUTPUT -j KEEP_STATE
iptables -A FORWARD -j KEEP_STATE

# services hebergés par la machine locale accessibles depuis eth0
iptables -A INPUT -m state --state NEW -p tcp --dport 123  -i eth0 -j ACCEPT 					
iptables -A INPUT -m state --state NEW -p tcp --dport 22   -i eth0 -j ACCEPT 					
iptables -A INPUT -m state --state NEW -p tcp --dport 3128 -i eth0 -j ACCEPT 					
iptables -A INPUT -m state --state NEW -p tcp --dport 9999 -i eth0 -j ACCEPT 					
iptables -A INPUT -m state --state NEW -p icmp -i eth0 -j ACCEPT						

# services hebergés par la machine locale qui communiquent vers eth0
iptables -A OUTPUT -m state --state NEW -p icmp -o eth0 -j ACCEPT						
iptables -A OUTPUT -m state --state NEW -p udp --dport 53 -d 192.168.100.001 -o eth0 -j ACCEPT			
iptables -A OUTPUT -m state --state NEW -p tcp --dport 53 -d 192.168.100.001 -o eth0 -j ACCEPT			
iptables -A OUTPUT -m state --state NEW -p tcp --dport 25 -d 192.168.100.002 -o eth0 -j ACCEPT

# services hebergés par la machine locale qui communiquent vers eth1
iptables -A OUTPUT -m state --state NEW -p tcp --dport 123 -o eth1 -j ACCEPT 
iptables -A OUTPUT -m state --state NEW -p tcp --dport 443 -o eth1 -j ACCEPT 	
iptables -A OUTPUT -m state --state NEW -p tcp --dport 80  -o eth1 -j ACCEPT 
iptables -A OUTPUT -m state --state NEW -p tcp --dport 21  -o eth1 -j ACCEPT 
iptables -A OUTPUT -m state --state NEW -p icmp -o eth1 -j ACCEPT	

# services autorisés en forward depuis eth0 vers eth1
iptables -A FORWARD -m state --state NEW -p udp --dport 53 -i eth0 -s 192.168.100.001 -o eth1 -j ACCEPT 
iptables -A FORWARD -m state --state NEW -p tcp --dport 53 -i eth0 -s 192.168.100.001 -o eth1 -j ACCEPT 
iptables -A FORWARD -m state --state NEW -p tcp --dport 25 -i eth0 -s 192.168.100.002 -o eth1 -j ACCEPT 
iptables -A FORWARD -m state --state NEW -p icmp -i eth0 -o eth1 -j ACCEPT	

# services autorisés en forward depuis eth1 vers eth0
iptables -A FORWARD -m state --state NEW -p tcp --dport 25 -d 192.168.100.002 -i eth1 -o eth0 -j LOG --log-prefix 'forward SMTP :'
iptables -A FORWARD -m state --state NEW -p tcp --dport 25 -d 192.168.100.002 -i eth1 -o eth0 -j ACCEPT 
iptables -A FORWARD -m state --state NEW -p tcp --dport 80 -d 192.168.100.004 -i eth1 -o eth0 -j LOG --log-prefix 'forward HTTP :'
iptables -A FORWARD -m state --state NEW -p tcp --dport 80 -d 192.168.100.004 -i eth1 -o eth0 -j ACCEPT 
iptables -A FORWARD -m state --state NEW -p tcp --dport 443 -d 192.168.100.002 -i eth1 -o eth0 -j LOG --log-prefix 'forward HTTPS :' 
iptables -A FORWARD -m state --state NEW -p tcp --dport 443 -d 192.168.100.002 -i eth1 -o eth0 -j ACCEPT 

# services demandés depuis eth1 et redirigés vers des machines du LAN
iptables -t nat -A PREROUTING -p tcp --dport 25 -i eth1 -j DNAT --to-destination 192.168.100.002 	# SMTP
iptables -t nat -A PREROUTING -p tcp --dport 443 -i eth1 -j DNAT --to-destination 192.168.100.002 	# HTTPS
iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth1 -j DNAT --to-destination 192.168.100.004 	# HTTP

-> je ne suis pas vraiment sur de moi concernant la redirection des paquets pour les serveurs qui sont hébergés sur le LAN. dan sun premier temps j’utilise DNAT en prerouting, puis j’autorise le forward vers le LAN pour les trois ports concernés. je ne sais pas si c’est la meilleur façon de faire.

merci pour vos commentaires.

Pas grand chose à dire sur le fond, excepté que le protocole NTP utilise le transport UDP et non TCP.
Sur la forme, quelques suggestions.

  • Utiliser des variables avec des noms explicites pour représenter les interfaces et les adresses. Non seulement ça améliore la lisibilité mais en plus ça facilite la maintenance.
  • Regrouper les règles ayant des critères communs (même interface, même adresse de destination, même état de connexion…) dans des chaînes utilisateur rend les règles plus courtes et améliore leur lisibilité.
  • Eviter d’écrire les nombres décimaux des adresses avec des 0 devant, comme 001, car certains programmes peuvent l’interpréter comme de l’octal comme en C.
  • Il manque les commandes vidant les chaînes. Or "iptables -X " pour supprimer une chaîne utilisateur ne marche que si la chaîne est vide. Je recommande le classique “iptables -F” pour vider toutes les chaînes suivi d’un “iptables -X” pour supprimer toutes les chaînes utilisateur, à faire pour chaque table.
  • Si tu comptes utiliser le protocole FTP sur la machine, il vaut mieux charger le module assistant de suivi de connexion pour FTP ip_conntrack_ftp ou nf_conntrack_ftp selon le noyau. Si tu comptais utiliser le protocole FTP à travers la machine avec du NAT, il faudrait en plus charger le module assistant de NAT pour FTP ip_nat_ftp ou nf_nat_ftp.

Concernant la redirection de ports, c’est la méthode classique. On peut affiner en marquant la connexion avec CONNMARK dans mangle/PREROUTING et en se basant sur la marque de connexion dans les règles DNAT et FORWARD, mais c’est du luxe.

merci pour tes remarques pertinentes, ça sent l’expérience. en même temps je m’attendais bien à ce que ça soit toit qui réponde… Mr iptables.

j’ai corrigé les anomalies, pour les chiffres qui commencent par zéro j’avais deja vu ça dans /etc/network/interfaces, les adresses paramétrées n’étaient pas les mêmes que celles dans ifconfig, à cause des zéro.

pour les variables et les chaines, je pense que je verrais ça pour un prochain script (en tout cas pas avant l’année prochaine). pour l’instant j’ai juste fait des regroupement en utilisant l’option --dports afin de gagner quelques lignes.

sinon j’ai pas bien saisi le sens de :

sachant que le FTP est ouvert en OUTPUT uniquement afin que SQUID puisse faire son boulot de proxy HTTP/HTTPS/FTP. pas de FTP en direct depuis le LAN et pas de serveur FTP. est ce vraiment nécéssaire ? et si oui comment on fait ?

merci encore.

Vu tes restrictions fascistes sur les connexions entrantes et sortantes, oui c’est nécessaire. Le protocole FTP n’utilise pas que le port 21, qui sert pour établir uniquement la connexion de commande. Les connexions de données servant au transfert des fichiers et au listage des répertoires passent par d’autre ports, dynamiques eux. En plus ces connexions peuvent être entrantes ou sortantes selon que le client FTP utilise le mode actif ou passif. Le module assistant de suivi de connexion FTP repère ces ports à la volée et classe les connexions correspondantes dans l’état RELATED. Pour le charger, tu peux le faire dans le script :

ou bien ajouter le nom du module dans le fichier /etc/modules, ce qui le fera charger automatiquement au démarrage.

Ok, merci, ça roule
eh ben voila, iptables c’est fait, à ajouter sur mon cv :smiley:

ça je ne sais pas si je vais le mettre… :laughing:

Eh, mais c’est de la concurrence déloyale !

Dans le contexte du filtrage, “fasciste” n’est pas péjoratif. Je désigne par là un filtrage qui n’autorise strictement que ce qui est nécessaire aussi bien en entrée qu’en sortie, ce qui est plus difficile (ne rien oublier, ne rien autoriser en trop) que de tout autoriser en sortie comme on voit souvent. J’aurais pu aussi dire “filtrage suisse”, non en référence au gruyère suisse (qui pourtant n’a pas de trous, contrairement à l’emmental) mais au dicton bien connu selon lequel “en Suisse, tout ce qui n’est pas interdit est obligatoire”.

tiens, tant que je suis dans le fascisme à la suisse, est ce que j’ai la possibilité d’utiliser un antivirus sur le firewall pour scanner le traffic venant de l’exterieur ?? et si oui dans quelle phase est ce idéal, le PREROUTING ?

Je ne peux pas te renseigner : les anti-virus, je n’y connais rien, mais alors rien du tout. Ceci dit, selon la formule consacrée “ce n’est pas parce qu’on n’a rien à dire qu’il faut fermer sa gueule” (décidément, c’est le jour des citations à la noix), je peux dire ceci. netfilter/iptables étant essentiellement un filtre de paquets, il n’est pas forcément adapté pour un anti-virus qui par essence doit analyser les données de la couche applicative transportées par une connexion. Cependant il y a peut-être quelque chose à voir du côté du filtrage de couche 7 avec le patch l7-filter http://l7-filter.sourceforge.net/, ou de la cible QUEUE qui permet d’intercepter les paquets pour les analyser en userland. Ceci dit, il est probablement plus simple d’utiliser des techniques de type packet sniffer/détecteur d’intrusion qui fonctionnent indépendamment d’iptables. En cas de virus détecté dans le flux de données d’une connexion TCP, il serait possible de la couper en envoyant un paquet RST qui va bien aux deux côtés.