[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: