Re: [firewall] iptables, le script parfait?
Gaëtan PERRIER a écrit :
Ça commence mal. Un jeu de règles sans chaînes utilisateur ne peut
pas être un bon jeu de règles. ;-)
Bon, je me pencherai sur la question des chaînes utilisateurs. Pour
l'instant je ne sais pas ce que c'est...
Voir la documentation de Netfilter/iptables. Comme son nom l'indique,
une chaîne utilisateur est une chaîne créée par l'utilisateur avec
iptables -N. On peut on peut y créer des règles avec iptables -A et on
peut l'appeler à partir d'une règle comme une cible avec l'option -j.
C'est une sorte de sous-programme pour iptables. Une chaîne utilisateur
peut être appelée depuis plusieurs endroits, y compris plusieurs chaînes
de base. Elle permet notamment de "factoriser" des critères de
correspondance communs à plusieurs règles (ex: regrouper toutes les
règles relatives à un interface d'entrée ou un état) ou de faire les
mêmes tests à plusieurs endroits sans dupliquer les règles (ex: même
vérification d'adresse/port dans INPUT et FORWARD). Pour info, mon jeu
de règles contient une cinquantaine de chaînes utilisateur.
Où la variable $new_ip_address est-elle définie ? Que
contient-elle ?
ça vient du client dhcp. Ce script est appelé à chaque attribution
d'une adresse ip sur mon interface réseaux allant vers internet.
Justement, je voulais en parler dans ma réponse précédente. Il n'est pas
nécessaire de réinitialiser toutes les règles. Il suffirait d'effacer et
recréer uniquement les règles liées à l'adresse susceptible de changer.
Et pour limiter le nombre de règles impliquées, les chaînes utilisateur
sont d'une grande aide. C'est ce que je fais pour mes interfaces PPP.
###############################################################################
# Règles de conexion au reseau local
# Tout est autorisé
###############################################################################
echo "+ Règles du réseau local ($LAN_INTERFACE - $LAN_IP -
$LAN_NETWORK)"
# Connexions firewall <-> réseau
iptables -t filter -A OUTPUT -o $LAN_INTERFACE -s $LAN_IP -d
$LAN_NETWORK -p all -j ACCEPT iptables -t filter -A INPUT -i
$LAN_INTERFACE -s $LAN_NETWORK -d $LAN_IP -p all -j ACCEPT
Ces règles oublient de prendre en compte les paquets émis (resp.
reçus) sur $LAN_INTERFACE avec l'adresse source (resp. destination)
$WAN_IP, qui sont pourtant parfaitement légitimes.
Je n'ai pas bien compris comment ça peu arriver?
Si tu veux établir une communication (par exemple un simple ping) vers
l'adresse WAN de la passerelle depuis un poste du LAN. C'est
parfaitement légal, et pourtant tes règles la bloqueraient, ainsi que la
réponse. Un point souvent mal compris est qu'une adresse IP ne doit pas
être considérée comme identifiant l'interface qui la porte mais la
machine tout entière. Opérationnellement, il n'y a pas de lien entre les
interfaces et les adresses locales et on peut utiliser n'importe quelle
adresse locale avec n'importe quelle interface. Ce n'est que dans
certains cas particulier qu'il peut être souhaitable d'interdire les
communications avec une adresse donnée sur une interface particulière ;
par exemple interdire l'adresse privée sur l'interface WAN parce qu'une
adresse privée ne devrait jamais apparaître sur l'internet public.
echo "+ Règles pour Internet ($WAN_INTERFACE - $WAN_IP - $WAN_NETWORK)"
iptables -t filter -A OUTPUT -o $WAN_INTERFACE -s $WAN_IP -d $WAN_NETWORK -p all -m state --state ! INVALID -j ACCEPT
iptables -t filter -A INPUT -i $WAN_INTERFACE -s $WAN_NETWORK -d $WAN_IP -p tcp --tcp-flags ! ALL SYN -m state --state NEW,RELATED -j DROP #06/05/2006
iptables -t filter -A INPUT -i $WAN_INTERFACE -s $WAN_NETWORK -d $WAN_IP -p all -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t filter -A INPUT -i $WAN_INTERFACE -s $WAN_NETWORK -d $WAN_IP -p tcp --destination-port auth -j REJECT --reject-with tcp-reset #06/05/2006
La dernière règle ne serait pas nécessaire si toutes les connexions
indésirables étaient traitées par REJECT au lieu de DROP.
Peux-tu m'expliquer pourquoi?
Initialement je n'avais pas les lignes finissant par #06/05/2006, sont-elles nécessaires?
La première, qui bloque les paquets TCP dans l'état NEW ou RELATED
autres que SYN n'est pas franchement indispensable puisque soit c'est le
suivi de connexion TCP lui-même qui va classer le paquet INVALID soit
c'est la pile TCP/IP qui va le rejeter.
La seconde, qui répond "fermé" aux requêtes IDENT notamment des serveurs
IRC ou SMTP pour éviter un délai d'attente ou carrément de se faire
jeter par le serveur à cause de l'absence de réponse n'est utile que
parce que ton traitement par défaut des requêtes entrantes est DROP. Si
le traitement pour toutes les requêtes indésirables était REJECT, tu
n'aurais pas besoin d'une exception pour les requêtes IDENT.
echo "+ Autorise l'IP masquerading de $LAN_NETWORK -> $WAN_NETWORK"
iptables -t filter -A FORWARD -i $LAN_INTERFACE -o $WAN_INTERFACE -s $LAN_NETWORK -d $WAN_NETWORK -p all -m state --state ! INVALID -j ACCEPT
Si on veut être puriste, "! INVALID" n'est pas approprié ici. En
effet cela équivaut à NEW,RELATED,ESTABLISHED,UNTRACKED. Or les
paquets dans l'état UNTRACKED, comme ceux dans l'état INVALID, sont
ignorés par les chaînes de la table 'nat'. Par conséquent un tel
paquet serait retransmis sur l'interface WAN avec son adresse
source privée originale, ce qui n'est pas souhaitable. Certes en
l'absence de règles NOTRACK, aucun paquet ne peut se retrouver dans
l'état UNTRACKED.
Donc il faudrait remplacer !INVALID par NEW,RELATED,ESTABLISHED ?
Oui.
[...]
C'est vrai! Donc toutes mes règles OUTPUT pour jabber, xmule, msn, mp9
sont inutiles, c'est ça?
Oui. Et pareil pour les règles INPUT avec ESTABLISHED,RELATED.
D'autre part, un paquet de réponse TCP ou UDP (--sport) ne
peut pas avoir l'état RELATED. Seul le premier paquet d'une
connexion liée peut avoir cet état.
RELATED c'est une nouvelle connexion en relation avec une existante, c'est ça?
En gros, oui. Ici "connexion" et "existante" sont à prendre au sens
large car cela peut être un message d'erreur ICMP - qui n'est pas
vraiment une connexion - émis pour rejeter une requête dont la
"connexion" aura été éphémère.
Pour compléter la réponse de Franck, il existe une version française du
tutorial iptables d'O. Andreasson, dont la page décrivant les états de
connexion se trouve ici :
http://iptables-tutorial.frozentux.net/fr/x1329.html
On ne peut pas avoir de RELATED en sortie?
Si, bien sûr. L'état ne dépend pas du sens de transmission par rapport à
la machine mais par rapport à la connexion elle-même. On définit la
direction "originale" comme la direction du premier paquet qui a créé la
connexion et la direction "retour" comme la direction opposée, celles
des paquets de réponse. Dans une connexion TCP ou UDP liée à une
connexion existante (ex: connexion de données FTP ou TFTP) l'état
RELATED remplace l'état NEW et donc ne peut exister que dans la
direction originale de la connexion liée.
De toute évidence, la règle qui a motivé ma remarque était prévue pour
le trafic dans le sens retour (généralement "--sport xx" = réponse à une
connexion sur le port xx), ce qui est incompatible avec l'état RELATED.
[...]
Je voudrais faire une remarque générale au sujet des nombreuses
règles acceptant des paquets dans l'état RELATED ou ESTABLISHED. Si
le suivi de connexion a classé un paquet dans un de ces états,
c'est que le trafic précédent auquel il est lié a déjà été vu et
accepté (à l'exception des paquets RST ou ICMP émis localement en
réponse à un paquet rejeté). Par conséquent il n'est pas utile de
recréer ces règles pour chaque interface, application, protocole,
port... On peut se contenter d'une unique règle acceptant tous les
paquets dans l'état RELATED ou ESTABLISHED en début de chaîne (pour
l'efficacité, l'immense majorité des paquets étant dans l'état
ESTABLISHED) suivie de règles traitant les paquets dans l'état NEW
au cas par cas. Ça allège et simplifie sensiblement le jeu de
règles sans sacrifier à la sécurité. Beaucoup de jeux de règles
sont construits ainsi.
Bon là je ne suis pas sur d'avoir compris:
on a vu que mes règles OUTPUT étaient superflues car redondantes avec
cette règle (si j'ai bien compris):
iptables -t filter -A INPUT -i $WAN_INTERFACE -s $WAN_NETWORK -d $WAN_IP -p all -m state --state RELATED,ESTABLISHED -j ACCEPT
Non, avec la règle OUTPUT juste à côté. :-)
Donc je vire tous mes OUTPUT avec RELATED,ESTABLISHED
Oui.
Les paquets NEW je ne les traite pas car je n'ai pas de serveurs sur
machine, et si j'en avais je n'aurais à les traiter qu'en INPUT sur
les ports des serveurs. C'est ça?
Tu peux avoir des serveurs sans le savoir. Ainsi les transferts de
fichiers par MSN dans un certain sens (je ne sais plus si c'est en
émission ou réception) s'effectuent normalement en pair-à-pair et
impliquent que ton client MSN devient serveur sur un des ports TCP de la
plage $MSN_TRANSFERT_TCP_PORT (sinon ça peut passer par le serveur MSN
mais ça va moins vite). Si tu as un module de suivi de connexion pour le
protocole MSN, il identifiera le premier paquet comme RELATED et sera
pris en charge par la règle générale. Mais dans le cas contraire, le
premier paquet sera classé NEW et il faudra l'accepter explicitement
avec une règle :
iptables -A INPUT -i $WAN_INTERFACE -d $WAN_IP -p tcp \
--dport $MSN_TRANSFERT_TCP_PORT -m state --state NEW -j ACCEPT
Même chose pour les communications vocales, j'imagine.
[...]
###############################################################################
# Règles pour le log
###############################################################################
Il n'y a rien de prévu pour le log des paquets dans FORWARD ?
Euh, je ne sais pas...
Tu mettrais quoi?
La même chose qu'en entrée et/ou sortie mais dans la chaîne FORWARD.
Reply to: