IPTABLES : Autorisé uniquement les requêtes DNS sortantes ?

Bonjour,

Je cherche à autoriser uniquement les requêtes DNS sur un PC.

J’ai fait plusieurs tentatives en m’inspirant des lien suivant:
https://gist.github.com/thomasfr/9712418
http://www.cyberciti.biz/tips/linux-iptables-12-how-to-block-or-open-dnsbind-service-port-53.html

Mais le succès reste partiel.
Bien que, via iceweasel, la majorité du trafic est bloqué, j’ai toujours accès à certains sites comme google ?
Et pour moi c’est un mystère.

Toutes précisions seraient la bienvenue.
Merci.

Les scripts “tests” ressemblent à cela:

[code]#!/bin/sh

IPT=“iptables”

echo “Reset iptables rules”
$IPT -F
$IPT -X

Interdire toutes connexions entrantes et sortantes

$IPT -P INPUT DROP
$IPT -P OUTPUT DROP

This should be one of the first rules.

so dns lookups are already allowed for your other rules

DNS_SERVER=“192.168.1.254”

for ip in $DNS_SERVER
do
echo “Autorisé la résolution DNS (tcp, udp port 53) vers ‘$DNS_SERVER’”
$IPT -A OUTPUT -p tcp -d $ip --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -p udp -d $ip --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT

$IPT -A INPUT  -p udp -s $ip --sport 53 -m state --state ESTABLISHED     -j ACCEPT
$IPT -A INPUT  -p tcp -s $ip --sport 53 -m state --state ESTABLISHED     -j ACCEPT

done

Autoriser loopback (localhost)

$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT[/code]

Hello je ne vois pas le RELATED, pour moi ça marcherai mieux comme ça (je ne donne qu’une partie de tes règles, celles qui me semblent incomplètent) :

[code]for ip in $DNS_SERVER
do
echo “Autorisé la résolution DNS (tcp, udp port 53) vers ‘$DNS_SERVER’”
$IPT -A OUTPUT -p tcp -d $ip --dport 53 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -p udp -d $ip --dport 53 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT

$IPT -A INPUT -p udp -s $ip --sport 53 -m state --state RELATED,ESTABLISHED -j ACCEPT
$IPT -A INPUT -p tcp -s $ip --sport 53 -m state --state RELATED,ESTABLISHED -j ACCEPT
done[/code]

@ plus :blush:

Merci SylvainMuller,

Je viens de faire le test, il n’y a pas de changement an ajoutant “RELATED”.
J’ai toujours accès à google.

Je vais cependant laissé “RELATED”, et voir au prochain redémarrage de la machine, on sait jamais.

L’ajout de l’état RELATED à ces règles n’apporte rien car les paquets qu’elles ciblent (DNS) ne peuvent pas être dans cet état. S’il devait y avoir des paquets liés aux requêtes DNS classés dans l’état RELATED, ce seraient des types d’erreur ICMP (destination unreachable, time exceeded, parameter problem…). Accepter ces paquets est recommandé pour éviter certains problèmes ou être informé des erreurs (ou pour utiliser certains outils comme traceroute).

Si la machine a une connectivité IPv6 native, elle peut contacter les sites qui ont des adresses IPv6 puisque les règles mises en place par [mono]iptables[/mono] ne s’appliquent qu’aux paquets IPv4. Google, mais aussi debian-fr.org, debian.org sont accessibles en IPv6. Pour vérifier :

ip -6 addr ip -6 route
Dans ce cas il faut mettre en place des règles similaires pour les paquets IPv6 avec [mono]ip6tables[/mono]. Dans le script il suffit de remplacer “iptables” par “ip6tables” et les adresses IPv4 de serveurs DNS par les adresses IPv6 de serveurs DNS figurant dans /etc/resolv.conf.

Merci Pascalhambourg,

Je vais mettre l’option “RELATED” comme tu me le conseilles.
Ce n’était pas mon but premier qui était d’autorisé seulement certaines IP sur les ports http/80 et https/443.
Mais j’ai étais amené à réduire mes règles iptables au minimum pour cerner le problème.

Je te remercie pour toutes ces précisions même si certaines me dépasse.
Je n’avais pas du tout pensé à l’ipv6.

Bien que je n’ai pas encore établi de règles ipv6, je te fais pleinement confiance et passe donc le sujet en résolu.

[code]# ip -6 addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qlen 1000
inet6 2a01:e35:87d4:58f0:202:b3ff:feef:6b91/64 scope global mngtmpaddr dynamic
valid_lft 86385sec preferred_lft 86385sec
inet6 fe80::202:b3ff:feef:6b91/64 scope link
valid_lft forever preferred_lft forever

ip -6 route

2a01:e35:87d4:58f0::/64 dev eth1 proto kernel metric 256 expires 86300sec mtu 1480
fe80::/64 dev eth1 proto kernel metric 256 mtu 1480
default via fe80::6aa3:78ff:fe01:48f7 dev eth1 proto ra metric 1024 expires 1700sec mtu 1480 hoplimit 64[/code]

Merci encore, tu as mis fin à mes multiples tentatives infructueuses. :smiley:

Les sorties des commandes confirment que la machine a de l’IPv6 (de Free).

Et oui, il faut commencer à y penser systématiquement dès qu’on veut contrôler son trafic internet, ce n’est plus marginal maintenant que de gros fournisseurs d’accès le proposent et de gros services internet comme Google sont disponibles en IPv6. Il faut notamment faire attention avec les VPN qui sont à la mode : on pense que tout passe par le VPN, mais souvent seul l’IPv4 est concerné et l’IPv6 continue à passer par le FAI. Or par défaut l’IPv6 est prioritaire !

[quote=“PascalHambourg”]L’ajout de l’état RELATED à ces règles n’apporte rien car les paquets qu’elles ciblent (DNS) ne peuvent pas être dans cet état. S’il devait y avoir des paquets liés aux requêtes DNS classés dans l’état RELATED, ce seraient des types d’erreur ICMP (destination unreachable, time exceeded, parameter problem…). Accepter ces paquets est recommandé pour éviter certains problèmes ou être informé des erreurs (ou pour utiliser certains outils comme traceroute).

Si la machine a une connectivité IPv6 native, elle peut contacter les sites qui ont des adresses IPv6 puisque les règles mises en place par [mono]iptables[/mono] ne s’appliquent qu’aux paquets IPv4. Google, mais aussi debian-fr.org, debian.org sont accessibles en IPv6. Pour vérifier :

ip -6 addr ip -6 route
Dans ce cas il faut mettre en place des règles similaires pour les paquets IPv6 avec [mono]ip6tables[/mono]. Dans le script il suffit de remplacer “iptables” par “ip6tables” et les adresses IPv4 de serveurs DNS par les adresses IPv6 de serveurs DNS figurant dans /etc/resolv.conf.[/quote]
Merci aussi pour toutes ces précisions, j’apprends beaucoup encore aujourd’hui, ouf… Je continue à penser que les connaissances ne sont que si elles sont partagées, et Linux ouvre beaucoup de voies. (ou de voix, ça marche aussi), à toute :stuck_out_tongue:

:118 Bon, plus qu’a voir mes règles ipv6.

[code]# ip6tables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination[/code]

Merci encore pour votre aide.

Cedric ton but est d’appliquer le même filtrage à l’ipv6 qu’à l’ipv4 svp ?

Pour le moment tes chaînes [mono]ip6tables[/mono] sont vides et laissent tout passer. Essaie de prendre l’habitude d’utiliser [mono]ip{6}tables-save[/mono] à la place d’[mono]ip{6}tables -nL[/mono] car la sortie est plus complète et plus lisible (plus proche de la syntaxe des commandes [mono]ip{6}tables[/mono]).

J’ai été un peu rapide en écrivant qu’il suffisait de reproduire les mêmes règles qu’en IPv4. Le protocole IPv6 a une différence majeure avec IPv4 : il remplace le protocole ARP (indépendant d’IPv4) pour la résolution d’adresse par un sous-ensemble du protocole ICMPv6 (basé sur IPv6) : NDP. Donc bloquer ce sous-ensemble équivaut à empêcher quasiment toute communication en IPv6. Depuis le noyau 2.6.29, une facilité existe pour éviter de lister tous les types ICMPv6 de NDP : ils sont classés dans l’état UNTRACKED (indiquant qu’ils sont ignorés par le suivi de connexion).

Si tu veux juste bloquer tout trafic IPv6, c’est simple : tu mets les politiques par défaut des 3 chaînes à DROP. Si tu veux n’autoriser que certaines communications, comme la résolution DNS, il faut en plus des règles équivalentes à l’IPv4 ajouter des règles qui autorisent les paquets ICMPv6 dans l’état UNTRACKED en INPUT et OUTPUT.

[code]IPT=“ip6tables”

echo “Reset iptables rules”
$IPT -F
$IPT -X

Interdire toutes connexions entrantes et sortantes

$IPT -P INPUT DROP
$IPT -P OUTPUT DROP

This should be one of the first rules.

so dns lookups are already allowed for your other rules

DNS_SERVER=“2a01:e00::2” # exemple (serveur DNS IPv6 de Free)

for ip in $DNS_SERVER
do
echo “Autoriser la résolution DNS (tcp, udp port 53) vers ‘$DNS_SERVER’”
$IPT -A OUTPUT -p tcp -d $ip --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -p udp -d $ip --dport 53 -m state --state NEW,ESTABLISHED -j ACCEPT

$IPT -A INPUT -p udp -s $ip --sport 53 -m state --state ESTABLISHED -j ACCEPT
$IPT -A INPUT -p tcp -s $ip --sport 53 -m state --state ESTABLISHED -j ACCEPT
done

Autoriser loopback (localhost)

$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT

Autoriser NDP

$IPT -A INPUT -p icmpv6 -m state --state UNTRACKED -j ACCEPT
$IPT -A OUTPUT -p icmpv6 -m state --state UNTRACKED -j ACCEPT

Autoriser les messages d’erreur ICMPv6

$IPT -A INPUT -p icmpv6 -m state --state RELATED -j ACCEPT
$IPT -A OUTPUT -p icmpv6 -m state --state RELATED -j ACCEPT[/code]

Mon but est de faire un test de routeur/pare feu avec une machine dédiée ou pseudo dédiée.
Déja pas très à l’aise avec iptables, je pense déja essayer d’appliquer quelques règles ipv6 entre le pseudo routeur/firewall et la box.

Merci PascalHambourg pour toutes ces précisions…
Je découvre… :017

Déja je n’aurais pas jugé utile d’appliquer d’ipv6 sur “loopback (localhost)”.
Edit : Oui effectivement, si ça fais comme avec iptables, que “lo” est quasiment nécessaire… :075

C’est cool, bonne découverte :wink: