Iptables pour un noob

Bonjour,

Sur mon poste perso (petit serveur de fichiers basique), j’utilisais GUFW pour configurer le pare-feu.
GUFW me faisant des segmentation fault à tout-va, je me suis décidé à utiliser iptables directement.

En partant de ça : https://wiki.debian.org/iptables, j’ai fait ça :

[code]*filter

Allows all loopback (lo0) traffic and drop all traffic to 127/8 that doesn’t use lo0

-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT

Accepts all established inbound connections

-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Allows all outbound traffic

You could modify this to only allow certain traffic

-A OUTPUT -j ACCEPT

Allows HTTP and HTTPS connections from anywhere (the normal ports for websites)

-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT

SSH connections

-A INPUT -p tcp -m state --state NEW --dport 45689 -j ACCEPT

Transmission

-A INPUT -p tcp --dport 58974 -j ACCEPT
-A INPUT -p udp --dport 58974 -j ACCEPT

Samba

-A INPUT -p tcp -m multiport --dports 135,139,445 -j ACCEPT
-A INPUT -p tcp -m multiport --sports 135,139,445 -j ACCEPT
-A INPUT -p udp -m multiport --dports 137,138 -j ACCEPT
-A INPUT -p udp -m multiport --sports 137,138 -j ACCEPT

Cups

-A INPUT -p tcp --dport 631 -j ACCEPT
-A INPUT -p udp --dport 631 -j ACCEPT

Rygel

-A INPUT -p udp --dport 1900 -j ACCEPT
-A INPUT -p tcp --dport 26541 -j ACCEPT
-A INPUT -p udp --dport 26541 -j ACCEPT

VNC

-A INPUT -p tcp --dport 33569 -j ACCEPT

Allow ping

note that blocking other types of icmp packets is considered a bad idea by some

remove -m icmp --icmp-type 8 from this line to allow all kinds of icmp:

https://security.stackexchange.com/questions/22711

-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT

log iptables denied calls (access via ‘dmesg’ command)

-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

Reject all other inbound - default deny unless explicitly allowed policy:

-A INPUT -j REJECT
-A FORWARD -j REJECT

COMMIT[/code]

Première question, je voudrais savoir si c’est à peu près cohérent ?

Ce que j’ai compris ici : tout le traffic entant est bloqué sauf ce que j’accepte explicitement (HTTP & HTTPS, SSH, Transmission, samba, cups, rygel, vnc). En revanche, tout le traffic sortant est autorisé sans aucun filtre (on verra par la suite).

Ce que je n’ai pas compris ici (tout le reste en fait :laughing: ) :

# Allows all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0 -A INPUT -i lo -j ACCEPT -A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT

# Accepts all established inbound connections -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

[code]# Allow ping

note that blocking other types of icmp packets is considered a bad idea by some

remove -m icmp --icmp-type 8 from this line to allow all kinds of icmp:

https://security.stackexchange.com/questions/22711

-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT[/code]

# Reject all other inbound - default deny unless explicitly allowed policy: -A INPUT -j REJECT -A FORWARD -j REJECT

Et il ya cette option state que je ne saisis pas :

-m state --state ESTABLISHED,RELATED -m state --state NEW

Bon, soyez indulgents, j’en suis au début de mes investigations… Si certains d’entre vous pouvaient prendre quelques instants pour vulgariser un peu ?

Merci

Il y avait une solution intermédiaire : utiliser [mono]ufw[/mono] (dont gufw n’est qu’une interface graphique) en ligne de commande.

L’interface de loopback lo sert aux communications entre processus locaux. La plage d’adresses dédiée à cette interface est 127.0.0.0/8, mais les communications locales utilisant l’adresse d’une interface réseau quelconque passent aussi par l’interface de loopback. Comme ce qui entre par cette interface vient de la machine elle-même, il n’y a généralement pas lieu de filtrer le trafic sur celle-ci.

Cela part d’une bonne intention mais REJECT (qui envoie un paquet en réponse pour notifier le rejet du paquet reçu, contrairement à DROP qui bloque silencieusement) est une mauvaise idée. Ce genre de paquet ne peut être émis que par une machine malveillante ou très mal configurée, qui ne mérite pas de réponse donc DROP. De toute façon le noyau bloque déjà par défaut ce genre de paquet comportant une adresse invalide.

# Accepts all established inbound connections -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
Le suivi de connexion est une fonctionnalité majeure utilisable avec iptables. Il permet de reconnaître si un paquet émis ou reçu crée une nouvelle connexion (NEW), appartient (ESTABLISHED) ou est lié (RELATED) à une connexion existante, ou ne correspond à aucune connexion nouvelle ou existante (INVALID). C’est notamment utile pour identifier les paquets de réponse. En effet le port source seul ne peut pas être utilisé de façon fiable pour cela.

-A INPUT -p tcp -m multiport --sports 135,139,445 -j ACCEPT -A INPUT -p udp -m multiport --sports 137,138 -j ACCEPT
Passoire illustrant ce que j’écrivais juste au dessus. Un attaquant peut utiliser un de ces ports comme porte source et se connecter à n’importe quel port TCP ou UDP de ta machine grâce à ces règles.

# note that blocking other types of icmp packets is considered a bad idea by some
En effet bloquer certains types ICMP est une mauvaise idée, mais les paquets valides de ces types sont dans l’état ESTABLISHED (echo reply = réponse au ping) ou RELATED (messages d’erreur ICMP) et sont donc déjà acceptés par la règle de suivi de connexion vue plus haut. Par contre il y a quelques types ICMP potentiellement nocifs (source quench, redirect) qui sont aussi acceptés par la même occasion.

Quitte à utiliser la ligne de commande, autant configurer directement iptables non ?

[quote=“PascalHambourg”]Code:
-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT

Cela part d’une bonne intention mais REJECT (qui envoie un paquet en réponse pour notifier le rejet du paquet reçu, contrairement à DROP qui bloque silencieusement) est une mauvaise idée. Ce genre de paquet ne peut être émis que par une machine malveillante ou très mal configurée, qui ne mérite pas de réponse donc DROP. De toute façon le noyau bloque déjà par défaut ce genre de paquet comportant une adresse invalide.[/quote]
Donc cette ligne peut être supprimée si le noyau la bloque par défaut.

[quote=“PascalHambourg”]Code:
-A INPUT -p tcp -m multiport --sports 135,139,445 -j ACCEPT
-A INPUT -p udp -m multiport --sports 137,138 -j ACCEPT

Passoire illustrant ce que j’écrivais juste au dessus. Un attaquant peut utiliser un de ces ports comme porte source et se connecter à n’importe quel port TCP ou UDP de ta machine grâce à ces règles.[/quote]
Ces lignes modifiées comme suit auraient-elles plus de sens ?

-A OUTPUT -p tcp -m multiport --sports 135,139,445 -j ACCEPT -A OUTPUT -p udp -m multiport --sports 137,138 -j ACCEPT
Mais inutiles vu que tout le traffic sortant est autorisé.

Merci pour ta péda. Hardue l’affaire…
A+

[quote]Ces lignes modifiées comme suit auraient-elles plus de sens ?
Code:
-A OUTPUT -p tcp -m multiport --sports 135,139,445 -j ACCEPT
-A OUTPUT -p udp -m multiport --sports 137,138 -j ACCEPT

Mais inutiles vu que tout le traffic sortant est autorisé.[/quote]

Tout à fait. Il faut bien comprendre que le --sport se situe par rapport a la machine envoyant le paquet, dans le cas d’un INPUT la machine qui dialogue avec la tienne donc.
Si ton but est d’autoriser l’accès a tes ports 135 137 138 139 et 445 il faut faire :

-A INPUT -p tcp -m multiport --dports 135,139,445 -j ACCEPT
-A INPUT -p udp -m multiport --dports 137,138 -j ACCEPT

Merci pour ton aide.

[quote=“aytine”]Si ton but est d’autoriser l’accès a tes ports 135 137 138 139 et 445 il faut faire :

-A INPUT -p tcp -m multiport --dports 135,139,445 -j ACCEPT
-A INPUT -p udp -m multiport --dports 137,138 -j ACCEPT[/quote]

Sur le net on trouve des lignes similaires avec “-m state --state NEW” en plus :

-A INPUT -p tcp -m multiport -m state --state NEW --dports 135,139,445 -j ACCEPT -A INPUT -p udp -m multiport -m state --state NEW --dports 137,138 -j ACCEPT

Ca change quoi ?

Non, pas forcément. iptables gère le filtrage au plus bas niveau, au niveau du paquet, alors qu’ufw gère le filtrage à plus haut niveau, au niveaux des flux et connexions.

Non, puisque le trafic sortant est déjà autorisé.
Quel était le but de ces règles ? Quels types de paquets entrants que d’autres règles n’acceptent pas déjà sont-elles censées accepter ? Pour TCP, c’est réglé : si ce sont des réponses à des requêtes émises, elles sont dans l’état ESTABLISHED ou RELATED donc acceptées par la règle de suivi de connexion. Pour UDP, c’est plus compliqué car le protocole étant non connecté, les paquets de réponse échappent parfois à la notion de “connexion” du suivi de connexion utilisé par iptables. C’est par exemple le cas d’un paquet émis en réponse à une requête NBNS (Netbios Name Service) émis en broadcast. Pour ce cas particulier, il existe un module de suivi de connexion nf_conntrack_netbios_ns qui doit être chargé pour que ces paquets de réponses soient classés dans l’état RELATED au lieu de NEW.

Le jeu de règles contient déjà des règles pour cela, pas besoin d’en ajouter.

Cela sert essentiellement à ne pas accepter les éventuels paquets dans l’état INVALID. En toute rigueur il faudrait l’ajouter à chaque règle acceptant un type de connexion. Il faut bien sûr qu’une autre règle acceptant les paquet ESTABLISHED voire RELATED soit présente, sinon la connexion va tourner court après le premier échange.

C’est là que je commence à être largué :wink:

[quote=“PascalHambourg”]jul a écrit:
Ces lignes modifiées comme suit auraient-elles plus de sens ?
Non, puisque le trafic sortant est déjà autorisé.[/quote]
Ca, j’avais compris.

Autoriser samba

[quote=“PascalHambourg”]Si ton but est d’autoriser l’accès a tes ports 135 137 138 139 et 445
Le jeu de règles contient déjà des règles pour cela, pas besoin d’en ajouter.[/quote]
Là, en revanche je ne comprends pas du tout… Ce sont bien les ports samba, je dois bien les autoriser, non ?

Connais-tu le fonctionnement des protocoles IP, TCP, UDP, ICMP, la structure des en-têtes de paquets… ? Cela me semble un prérequis indispensable à l’écriture de règles iptables. Et je ne me vois pas faire un cours sur TCP/IP.

Trop vague. Iptables est un filtre de paquets alors que Samba est une application, et même une collection d’applications clientes et serveur utilisant plusieurs protocoles (Netbios, SMB/CIFS). Selon l’usage, les flux réseau ne seront pas les mêmes.

Autoriser un port, ça ne veut rien dire. Iptables est un filtre de paquets, il accepte ou bloque des paquets individuels en fonction de critères. Parmi ces critères se trouve la direction du paquet, l’interface d’entrée et/ou de sortie, le protocole, l’adresse et le port source, l’adresse et le port destination…

Une simple connexion TCP met en oeuvre des paquets dans les deux directions, avec des ports source et destination différents (intervertis dans les deux directions), qu’il faut tous autoriser pour que la connexion fonctionne. Les règles iptables à mettre en place sont différentes pour une machines cliente qui initie une connexion et pour une machine serveur qui attend à l’écoute.

Non effectivement, je me rends compte que j’ai eu les yeux plus gros que le ventre… Je vais peut-être me rabattre sur la solution intermédiaire ufw que tu préconisais. Mais je ne lâche pas l’affaire et vais me documenter sur le fonctionnement de ces protocoles. Je passe donc en résolu.

Ouai, j’imagine bien que tu as d’autres choses à faire… En tout cas merci pour tes éclaircissements, qui me laissent entrevoir le long chemin que j’ai encore à parcourir au travers les méandres de l’informatique et du réseau en particulier.