iptables
Différences
Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
iptables [2009/03/14 22:47] – root | iptables [Date inconnue] (Version actuelle) – supprimée - modification externe (Date inconnue) 127.0.0.1 | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
- | * source : http:// | ||
- | * Autre tuto : http:// | ||
- | |||
- | ====== Les tables ====== | ||
- | |||
- | Nous allons maintenant voir ce qu'est une table. Une table permet de définir un comportement précis de Netfilter. Une table est en fait un ensemble de chaînes, elles-mêmes composées de règles. Bref, une table va nous permettre de manipuler Netfilter, afin de lui faire faire des choses intéressantes. | ||
- | |||
- | Mais comment manipuler ces tables ? Je vous le donnes en 1000 : Avec le programme " | ||
- | |||
- | Il existe pour l' | ||
- | |||
- | |||
- | ===== La table Filter ===== | ||
- | |||
- | Comme son nom l' | ||
- | * INPUT : Cette chaîne contrôle les paquets à destination des applications. | ||
- | * OUTPUT : Elle analyse les paquets qui sortent des applications. | ||
- | * FORWARD : Elle filtre les paquets qui passent d'une interface réseau à l' | ||
- | |||
- | La philosophie du filtrage est très simple : Tout ce qui n'est pas explicitement autorisé est strictement interdit. C'est plutôt autoritaire comme système non ? | ||
- | |||
- | Pour cela, nous allons travailler en deux temps : | ||
- | * Premièrement, | ||
- | * Dans un second temps, nous n' | ||
- | |||
- | |||
- | ===== La table NAT ===== | ||
- | |||
- | La table NAT (Network Adress Translation, | ||
- | |||
- | Pour faire tout ceci, nous avons besoin là encore de 3 chaînes : | ||
- | * PREROUTING : Les paquets vont être modifiés à l' | ||
- | * OUTPUT : Les paquets sortant des processus locaux sont modifiés. | ||
- | * POSTROUTING : les paquets qui sont près à être envoyés aux interfaces réseaux sont modifiés. | ||
- | |||
- | |||
- | ===== La table Mangle ===== | ||
- | |||
- | Nous allons nous transformer en boucher, avide de bits à découper et à reconditionner... En effet, le terme " | ||
- | |||
- | Que diable voulons nous faire à nos braves paquets réseaux ? En fait, il s'agit de les marquer en entrée de la couche réseau, afin que d' | ||
- | |||
- | Un exemple d' | ||
- | |||
- | Mais l' | ||
- | |||
- | Dans les premiers kernels de la série 2.4, la table Mangle n' | ||
- | * PREROUTING : Les paquets vont être marqués en entrée de la couche réseau, en fonction de certains critères, de type de service (grâce aux numéros de ports source et/ou de destination), | ||
- | * INPUT : Les paquets sont marqués juste avant d' | ||
- | * FORWARD : Les paquets passant d'une interface réseau à l' | ||
- | * OUTPUT : Là, ce sont les paquets générés par les applications locales (un client web par exemple) qui vont être marqués, tout comme les paquets entrant dans la couche réseau. | ||
- | * POSTROUTING : Les paquets prêt à être envoyés sur le réseau sont marqués. L' | ||
- | |||
- | |||
- | ====== Chaînes, règles et iptables ====== | ||
- | |||
- | ===== Les chaînes utilisateurs ===== | ||
- | |||
- | Nous avons vu précédemment qu'il existe 5 principales chaînes, appelées aussi chaînes pré-définies, | ||
- | |||
- | Ce que nous n' | ||
- | |||
- | Sur le dessin ci-dessous, on voit quelques chaînes utilisateurs qui sont crées pour la table " | ||
- | * Êtres utilisées par une chaîne en particulier : perso_2 | ||
- | * Êtres appelées par plusieurs chaînes : perso_1 | ||
- | * Ne pas êtres appelées du tout (perso_3). A quoi cela sert il alors ? A rien tout simplement : le root qui a écrit ces chaînes là à oublié pourquoi il les as créées, et il a du s' | ||
- | |||
- | |||
- | ===== Règles et cibles ===== | ||
- | |||
- | Les règles, comme leur nom l' | ||
- | |||
- | Les critères peuvent être multiples : | ||
- | * Interface source ou destination. | ||
- | * Adresse IP source ou de destination. | ||
- | * Port source ou de destination. | ||
- | * Type de trame. | ||
- | * Nombre de paquets. | ||
- | * Paquet marqué par la table Mangle. | ||
- | * Etc. | ||
- | |||
- | Il peut y avoir autant de règles que l'on veut dans une chaîne, mais il est intéressant de limiter au maximum leur nombre, afin d' | ||
- | |||
- | Enfin, à chaque règle est associée une action (ou " | ||
- | * DROP : Le paquet est détruit purement et simplement. C'est typique du " | ||
- | * ACCEPT : Le paquet a une "bonne tête", | ||
- | * LOG / ULOG : Le paquet est autorisé à continuer de passer, mais ses caractéristiques sont notées au passage. En général, c'est qu'on estime que le paquet est " | ||
- | * MASQUERADE : Le paquet va être modifié, afin de dissimuler (de masquer en fait) certaines informations concernant son origine. Cette technique sera utilisée un peu plus loin. | ||
- | * MARK : le paquet est marqué en y attachant une information. Ceci est principalement utilisé avec les tables " | ||
- | * Une chaîne utilisateur : Nous avons vu un peu plus haut qu'il existe des chaînes utilisateurs. Dans le cas de cette action, le paquet est envoyé à une chaîne définie par l' | ||
- | |||
- | ===== Iptables ===== | ||
- | |||
- | Iptables est donc une commande que seul le root peut lancer. Son but est de dialoguer avec Netfilter, afin de contrôler les règles des chaînes, dans le but de configurer les tables. | ||
- | |||
- | Iptables est la boîte à tout faire de Netfilter. Cette commande va pouvoir : | ||
- | * Rajouter des règles / chaînes. | ||
- | * Supprimer des règles / chaînes. | ||
- | * Modifier des règles / chaînes. | ||
- | * Afficher les règles / chaînes | ||
- | |||
- | Comme toute commande Linux qui se respecte, " | ||
- | |||
- | ^ **Option** ^ **Paramètre** ^ **Paramètre optionnel ** ^ **Explication** ^ **Exemple** ^ | ||
- | | -t (table) | " | ||
- | | -F (Flush) | " | ||
- | | -X (eXclude) | [Chaîne utilisateur] | Oui | Supprime une chaîne utilisateur. Si il n'y a aucun paramètre, toutes les chaînes utilisateurs sont supprimées. | " | ||
- | | -P (Policy) | " | ||
- | | -N (New) | [Chaîne utilisateur] | Non | Cette option crée une nouvelle chaîne utilisateur. Par la suite, des règles doivent êtres créées, afin de remplir cette chaîne. Sinon, elle ne sera pas très utile ! | " | ||
- | | -A (Append) | [Chaîne] | Non | Ajoute une règle à une chaîne prédéfinie ou utilisateur. Nous allons utiliser majoritairement cette commande. | " | ||
- | | -D (Delete) | [Chaîne] [Numéro de règle] | Non | Supprime une règle dans une chaîne particulière. Le numéro de la règle peut être retrouvé avec la commande " | ||
- | | -L (Liste) | [Chaîne] | Oui | Affiche la liste des règles pour la chaîne indiquée. Ou, si aucune chaîne n'est indiquée, cela affichera les règles pour toutes les chaînes de la table indiquée. Note : Rajouter à " | ||
- | | -j (jump) | [Cible] | Non | Défini l' | ||
- | | -i (input) | [Interface réseau] | Non | Critère sur l' | ||
- | | -o (output) | [Interface réseau] | Non | Critère sur l' | ||
- | | -s (source) | [!] [Adresse IP ou réseau] | Non | Critère sur l' | ||
- | | -p (protocole) | [!] " | ||
- | | --sport | [!] [Port ou service] | Non | Critère sur le port source des paquets IP | " | ||
- | | --dport | [!] [Port ou service] | Non | Critère sur le port de destination des paquets IP | " | ||
- | | -m (module) | [Nom d'un module] | Non | Demande d' | ||
- | | --state | [!] " | ||
- | | --log-prefix --ulog-prefix | [Un mot] | Non | Rajoute un commentaire pour les cibles LOG et ULOG | " | ||
- | |||
- | |||
- | Remarque : On trouve parfois dans la colonne " | ||
- | * " | ||
- | * " | ||
- | |||
- | Dans la suite de ce document, je vous conseille de revenir régulièrement sur ce tableau, afin de bien comprendre le mécanisme des règles que nous allons utiliser. Lorsque ce tableau aura répondu à toutes vos questions, et qu'il ne suffira plus à répondre à votre soif de connaissances, | ||
- | |||
- | ====== Un premier script simple ====== | ||
- | |||
- | Comme vous vous devez vous en douter à ce niveau du document, le paramétrage de notre firewall va se résumer à taper un certain nombre de commandes " | ||
- | |||
- | |||
- | ===== Iptables basique ===== | ||
- | |||
- | Nous allons commencer par travailler exclusivement sur la table filter. | ||
- | |||
- | Bon, petit rappel sur LA règle de filtrage universellement reconnue : | ||
- | * Premièrement, | ||
- | * Deuxièmement, | ||
- | * Dans un dernier temps, nous n' | ||
- | * Concernant l' | ||
- | |||
- | Facile non ? Bon, gardez en mémoire le tableau des options d' | ||
- | * Suppression de toutes les chaînes : C'est facile, il faut supprimer les tables pré-défines (option " | ||
- | |||
- | [root@phoenix /]# iptables -t filter -F | ||
- | [root@phoenix /]# iptables -t filter -X | ||
- | |||
- | * Définition de la politique (cibles) par défaut : La table filter possède 3 chaînes, donc elles sont toutes les trois à initialiser. Par défaut, on décide donc de tout détruire (DROP) : | ||
- | |||
- | [root@phoenix /]# iptables -t filter -P INPUT DROP | ||
- | [root@phoenix /]# iptables -t filter -P OUTPUT DROP | ||
- | [root@phoenix /]# iptables -t filter -P FORWARD DROP | ||
- | |||
- | A ce stade là, vous avez court-circuité tout votre système de réseau. Toutes vos connexions réseaux sont hors service. Pas un logiciel que vous utilisez ne peut accéder au réseau, ou à vous propres serveur. J'en veux pour preuve, la commande "ping localhost" | ||
- | |||
- | [olivier@phoenix /]$ ping localhost | ||
- | PING localhost.sky.net (127.0.0.1) 56(84) bytes of data. | ||
- | ping: sendmsg: Operation not permitted | ||
- | ping: sendmsg: Operation not permitted | ||
- | ping: sendmsg: Operation not permitted | ||
- | | ||
- | --- localhost.sky.net ping statistics --- | ||
- | 3 packets transmitted, | ||
- | |||
- | Hahhh bravo, c'est du propre ! | ||
- | |||
- | Mais cela tombe bien, car c'est exactement ce que nous voulions faire. Smiley D'un autre coté, c'est la protection absolue du réseau, qui rivalise presque avec la déconnexion physique des câbles... Mais quand à l' | ||
- | * Autoriser quelques connexions : Dans notre réseau, nous avons 2 cartes réseaux (" | ||
- | o lo (réseau virtuel localhost) : C'est le plus facile. | ||
- | Nous pouvons avoir toute confiance en ce réseau, car il est interne à la mémoire de notre machine. Nous allons donc autoriser ("-j ACCEPT" | ||
- | |||
- | [root@phoenix /]# iptables -t filter -A OUTPUT -o lo -s 127.0.0.0/8 -d 127.0.0.0/8 -j ACCEPT | ||
- | |||
- | Puis nous allons faire l' | ||
- | |||
- | [root@phoenix /]# iptables -t filter -A INPUT -i lo -s 127.0.0.0/8 -d 127.0.0.0/8 -j ACCEPT | ||
- | |||
- | Et nous pouvons immédiatement vérifier que le "ping localhost" | ||
- | [olivier@phoenix /]$ ping localhost | ||
- | PING localhost.sky.net (127.0.0.1) 56(84) bytes of data. | ||
- | 64 bytes from localhost.sky.net (127.0.0.1): | ||
- | 64 bytes from localhost.sky.net (127.0.0.1): | ||
- | | ||
- | --- localhost.sky.net ping statistics --- | ||
- | 2 packets transmitted, | ||
- | rtt min/ | ||
- | |||
- | Ouuuuiiiii ! Nous sommes très fort ! Bon, une interface de réglée passons aux autres. | ||
- | |||
- | o eth0 (réseau interne " | ||
- | |||
- | Donc nous avons fait comme pour l' | ||
- | |||
- | [root@phoenix /]# iptables -t filter -A OUTPUT -o eth0 -s 192.168.0.0/ | ||
- | [root@phoenix /]# iptables -t filter -A INPUT -i eth0 -s 192.168.0.0/ | ||
- | |||
- | Bien, et que donne le "ping paradise.sky.net" | ||
- | |||
- | [olivier@phoenix /]$ ping paradise.sky.net | ||
- | PING paradise.sky.net (192.168.0.2) 56(84) bytes of data. | ||
- | 64 bytes from paradise.sky.net (192.168.0.2): | ||
- | 64 bytes from paradise.sky.net (192.168.0.2): | ||
- | | ||
- | --- localhost.sky.net ping statistics --- | ||
- | 2 packets transmitted, | ||
- | rtt min/ | ||
- | |||
- | Très bien ! 2 de passées, reste la 3ème... | ||
- | |||
- | o eth1 (réseau Internet " | ||
- | Que vous nous faire exactement en fait ? Interdire l' | ||
- | |||
- | En fait, c'est très simple : nous n' | ||
- | |||
- | [root@phoenix /]# iptables -t filter -A OUTPUT -o eth1 -s 10.0.0.0/8 -p tcp --dport 80 -j ACCEPT | ||
- | [root@phoenix /]# iptables -t filter -A OUTPUT -o eth1 -s 10.0.0.0/8 -p tcp --dport 443 -j ACCEPT | ||
- | [root@phoenix /]# iptables -t filter -A INPUT -i eth1 -d 10.0.0.0/8 -p tcp --sport 80 -j ACCEPT | ||
- | [root@phoenix /]# iptables -t filter -A INPUT -i eth1 -d 10.0.0.0/8 -p tcp --sport 443 -j ACCEPT | ||
- | |||
- | Il ne nous reste plus qu'à faire ouvrir une page web sur web.internet.net, | ||
- | |||
- | [olivier@phoenix /]$ nmap web.internet.net -p 80,443 | ||
- | | ||
- | Starting nmap V. 3.00 ( www.insecure.org/ | ||
- | Interesting ports on web.0.0.10.in-addr.arpa (10.0.0.200): | ||
- | Port State Service | ||
- | 80/tcp open http | ||
- | 443/tcp open https | ||
- | | ||
- | Nmap run completed -- 1 IP address (1 host up) scanned in 0 seconds | ||
- | |||
- | Bingo ! Ca marche ! Faites péter les biscuits apéros ! Ce soir, c'est fête ! Et en plus, ce premier script " | ||
- | |||
- | | ||
- | |||
- | | ||
- | |||
- | | ||
- | PING phoenix.sky.net (192.168.0.1) 56(84) bytes of data. | ||
- | ping: sendmsg: Operation not permitted | ||
- | ping: sendmsg: Operation not permitted | ||
- | | ||
- | --- phoenix.sky.net ping statistics --- | ||
- | 2 packets transmitted, | ||
- | | ||
- | | ||
- | PING phoenix0.sky.net (192.168.0.1) 56(84) bytes of data. | ||
- | ping: sendmsg: Operation not permitted | ||
- | ping: sendmsg: Operation not permitted | ||
- | | ||
- | --- phoenix0.sky.net ping statistics --- | ||
- | 2 packets transmitted, | ||
- | | ||
- | | ||
- | PING phoenix1.internet.net (10.0.0.1) 56(84) bytes of data. | ||
- | ping: sendmsg: Operation not permitted | ||
- | | ||
- | --- phoenix1.internet.net ping statistics --- | ||
- | 1 packets transmitted, | ||
- | |||
- | | ||
- | |||
- | En fait, c'est très simple : dans nos règles " | ||
- | |||
- | | ||
- | |||
- | | ||
- | Chain INPUT (policy DROP 463 packets, 35458 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | 0 0 ACCEPT all -- lo * 127.0.0.0/8 127.0.0.0/8 <-- Ceci est la règle 1 | ||
- | 0 0 ACCEPT all -- eth0 * 192.168.0.0/ | ||
- | 0 0 ACCEPT tcp -- eth1 * 0.0.0.0/0 0.0.0.0/0 tcp spt:80 | ||
- | 0 0 ACCEPT tcp -- eth1 * 0.0.0.0/0 0.0.0.0/0 tcp spt:443 | ||
- | | ||
- | Chain FORWARD (policy DROP 0 packets, 0 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | | ||
- | Chain OUTPUT (policy DROP 71 packets, 10712 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | 0 0 ACCEPT all -- * lo 127.0.0.0/8 127.0.0.0/8 <-- Ceci est la règle 1 | ||
- | 0 0 ACCEPT all -- * eth0 0.0.0.0/0 192.168.0.0/ | ||
- | 0 0 ACCEPT tcp -- * eth1 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 | ||
- | 0 0 ACCEPT tcp -- * eth1 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | Chain INPUT (policy DROP 475 packets, 37048 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | 1 248 ACCEPT all -- eth0 * 192.168.0.0/ | ||
- | 0 0 ACCEPT tcp -- eth1 * 0.0.0.0/0 0.0.0.0/0 tcp spt:80 | ||
- | 0 0 ACCEPT tcp -- eth1 * 0.0.0.0/0 0.0.0.0/0 tcp spt:443 | ||
- | 274 166K ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 | ||
- | | ||
- | Chain FORWARD (policy DROP 0 packets, 0 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | | ||
- | Chain OUTPUT (policy DROP 84 packets, 12080 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | 9 872 ACCEPT all -- * eth0 0.0.0.0/0 192.168.0.0/ | ||
- | 0 0 ACCEPT tcp -- * eth1 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 | ||
- | 0 0 ACCEPT tcp -- * eth1 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 | ||
- | 274 166K ACCEPT all -- * lo 0.0.0.0/0 0.0.0.0/0 | ||
- | | ||
- | Cette fois ci, un "ping phoenix0.sky.net" | ||
- | |||
- | Vous vous demandez sûrement pourquoi j'ai pris un (malin ?) plaisir à introduire cette " | ||
- | * Il sera très important par la suite de comprendre cette histoire d'auto connexion. | ||
- | * Je ne suis pas sûr que vous vous en seriez souvenu si je ne vous avais pas fait pointer le doigt dessus. | ||
- | * Au passage, nous avons vu une utilisation de deux commandes que nous ne connaissions pas : " | ||
- | |||
- | Bon, pendant que vous prenez un biscuit apéro bien mérité, je ferais quelques remarques sur ces scripts : | ||
- | * Dans toutes nos commandes, nous avons utilisé l' | ||
- | * Dans nos commandes iptables ayant pour cible " | ||
- | * Même si nos règles sur le réseau " | ||
- | * Enfin, au point où nous en somme, nous avons l' | ||
- | |||
- | | ||
- | | ||
- | | ||
- | | ||
- | (The 1590 ports scanned but not shown below are in state: closed) | ||
- | Port State Service | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | Nmap run completed -- 1 IP address (1 host up) scanned in 1 second | ||
- | |||
- | | ||
- | | ||
- | | ||
- | | ||
- | Note: Host seems down. If it is really up, but blocking our ping probes, try -P0 | ||
- | Nmap run completed -- 1 IP address (0 hosts up) scanned in 30 seconds | ||
- | |||
- | Alors que nous, nous pouvons surfer en toute tranquillité. He he he, nous avons berné l' | ||
- | |||
- | Ahhh, que c'est beau l' | ||
- | |||
- | Bon, prenez fissa de quoi vous remonter, et préparez vous à vous remettre une nouvelle couche d' | ||
- | |||
- | | ||
- | |||
- | ===== Comment leurrer un firewall en une leçon... ===== | ||
- | |||
- | |||
- | | ||
- | |||
- | Notre intrus va donc se connecter en temps que root sur sa propre machine, et lancer la commande "nmap phoenix1.internet.net -g 80" : | ||
- | |||
- | | ||
- | | ||
- | | ||
- | | ||
- | (The 1585 ports scanned but not shown below are in state: closed) | ||
- | Port State Service | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | |||
- | Nmap run completed -- 1 IP address (1 host up) scanned in 5 seconds | ||
- | |||
- | | ||
- | |||
- | Non, en fait c'est tout à fait naturel et cela prouve la protection complètement insuffisante d'un firewall basé uniquement sur l' | ||
- | * En rouge : Pirate ouvre une connexion venant du port 80, et à destination d'un port de Phoenix sur lequel il suppose que tourne un démon. Il commence une "hand check" tout à fait classique (SYN), auquel répond Phoenix par un " | ||
- | * En bleu : là encore, Pirate ouvre une connexion venant du port 80. Mais cette fois ci, Phoenix l' | ||
- | |||
- | {{: | ||
- | |||
- | |||
- | Comme on le voit, l' | ||
- | |||
- | On peut se demander si un tel port scanning a un réel intérêt. Bon, l' | ||
- | |||
- | Bon, notre intrus n'est pas née de la dernière pluie, et il connaît aussi le programme " | ||
- | |||
- | [root@pirate /]# nc -p 80 phoenix1.internet.net 80 | ||
- | GET / | ||
- | < | ||
- | < | ||
- | < | ||
- | <meta http-equiv=" | ||
- | <meta name=" | ||
- | <meta name=" | ||
- | < | ||
- | |||
- | La fin de la réponse a été coupée, car inutile. On voit bien ici la réponse du serveur web de Phoenix, qui affiche tout naturellement une page web de notre réseau local... Que le lecteur continue de s' | ||
- | |||
- | Bon, si à ce stade je n'ai pas réussi à capter toute votre attention sur ce problème, vous pouvez définitivement arrêter la lecture de ce document, et continuer de vous faire allégrement pirater ! | ||
- | |||
- | |||
- | ===== Et comment renvoyer l' | ||
- | |||
- | Toujours là ? Parfais, passons à la solution de ce problème : | ||
- | |||
- | Bien, le problème ici est que notre intrus peut rentrer comme il veut par les différents ports que nous aurions laissé ouverts afin que nous, nous puissions aller sur Internet. En fait, il faudrait que notre firewall soit semi-perméable, | ||
- | |||
- | Cette technique est vraiment une avancée en matière de firewall. Netfilter se base sur la poignée de main ("hand check", | ||
- | |||
- | Il existe un dernier statut intéressant pour le suivit de connexion, il s'agit du statut " | ||
- | |||
- | {{: | ||
- | |||
- | Voyons maintenant comment mettre en oeuvre cette technique. Le système de suivit de connexion de Netfilter n'est pas forcément compilé dans le kernel, donc si ce n'est pas le cas, vous devez d' | ||
- | |||
- | [root@phoenix /]# modprobe ip_conntrack | ||
- | |||
- | Si vous envisagez d' | ||
- | |||
- | [root@phoenix /]# modprobe ip_conntrack_ftp | ||
- | [root@phoenix /]# modprobe ip_conntrack_irc | ||
- | |||
- | Enfin, pour voir la listes des modules " | ||
- | |||
- | [root@phoenix /]# uname -a | ||
- | Linux phoenix.sky.net 2.4.21-0.13mdksmp #1 SMP Fri Mar 14 13:41:18 EST 2003 i686 unknown unknown GNU/Linux | ||
- | |||
- | [root@phoenix /]# find / | ||
- | / | ||
- | / | ||
- | / | ||
- | / | ||
- | / | ||
- | |||
- | Maintenant, comment indiquer à Netfilter que nous ne désirons laisser passer que les connexions sortantes initialisées par la machine, mais aussi de ne laisser passer que celles qui sont en réponse avec les premières ? C'est tout simplement aussi facile que ce que nous venons de dire : | ||
- | |||
- | [root@phoenix /]# iptables -A OUTPUT -o eth1 -s 10.0.0.1 -d 0.0.0.0/0 | ||
- | -p all -m state --state ! INVALID -j ACCEPT | ||
- | [root@phoenix /]# iptables -A INPUT -i eth1 -s 0.0.0.0/0 -d 10.0.0.1 | ||
- | -p all -m state --state RELATED, | ||
- | |||
- | * Le paramètre "-m state" signifie que nous avons besoin du module " | ||
- | * " | ||
- | * "! INVALID" | ||
- | |||
- | Voila, nous venons de terminer notre configuration de Netfilter en utilisant le suivi de connexion. Le script iptables de tout ceci se trouve [[http:// | ||
- | |||
- | Mais est-ce vraiment efficace ? On va le voir tout de suite : | ||
- | |||
- | | ||
- | | ||
- | | ||
- | All 1601 scanned ports on phoenix1.internet.net (10.0.0.1) are: filtered | ||
- | |||
- | Nmap run completed -- 1 IP address (1 host up) scanned in 1721 seconds | ||
- | |||
- | On utilise l' | ||
- | Dans ces conditions, Nmap ne peut déterminer si Phoenix est joignable ou pas. | ||
- | |||
- | Sur Phoenix on peut voir par contre qu'un grand nombre de paquets entrants ont été " | ||
- | |||
- | | ||
- | Chain INPUT (policy DROP 6571 packets, 268K bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | 3480 2235K ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 | ||
- | 9 2232 ACCEPT all -- eth0 * 192.168.0.0/ | ||
- | 0 0 ACCEPT all -- eth1 * 0.0.0.0/0 10.0.0.1 state RELATED, | ||
- | | ||
- | Chain FORWARD (policy DROP 0 packets, 0 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | | ||
- | Chain OUTPUT (policy DROP 22 packets, 1716 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp spt:6000 | ||
- | 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp spt:6000 | ||
- | 3480 2235K ACCEPT all -- * lo 0.0.0.0/0 0.0.0.0/0 | ||
- | 9 2232 ACCEPT all -- * eth0 192.168.0.0/ | ||
- | 97 9096 ACCEPT all -- * eth1 10.0.0.1 0.0.0.0/0 state NEW, | ||
- | |||
- | La conclusion est sans appel : notre machine est un "trou noir" qui se refuse de répondre aux sollicitations extérieures. Par contre, Phoenix arrive toujours à se connecter sur internet.net : | ||
- | | ||
- | PING web.internet.net (10.0.0.200) 56(84) bytes of data. | ||
- | 64 bytes from web.0.0.10.in-addr.arpa (10.0.0.200): | ||
- | 64 bytes from web.0.0.10.in-addr.arpa (10.0.0.200): | ||
- | | ||
- | --- web.internet.net ping statistics --- | ||
- | 2 packets transmitted, | ||
- | rtt min/ | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | Port State Service | ||
- | | ||
- | | ||
- | | ||
- | Nmap run completed -- 1 IP address (1 host up) scanned in 0 seconds | ||
- | |||
- | | ||
- | |||
- | Bien, maintenant que nous avons sécurisé l' | ||
- | |||
- | |||
- | | ||
- | |||
- | Si Netfilter est très efficace pour filtrer les connexions entrantes et sortantes des processus locaux, il peut servir aussi à d' | ||
- | |||
- | |||
- | ===== IP masquerading ===== | ||
- | |||
- | | ||
- | |||
- | Dans tout ce qui suit, nous allons nous arranger pour que paradise.sky.net puisse se connecter au serveur web web.internet.net. | ||
- | |||
- | Sous Windows®, ce que nous allons faire s' | ||
- | |||
- | Pour réaliser ceci, il nous faut réaliser plusieurs opérations : | ||
- | |||
- | * La première, c'est de charger les modules dont nous allons avoir besoin. En premier, nous avons besoin du module de NAT, c'est à dire " | ||
- | |||
- | | ||
- | | ||
- | | ||
- | |||
- | * Bien entendu, tout comme nous initialisons la table " | ||
- | |||
- | | ||
- | | ||
- | |||
- | * Pour ce qui est des cibles par défaut des chaînes de la table NAT, nous acceptons toutes les connexions. Il n'est pas nécessaire de faire pointer ces cibles sur " | ||
- | |||
- | | ||
- | | ||
- | | ||
- | | ||
- | |||
- | * Bien, maintenant nous allons faire suivre sur le réseau internet.net, | ||
- | |||
- | | ||
- | -m state --state ! INVALID -j ACCEPT | ||
- | | ||
- | -m state --state ESTABLISHED, | ||
- | |||
- | | ||
- | |||
- | * Au point où nous en somme, les paquets venant de sky.net et sortant par l' | ||
- | o pour adresse de destination, | ||
- | o pour adresse source, l' | ||
- | Il va donc falloir que Phoenix subtilise l' | ||
- | |||
- | | ||
- | -s 192.168.0.0/ | ||
- | |||
- | Vous pouvez cependant vous poser la question suivante : que deviennent les paquets revenant du réseau internet.net sur l' | ||
- | |||
- | En fait, ce serait même terriblement dangereux de mettre en place une telle règle de ce type. En effet, cela pourrait faire passer pour des connexions de Phoenix, des connexions initialisées par les machines de internet.net ! C'est comme si vous poussiez vous-même le loup dans la bergerie ! Donc l' | ||
- | |||
- | * Enfin, maintenant que tout le NAT est configuré, il ne reste plus qu'à autoriser dûment votre Linux à faire jouer son rôle de gateway. Pour cela, il faut utiliser simplement écrire un " | ||
- | |||
- | | ||
- | |||
- | {{: | ||
- | |||
- | Le NAT étant maintenant configuré et activé, il reste à configurer les machines du réseau sky.net, afin de leur indiquer quelle est la passerelle. C'est chose faite en lançant par exemple sur paradise.sky.net : | ||
- | |||
- | [root@paradise /]# route add default gw phoenix0.sky.net | ||
- | [root@paradise /]# route | ||
- | Table de routage IP du noyau | ||
- | Destination Passerelle Genmask Indic Metric Ref Use Iface | ||
- | 192.168.0.0 * 255.255.255.0 U 0 0 0 eth0 | ||
- | 127.0.0.0 * 255.0.0.0 U 0 0 0 lo | ||
- | default phoenix0.sky.ne 0.0.0.0 UG 0 0 0 eth0 | ||
- | |||
- | Bien, tout est en place. Voyons ce que cela donne. Depuis paradise.sky.net, | ||
- | [olivier@paradise /]$ nmap web.internet.net -p 80,443 | ||
- | | ||
- | Starting nmap V. 3.00 ( www.insecure.org/ | ||
- | Interesting ports on web.0.0.10.in-addr.arpa (10.0.0.200): | ||
- | Port State Service | ||
- | 80/tcp open http | ||
- | 443/tcp open https | ||
- | |||
- | Nmap run completed -- 1 IP address (1 host up) scanned in 0 seconds | ||
- | |||
- | Bien ! Comme on le voit, la connexion se fait d'un réseau à l' | ||
- | |||
- | Remarques : Dans tout nos exemples, nous avons systématiquement autorisé tout le réseau sky.net à accéder à internet.net. Cependant, nous aurions très bien pu limiter cet accès à uniquement quelques machines de notre réseau interne. Pour cela, il suffit de changer les options " | ||
- | Exemple : | ||
- | |||
- | [root@phoenix ]# iptables -t filter -A FORWARD -i eth0 -o eth1 -s 192.168.0.2 -d 0.0.0.0/0 \ | ||
- | -m state --state ! INVALID -j ACCEPT | ||
- | [root@phoenix ]# iptables -t filter -A FORWARD -i eth1 -o eth0 -s 0.0.0.0/0 -d 192.168.0.2 \ | ||
- | -m state --state ESTABLISHED, | ||
- | |||
- | Et qu'en dit la sécurité ? Est-ce que par hasard pirate.internet.net peut accéder à paradise.sky.net ? Est-ce possible ? Techniquement oui, il suffit que pirate.internet.net déclare phoenix1.internet.net comme étant sa passerelle pour le réseau internet.net : | ||
- | |||
- | [root@pirate /]# route add default gw phoenix1.internet.net | ||
- | [root@pirate /]# route | ||
- | Table de routage IP du noyau | ||
- | Destination Passerelle Genmask Indic Metric Ref Use Iface | ||
- | 10.0.0.0 * 255.0.0.0 U 0 0 0 eth0 | ||
- | 127.0.0.0 * 255.0.0.0 U 0 0 0 lo | ||
- | default phoenix1.intern 0.0.0.0 UG 0 0 0 eth0 | ||
- | |||
- | Puis, de lancer par exemple un " | ||
- | |||
- | [root@pirate /]# ping -c 3 192.168.0.2 | ||
- | PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data. | ||
- | | ||
- | --- 192.168.0.2 ping statistics --- | ||
- | 3 packets transmitted, | ||
- | |||
- | Bien, notre machine est correctement sécurisée. Tout va donc pour le mieux ? Indéniablement, | ||
- | |||
- | En effet, regardons les traces qu'on laissé la dernière connexion de pirate.internet.net dans les statistiques de Netfilter : | ||
- | |||
- | [root@phoenix /]# iptables -L -v -n -t nat | ||
- | Chain PREROUTING (policy ACCEPT 3 packets, 252 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | | ||
- | Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | 0 0 MASQUERADE all -- * eth1 192.168.0.0/ | ||
- | | ||
- | Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | |||
- | Cette commande nous indique que 3 paquets ont été acceptés par le comportement par défaut de la chaîne " | ||
- | |||
- | [root@phoenix /]# iptables -L -v -n -t filter | ||
- | Chain INPUT (policy DROP 0 packets, 0 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | 0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 | ||
- | 0 0 ACCEPT all -- eth0 * 192.168.0.0/ | ||
- | | ||
- | Chain FORWARD (policy DROP 3 packets, 252 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | 0 0 ACCEPT all -- eth0 eth1 192.168.0.0/ | ||
- | 0 0 ACCEPT all -- eth1 eth0 0.0.0.0/0 192.168.0.0/ | ||
- | | ||
- | Chain OUTPUT (policy DROP 0 packets, 0 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | 0 0 ACCEPT all -- * lo 0.0.0.0/0 0.0.0.0/0 | ||
- | 0 0 ACCEPT all -- * eth0 192.168.0.0/ | ||
- | |||
- | Cette commande là nous indique que 3 paquets ont été détruits par le comportement par défaut de la chaîne " | ||
- | |||
- | Maintenant, changeons seulement le comportement par défaut de la table " | ||
- | |||
- | [root@phoenix /]# iptables -t filter -P FORWARD ACCEPT | ||
- | |||
- | Juste pour information, | ||
- | |||
- | Et relançons notre " | ||
- | | ||
- | PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data. | ||
- | 64 bytes from 192.168.0.2: | ||
- | 64 bytes from 192.168.0.2: | ||
- | 64 bytes from 192.168.0.2: | ||
- | |||
- | --- 192.168.0.2 ping statistics --- | ||
- | 3 packets transmitted, | ||
- | rtt min/ | ||
- | |||
- | QUOI !?!? Notre intrus peut accéder sans problème à l' | ||
- | |||
- | Oui, exactement. Regardons les statistiques d' | ||
- | |||
- | | ||
- | Chain INPUT (policy DROP 0 packets, 0 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:6000 | ||
- | 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:6000 | ||
- | 0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 | ||
- | 0 0 ACCEPT all -- eth0 * 192.168.0.0/ | ||
- | | ||
- | Chain FORWARD (policy ACCEPT 3 packets, 252 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | 3 252 ACCEPT all -- eth0 eth1 192.168.0.0/ | ||
- | 0 0 ACCEPT all -- eth1 eth0 0.0.0.0/0 192.168.0.0/ | ||
- | | ||
- | Chain OUTPUT (policy DROP 0 packets, 0 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp spt:6000 | ||
- | 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp spt:6000 | ||
- | 0 0 ACCEPT all -- * lo 0.0.0.0/0 0.0.0.0/0 | ||
- | 0 0 ACCEPT all -- * eth0 192.168.0.0/ | ||
- | |||
- | | ||
- | * 3 paquets sont passés par la cible " | ||
- | * 3 autres paquets ont utilisés la règle basée sur du suivi de connexion, partant du réseau sky.net et allant sur internet.net. Bien sûr, c'est tout à fait normal. Car pour Netfilter, une connexion sky.net -> internet.net est bien initialisée ou en relation avec une autre... | ||
- | |||
- | | ||
- | |||
- | | ||
- | Chain PREROUTING (policy ACCEPT 3 packets, 252 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | | ||
- | Chain POSTROUTING (policy ACCEPT 3 packets, 252 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | 0 0 MASQUERADE all -- * eth1 192.168.0.0/ | ||
- | | ||
- | Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | |||
- | 3 paquets sont passés par les chaînes " | ||
- | |||
- | De cette (longue) explication nous pourrons en tirer 3 leçons : | ||
- | * Il faut toujours initialiser les cibles par défaut, même pour les chaînes des tables que nous ne pensons peut-être pas utiliser. Il faut en toute situation connaître l' | ||
- | # Initialisation de la table FILTER | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | |||
- | # Initialisation de la table NAT | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | |||
- | # Initialisation de la table MANGLE | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | | ||
- | |||
- | * Avant de mettre en place un système de NAT, il faut bien prendre en compte tous les paramètres, | ||
- | * En cas de doute, ou de problème sur l' | ||
- | |||
- | Bien, l'IP masquerading étant vu, passons au port forwarding. | ||
- | | ||
- | Bien caché derrière notre firewall Phoenix, notre réseau sky.net ne craint plus grand chose. De plus, avec ce que nous avons vu au chapitre précédent, | ||
- | |||
- | | ||
- | |||
- | | ||
- | | ||
- | * Dans cette configuration, | ||
- | * Paradise devenant donc un serveur web à part entière, et du fait des risques énoncés, Phoenix devra donc s'en méfier comme de la peste. Fini les gentilles règles Netfilter laissant paradise.sky.net pleinement accéder à phoenix0.sky.net. Il faudra durcir tout cela, et utiliser le conntrack ! Dans notre esprit, paradise.sky.net devra devenir aussi soupçonnable que pirate.internet.net. | ||
- | * Enfin, dans le cas où un intrus prendrait le contrôle de Paradise, et même si Phoenix à des règles Netfilter très strictes, rien n' | ||
- | |||
- | En terme de sécurité informatique, | ||
- | |||
- | {{: | ||
- | |||
- | Mais revenons à un réseau un peu plus simple, et baissons d'un cran notre paranoïa. Nous allons supposer que la machine qui hébergera notre serveur HTTP est fiable, et que personne ne peut en prendre la main (ceci n'est qu'une hypothèse bien sûr !). Nous la laisserons donc dans le réseau sky.net, en compagnie des autres machines de notre réseau interne. | ||
- | |||
- | Que devons nous faire ? | ||
- | * Tout d' | ||
- | |||
- | [root@phoenix /]# modprobe iptable_nat | ||
- | [root@phoenix /]# iptables -t nat -F | ||
- | [root@phoenix /]# iptables -t nat -X | ||
- | [root@phoenix /]# iptables -t filter -P FORWARD DROP | ||
- | [root@phoenix /]# iptables -t nat -P PREROUTING ACCEPT | ||
- | [root@phoenix /]# iptables -t nat -P POSTROUTING ACCEPT | ||
- | [root@phoenix /]# iptables -t nat -P OUTPUT ACCEPT | ||
- | * Comme nous voulons partager un serveur HTTP, il peut être intéressant d' | ||
- | |||
- | [root@phoenix /]# iptables -t filter -A INPUT -i eth1 -s 0.0.0.0/0 -d 10.0.0.1 \ | ||
- | -p icmp -m state --state ! INVALID -j ACCEPT | ||
- | [root@phoenix /]# iptables -t filter -A OUTPUT -o eth1 -s 10.0.0.1 -d 0.0.0.0/0 \ | ||
- | -p icmp -m state --state RELATED, | ||
- | |||
- | Au passage, vous noterez qu'il n'est pas nécessaire d' | ||
- | * Nous allons maintenant faire suivre un certain type de paquets de l' | ||
- | |||
- | [root@phoenix /]# iptables -t filter -A FORWARD -i eth1 -o eth0 -s 0.0.0.0/0 \ | ||
- | -d 192.168.0.2 -p tcp --dport 80 \ | ||
- | -m state --state ! INVALID -j ACCEPT | ||
- | [root@phoenix /]# iptables -t filter -A FORWARD -i eth0 -o eth1 -s 192.168.0.2 \ | ||
- | -d 0.0.0.0/0 -p tcp --sport 80 \ | ||
- | -m state --state RELATED, | ||
- | |||
- | * Nous arrivons à la 1er spécificité du "port forwarding" | ||
- | |||
- | [root@phoenix /]# iptables -t nat -A PREROUTING -i eth1 -s 0.0.0.0/0 \ | ||
- | -d 10.0.0.1 -p tcp --dport 80 \ | ||
- | -m state --state ! INVALID -j DNAT --to-destination 192.168.0.2: | ||
- | |||
- | Au passage, on voit que l'on peut aussi modifier le port de destination, | ||
- | * La seconde spécificité du "port forwarding", | ||
- | |||
- | [root@phoenix /]# iptables -t nat -A POSTROUTING -o eth0 -s 0.0.0.0/0 \ | ||
- | -d 192.168.0.2 -p tcp --dport 80 \ | ||
- | -m state --state ! INVALID -j SNAT --to-source 192.168.0.1 | ||
- | |||
- | * Bien, au niveau de Netfilter, tout est configuré. Il nous reste qu'à activer le NAT par la commande que nous connaissons déjà : | ||
- | |||
- | [root@phoenix /]# echo 1 > / | ||
- | |||
- | Le script iptables décrit ici est téléchargeable [[http:// | ||
- | |||
- | Il ne nous reste plus qu'à vérifier que pirate.internet.net a bien accès à phoenix1.internet.net : | ||
- | < | ||
- | | ||
- | GET / | ||
- | < | ||
- | < | ||
- | < | ||
- | < | ||
- | < | ||
- | <meta name=" | ||
- | < | ||
- | <LINK REL=" | ||
- | <!-- Background white, links blue (unvisited), | ||
- | | ||
- | <body text="# | ||
- | <table border=0> | ||
- | <tr> | ||
- | <td valign=top>< | ||
- | ALT=" | ||
- | <td valign=top width=100%>< | ||
- | </ | ||
- | </ | ||
- | |||
- | La fin de la réponse a été tronquée. Bien que l'on accède à phoenix1.internet.net, | ||
- | |||
- | [root@paradise /]# tail -1 / | ||
- | 192.168.0.1 - - [06/ | ||
- | |||
- | On voit la connexion faite par pirate.internet.net, | ||
- | |||
- | Enfin, regardons ce que nous donne les statistiques de Netfilter sur Phoenix : | ||
- | |||
- | [root@phoenix /]# iptables -L -v -n -t filter | ||
- | Chain INPUT (policy DROP 0 packets, 0 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:6000 | ||
- | 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:6000 | ||
- | 0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 | ||
- | 0 0 ACCEPT all -- eth0 * 192.168.0.0/ | ||
- | 0 0 ACCEPT icmp -- eth1 * 0.0.0.0/0 10.0.0.1 state NEW, | ||
- | ESTABLISHED | ||
- | | ||
- | Chain FORWARD (policy DROP 0 packets, 0 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | 8 430 ACCEPT tcp -- eth1 eth0 0.0.0.0/0 192.168.0.2 tcp dpt:80 state | ||
- | NEW, | ||
- | 8 7412 ACCEPT tcp -- eth0 eth1 192.168.0.2 0.0.0.0/0 tcp spt:80 state | ||
- | RELATED, | ||
- | | ||
- | Chain OUTPUT (policy DROP 0 packets, 0 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp spt:6000 | ||
- | 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp spt:6000 | ||
- | 0 0 ACCEPT all -- * lo 0.0.0.0/0 0.0.0.0/0 | ||
- | 0 0 ACCEPT all -- * eth0 0.0.0.0/0 192.168.0.0/ | ||
- | 0 0 ACCEPT icmp -- * eth1 10.0.0.1 0.0.0.0/0 state RELATED, | ||
- | ESTABLISHED | ||
- | [root@phoenix /]# iptables -L -v -n -t nat | ||
- | Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | 1 60 DNAT tcp -- eth1 * 0.0.0.0/0 10.0.0.1 tcp dpt:80 state NEW, | ||
- | ESTABLISHED to: | ||
- | | ||
- | Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | 1 60 SNAT tcp -- * eth0 0.0.0.0/0 192.168.0.2 tcp dpt:80 state NEW, | ||
- | ESTABLISHED to: | ||
- | |||
- | La requête et l' | ||
- | |||
- | On voit bien que les paquets entrant dans phoenix1.internet.net sont bien passés par les cibles " | ||
- | |||
- | Nous pourrions nous arrêter ici pour le port fowarding, mais un dernier point est intéressant à soulever : que se passe t'il si nous n' | ||
- | |||
- | Commençons par retirer cette règle : | ||
- | |||
- | [root@phoenix /]# iptables -D POSTROUTING 1 -t nat | ||
- | |||
- | Puis, indiquons à Paradise que sa passerelle est phoenix0.sky.net | ||
- | |||
- | [root@paradise /]# route add default gw phoenix0.sky.net | ||
- | [root@paradise /]# route | ||
- | | ||
- | Table de routage IP du noyau | ||
- | Destination Passerelle Genmask Indic Metric Ref Use Iface | ||
- | 192.168.0.0 * 255.255.255.0 U 0 0 0 eth0 | ||
- | 127.0.0.0 * 255.0.0.0 U 0 0 0 lo | ||
- | default phoenix0.sky.ne 0.0.0.0 UG 0 0 0 eth0 | ||
- | |||
- | Et maintenant, demandons à nouveau notre page HTML depuis pirate.internet.net. Suite à cette connexion, les statistiques d'" | ||
- | |||
- | [root@phoenix /]# iptables -L -v -n -t nat | ||
- | Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | 1 60 DNAT tcp -- eth1 * 0.0.0.0/0 10.0.0.1 tcp dpt:80 state NEW, | ||
- | ESTABLISHED to: | ||
- | | ||
- | Chain POSTROUTING (policy ACCEPT 1 packets, 60 bytes) | ||
- | pkts bytes target prot opt in out source destination | ||
- | | ||
- | Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) | ||
- | |||
- | Comme précédemment, | ||
- | |||
- | Enfin ce qui est le plus intéressant c'est le log d' | ||
- | |||
- | [root@paradise /]# tail -1 / | ||
- | 10.0.0.66 - - [06/ | ||
- | |||
- | Cette fois ci, c'est bien l' | ||
- | |||
- | Vous trouverez le script de cet exemple ici, mais comme indiqué, plus haut c'est la méthode " | ||
- | |||
- | Ceci conclue donc l' | ||
- | |||
- | Pas utile donc ? En fait non, il y a bien un usage personnel fort utile où l'on peut utiliser le port forwarding, et qui est particulièrement à la mode au jour où j' | ||
- | |||
- | Avec les explications ci-dessus, vous pouvez sans difficulté écrire vos propres scripts iptables afin de renvoyer vos connexions entrantes vers la machine sur lequel tourne votre client P2P. Cependant, souvenez vous que vous ne faites que déplacer le problème de sécurité sur cette machine ci, et donc que c'est à vous d'en assurer la responsabilité. Si cette machine est par exemple sous Windows®, la présence de Netfilter en tête de votre réseau ne vous dispense pas de mettre en place un firewall logiciel sur cette machine, afin par exemple de surveiller ce que fait votre Windows®. Ceci étant, je me lave les mains de ce que vous pourriez faire de l' | ||
- | |||
- | Enfin, je dirais que la mise en place du port forwarding n'est pas forcément ce qui se fait le plus facilement, bien qu'en fait les règles ne soit pas beaucoup plus complexes que pour l'IP masquerading. Sur Internet, vous trouverez beaucoup de bribes d' | ||
- | |||
- | |||
- | ====== Log (LOG / ULOG) ====== | ||
- | |||
- | Jusqu' | ||
- | |||
- | Dans ce qui suis, nous allons utiliser l' | ||
- | |||
- | ===== LOG ===== | ||
- | |||
- | C'est la méthode la plus standard pour logger des trames. Il s'agit simplement de créer une règle " | ||
- | |||
- | | ||
- | |||
- | Comme Netfilter est un élément du Kernel, ses logs sont donc des logs de ce dernier. Et comme tout bon log Kernel, ils se retrouve dans le fichier "/ | ||
- | | ||
- | | ||
- | | ||
- | Note: Host seems down. If it is really up, but blocking our ping probes, try -P0 | ||
- | Nmap run completed -- 1 IP address (0 hosts up) scanned in 30 seconds | ||
- | |||
- | | ||
- | Jul 8 23:04:59 phoenix nmbd[2178]: [2003/07/08 23:04:59, 0]] nmbd/ | ||
- | Jul 8 23:04:59 phoenix nmbd[2178]: send_netbios_packet: | ||
- | Jul 8 23:04:59 phoenix nmbd[2178]: [2003/07/08 23:04:59, 0] nmbd/ | ||
- | Jul 8 23:04:59 phoenix nmbd[2178]: query_name: Failed to send packet trying to query name WORKGROUP | ||
- | Jul 8 23:07:03 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=28 TOS=0x00 PREC=0x00 | ||
- | TTL=38 ID=41593 PROTO=ICMP TYPE=8 CODE=0 ID=58020 SEQ=0 | ||
- | Jul 8 23:07:03 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=40 TOS=0x00 PREC=0x00 | ||
- | TTL=39 ID=51459 PROTO=TCP SPT=53120 DPT=80 WINDOW=4096 RES=0x00 ACK URGP=0 | ||
- | Jul 8 23:07:09 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=28 TOS=0x00 PREC=0x00 | ||
- | TTL=38 ID=2581 PROTO=ICMP TYPE=8 CODE=0 ID=58020 SEQ=256 | ||
- | Jul 8 23:07:09 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=40 TOS=0x00 PREC=0x00 | ||
- | TTL=39 ID=27444 PROTO=TCP SPT=53121 DPT=80 WINDOW=4096 RES=0x00 ACK URGP=0 | ||
- | Jul 8 23:07:15 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=28 TOS=0x00 PREC=0x00 | ||
- | TTL=38 ID=29887 PROTO=ICMP TYPE=8 CODE=0 ID=58020 SEQ=512 | ||
- | Jul 8 23:07:15 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=40 TOS=0x00 PREC=0x00 | ||
- | TTL=39 ID=48409 PROTO=TCP SPT=53122 DPT=80 WINDOW=4096 RES=0x00 ACK URGP=0 | ||
- | Jul 8 23:07:21 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=28 TOS=0x00 PREC=0x00 | ||
- | TTL=38 ID=37813 PROTO=ICMP TYPE=8 CODE=0 ID=58020 SEQ=768 | ||
- | Jul 8 23:07:21 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=40 TOS=0x00 PREC=0x00 | ||
- | TTL=39 ID=17449 PROTO=TCP SPT=53123 DPT=80 WINDOW=4096 RES=0x00 ACK URGP=0 | ||
- | Jul 8 23:07:27 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=28 TOS=0x00 PREC=0x00 | ||
- | TTL=38 ID=57294 PROTO=ICMP TYPE=8 CODE=0 ID=58020 SEQ=1024 | ||
- | Jul 8 23:07:27 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 LEN=40 TOS=0x00 PREC=0x00 | ||
- | TTL=39 ID=64622 PROTO=TCP SPT=53124 DPT=80 WINDOW=4096 RES=0x00 ACK URGP=0 | ||
- | |||
- | Grâce au log, on voit que phoenix1.internet.net reçoit une série de commandes " | ||
- | |||
- | Un moyen pratique de suivre ses logs en temps réel est la commande, lancé en temps que root : "tail -f / | ||
- | |||
- | Mais ce fichier sert aussi (surtout !) à stocker tout les messages d' | ||
- | |||
- | [root@phoenix /]# iptables -t filter -A INPUT -s 10.0.0.66 -j LOG --log-prefix=" | ||
- | [root@phoenix /]# iptables -t filter -A INPUT -s 10.0.0.200 -j LOG --log-prefix=" | ||
- | |||
- | indiquera clairement les connexions faites par les machines pirate.internet.net et web.internet.net : | ||
- | |||
- | [intrus@pirate /]$ nmap -p 80 phoenix1.internet.net | ||
- | [intrus@web /]$ nmap -p 80 phoenix1.internet.net | ||
- | [root@phoenix /]# tail -f / | ||
- | Jul 8 23:26:06 phoenix kernel: AttackPirate IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ... | ||
- | Jul 8 23:26:06 phoenix kernel: AttackWeb IN=eth1 OUT= SRC=10.0.0.200 DST=10.0.0.1 ... | ||
- | Jul 8 23:26:12 phoenix kernel: AttackPirate IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ... | ||
- | Jul 8 23:26:12 phoenix kernel: AttackWeb IN=eth1 OUT= SRC=10.0.0.200 DST=10.0.0.1 ... | ||
- | Jul 8 23:26:12 phoenix kernel: AttackPirate IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ... | ||
- | Jul 8 23:26:12 phoenix kernel: AttackWeb IN=eth1 OUT= SRC=10.0.0.200 DST=10.0.0.1 ... | ||
- | Jul 8 23:26:25 phoenix kernel: AttackPirate IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ... | ||
- | Jul 8 23:26:28 phoenix kernel: AttackPirate IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ... | ||
- | Jul 8 23:26:34 phoenix kernel: AttackPirate IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ... | ||
- | |||
- | Cependant, cette méthode de log a l' | ||
- | |||
- | Une autre méthode est de définir un " | ||
- | |||
- | [root@phoenix /]# iptables -t filter -A INPUT -j LOG --log-level=4 | ||
- | [root@phoenix /]# less / | ||
- | #define LOG_WARNING 4 /* warning conditions */ | ||
- | [root@phoenix /]# less / | ||
- | kern.=warn -/ | ||
- | [intrus@pirate /]$ nmap -p 80 phoenix1.internet.net | ||
- | | ||
- | Starting nmap V. 3.00 ( www.insecure.org/ | ||
- | Note: Host seems down. If it is really up, but blocking our ping probes, try -P0 | ||
- | Nmap run completed -- 1 IP address (0 hosts up) scanned in 60 seconds | ||
- | [root@phoenix /]# tail -10 / | ||
- | Jul 8 18:55:43 phoenix kernel: MSDOS FS: Using codepage 850 | ||
- | Jul 8 19:26:34 phoenix kernel: i2c-amd756.o version 2.7.0 (20021208) | ||
- | Jul 8 19:26:34 phoenix kernel: i2c-amd756.o: | ||
- | Jul 8 19:28:37 phoenix kernel: UDF-fs: No VRS found | ||
- | Jul 8 23:53:58 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ... | ||
- | Jul 8 23:54:01 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ... | ||
- | Jul 8 23:54:07 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ... | ||
- | Jul 8 23:54:10 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ... | ||
- | Jul 8 23:54:13 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ... | ||
- | Jul 8 23:54:19 phoenix kernel: IN=eth1 OUT= SRC=10.0.0.66 DST=10.0.0.1 ... | ||
- | |||
- | Comme on le voit, bien que les log de Netfilter soient isolés dans un fichiers à part (/ | ||
- | |||
- | On pourrait s' | ||
- | |||
- | Alors ? Stocker ces logs à part est vraiment une chose impossible sous Linux ? Non, heureusement que non ! La solution s' | ||
- | |||
- | |||
- | ===== ULOG ===== | ||
- | |||
- | ULOG est module du Kernel dont le développement a été fait par http:// | ||
- | * Kernel récent : il faut un Kernel >= 2.4.18-pre8 pour pouvoir utiliser ce module. | ||
- | * Option de compilation : il faut que votre kernel soit compilé avec l' | ||
- | * Une fois compilé, le module ipt_ULOG.o doit se trouver sur votre disque dur (/ | ||
- | |||
- | [root@phoenix /]# find / | ||
- | / | ||
- | |||
- | Sur une distribution " | ||
- | * Vous devez récupérer et installer le demon " | ||
- | * Il faut configurer le demon ulogd. Pour cela, il faut éditer son fichier de configuration. Vous pouvez utiliser le mien. Les 2 informations importantes sont de spécifier qu' | ||
- | * Le demon ULOG (" | ||
- | |||
- | [root@phoenix scripts]# ls -la / | ||
- | -rwxr--r-- 1 root root 1821 jui 9 00:30 / | ||
- | [root@phoenix scripts]# ls -la / | ||
- | lrwxrwxrwx 1 root root 15 mai 4 21:02 / | ||
- | |||
- | Une fois que tout ceci est mis en place : | ||
- | * Démarrez le demon ulog . Par exemple : | ||
- | |||
- | [root@phoenix /]# / | ||
- | |||
- | * Vérifiez que le démon fonctionne correctement : | ||
- | |||
- | [root@phoenix /]# cat / | ||
- | Wed Jul 9 00:50:27 2003 <3> ulogd.c:474 ulogd Version 1.00 starting | ||
- | Wed Jul 9 00:50:27 2003 <5> ulogd.c:688 initialization finished, entering main loop | ||
- | |||
- | * Configurez Netfilter pour qu'il utilise la cible ULOG au lieu de la cible LOG. Ici, on log tout ce qui va être supprimé par la chaîne " | ||
- | |||
- | [root@phoenix /]# iptables -t filter -A INPUT -p all -j ULOG --ulog-prefix=DefaultDrop | ||
- | |||
- | * Et attendez qu'un intrus vienne se frotter à votre Netfiler : | ||
- | |||
- | [root@phoenix /]# tail -f / | ||
- | Jul 8 20:24:22 phoenix DefaultDrop IN=ppp0 OUT= MAC= SRC=xx.xx.xx.xx DST=62.147.74.21 LEN=61 | ||
- | TOS=00 PREC=0x00 TTL=60 ID=0 DF PROTO=UDP SPT=53 DPT=32796 LEN=41 | ||
- | Jul 8 20:24:22 phoenix DefaultDrop IN=ppp0 OUT= MAC= SRC=xx.xx.xx.xx DST=62.147.74.21 LEN=40 | ||
- | TOS=00 PREC=0x00 TTL=251 ID=0 DF PROTO=TCP SPT=110 DPT=33108 SEQ=0 | ||
- | ACK=1355878989 WINDOW=0 ACK RST URGP=0 | ||
- | Jul 8 20:24:32 phoenix DefaultDrop IN=ppp0 OUT= MAC= SRC=xx.xx.xx.xx DST=62.147.74.21 LEN=61 | ||
- | TOS=00 PREC=0x00 TTL=60 ID=0 DF PROTO=UDP SPT=53 DPT=32797 LEN=41 | ||
- | Jul 8 20:24:54 phoenix DefaultDrop IN=ppp0 OUT= MAC= SRC=xx.xx.xx.xx DST=62.147.74.21 | ||
- | LEN=61 TOS=00 PREC=0x00 TTL=60 ID=0 DF PROTO=UDP SPT=53 DPT=32799 LEN=41 | ||
- | Jul 8 20:25:04 phoenix DefaultDrop IN=ppp0 OUT= MAC= SRC=xx.xx.xx.xx DST=62.147.74.21 | ||
- | LEN=61 TOS=00 PREC=0x00 TTL=60 ID=0 DF PROTO=UDP SPT=53 DPT=32800 LEN=41 | ||
- | Jul 8 20:25:22 phoenix DefaultDrop IN=ppp0 OUT= MAC= SRC=xx.xx.xx.xx DST=62.147.74.21 | ||
- | LEN=78 TOS=00 PREC=0x00 TTL=104 ID=36090 PROTO=UDP SPT=1034 DPT=137 LEN=58 | ||
- | Jul 8 20:25:28 phoenix DefaultDrop IN=ppp0 OUT= MAC= SRC=xx.xx.xx.xx DST=62.147.74.21 | ||
- | LEN=40 TOS=00 PREC=0x00 TTL=251 ID=0 DF PROTO=TCP SPT=110 DPT=33220 SEQ=0 | ||
- | ACK=1428948021 WINDOW=0 ACK RST URGP=0 | ||
- | Jul 8 20:25:34 phoenix DefaultDrop IN=ppp0 OUT= MAC= SRC=xx.xx.xx.xx DST=62.147.74.21 | ||
- | LEN=61 TOS=00 PREC=0x00 TTL=60 ID=0 DF PROTO=UDP SPT=53 DPT=32802 LEN=41 | ||
- | Jul 8 20:25:38 phoenix DefaultDrop IN=ppp0 OUT= MAC= SRC=xx.xx.xx.xx DST=62.147.74.21 | ||
- | LEN=61 TOS=00 PREC=0x00 TTL=60 ID=0 DF PROTO=UDP SPT=53 DPT=32803 LEN=41 | ||
- | |||
- | Ceci n'est qu'une simple portion de mon log de Netfilter, lors d'une connexion en RTC le 8 Juillet 2003. Remarquez le temps plutôt faible entre les accès. Il s'agit en fait de plusieurs "port scan" effectués par plusieurs machines... Et encore, mon Netfilter est configuré pour ne pas afficher les logs des requêtes P2P qui, bien que je n'ai aucun client P2P, inondent régulièrement ma machine... | ||
- | |||
- | Tout comme la cible LOG, la cible ULOG a des options intéressantes : | ||
- | * --ulog-prefix : préfixe des log. Même chose que pour " | ||
- | * --ulog-nlgroup : similaire à " | ||
- | |||
- | Conclusion : si vous voulez avoir des logs bien exploitables de votre Netfilter, utilisez ULOG plutôt que LOG. Ce n'est finalement pas si compliqué à installer, et c'est très pratique. Enfin, pour les maniaques de la sécurité qui ont plein de place disque et du CPU à revendre, vous pouvez spécifier au demon " | ||
- | |||
- | |||
- | ====== Autres astuces ====== | ||
- | |||
- | ===== Règles par défaut (" | ||
- | |||
- | Jusqu' | ||
- | |||
- | Donc il est est primordial que la première chose que vous fassiez dans un script Netfilter, c'est d' | ||
- | |||
- | [root@phoenix /]# iptables -t filter -F | ||
- | [root@phoenix /]# iptables -t filter -X | ||
- | [root@phoenix /]# iptables -t filter -P INPUT DROP | ||
- | [root@phoenix /]# iptables -t filter -P FORWARD DROP | ||
- | [root@phoenix /]# iptables -t filter -P OUTPUT DROP | ||
- | [root@phoenix /]# iptables -t nat -F | ||
- | [root@phoenix /]# iptables -t nat -X | ||
- | [root@phoenix /]# iptables -t nat -P PREROUTING ACCEPT | ||
- | [root@phoenix /]# iptables -t nat -P OUTPUT ACCEPT | ||
- | [root@phoenix /]# iptables -t nat -P POSTROUTING ACCEPT | ||
- | [root@phoenix /]# iptables -t mangle -F | ||
- | [root@phoenix /]# iptables -t mangle -X | ||
- | [root@phoenix /]# iptables -t mangle -P PREROUTING ACCEPT | ||
- | [root@phoenix /]# iptables -t mangle -P INPUT ACCEPT | ||
- | [root@phoenix /]# iptables -t mangle -P FORWARD ACCEPT | ||
- | [root@phoenix /]# iptables -t mangle -P OUTPUT ACCEPT | ||
- | [root@phoenix /]# iptables -t mangle -P POSTROUTING ACCEPT | ||
- | |||
- | Vous remarquerez que l'on définie à " | ||
- | |||
- | Ce n'est pas non plus une mauvaise chose que de désactiver en début de script, au moins temporairement, | ||
- | echo 0 > / | ||
- | |||
- | |||
- | ===== Chaînes utilisateurs ===== | ||
- | |||
- | Nous avons peu parlé des chaînes utilisateurs, | ||
- | |||
- | [root@phoenix /]# iptables -t filter -A INPUT -i eth0 -s 192.168.0.2 -p icmp -j LOG | ||
- | [root@phoenix /]# iptables -t filter -A INPUT -i eth0 -s 192.168.0.2 -p icmp -j DROP | ||
- | [root@phoenix /]# iptables -t filter -A INPUT -i eth0 -s 192.168.0.3 -p icmp -j LOG | ||
- | [root@phoenix /]# iptables -t filter -A INPUT -i eth0 -s 192.168.0.3 -p icmp -j DROP | ||
- | [root@phoenix /]# iptables -t filter -A INPUT -i eth1 -p icmp -j LOG | ||
- | [root@phoenix /]# iptables -t filter -A INPUT -i eth1 -p icmp -j DROP | ||
- | |||
- | Dans ces cas, les règles utilisateurs sont là pour simplifier la vie. Commençons par écrire notre propre règle " | ||
- | |||
- | [root@phoenix /]# iptables -t filter -N LogDrop | ||
- | [root@phoenix /]# iptables -t filter -A LogDrop -j LOG --log-prefix LogDrop | ||
- | [root@phoenix /]# iptables -t filter -A LogDrop -j DROP | ||
- | |||
- | Puis, appelons la pour nos pings sur les réseaux locaux : | ||
- | |||
- | [root@phoenix /]# iptables -t filter -A INPUT -i eth0 -s 192.168.0.2 -p icmp -j LogDrop | ||
- | [root@phoenix /]# iptables -t filter -A INPUT -i eth0 -s 192.168.0.3 -p icmp -j LogDrop | ||
- | |||
- | Et les réseaux externes : | ||
- | |||
- | [root@phoenix /]# iptables -t filter -A INPUT -i eth1 -p icmp -j LogDrop | ||
- | |||
- | On note au passage que notre chaîne " | ||
- | |||
- | |||
- | ===== Script final d' | ||
- | |||
- | Nous avons vu jusqu' | ||
- | |||
- | Avant toute chose, il faudra que vous le configuriez à votre usage. Pour cela, le début du script contient un certain nombre de variables globales, qui définissent le comportement du script : | ||
- | * LAN_* (Local Area Network) : ces variables définisent le réseau local. Dans notre exemple, il s'agit du réseau " | ||
- | * WAN_* (Wan Area Network) : là, il s'agit des variables définissant le réseau Internet. Elles sont spécialement conçues pour un réseau connecté par l' | ||
- | * NAT (Network Adress Translation) : cette variable définie si ou non vous voulez autorisez les machines de votre réseau interne à se connecter à Internet. | ||
- | * PF_* (Port Forwarding) : ces variables définissent si ou non vous voulez faire du port forwarding. Notez que j'ai pris ici l' | ||
- | |||
- | Quelques remarques à propos de ce script : | ||
- | * Toutes les règles Netfilter qui contrôlent l' | ||
- | |||
- | [root@phoenix /]# iptables -t filter -A OUTPUT -o $WAN_INTERFACE -s $WAN_IP -d $WAN_NETWORK \ | ||
- | -p all -m state --state ! INVALID -j ACCEPT | ||
- | [root@phoenix /]# iptables -t filter -A INPUT -i $WAN_INTERFACE -s $WAN_NETWORK -d $WAN_IP \ | ||
- | -p all -m state --state RELATED, | ||
- | |||
- | Ces autres scripts écriraient : | ||
- | |||
- | [root@phoenix /]# iptables -t filter -A OUTPUT -o $WAN_INTERFACE -d $WAN_NETWORK \ | ||
- | -p all -m state --state ! INVALID -j ACCEPT | ||
- | [root@phoenix /]# iptables -t filter -A INPUT -i $WAN_INTERFACE -s $WAN_NETWORK \ | ||
- | -p all -m state --state RELATED, | ||
- | |||
- | C'est effectivement plus simple à écrire, mais personnellement je n'ai pas confiance en ce type d' | ||
- | o On peut toujours craindre une attaque malicieuse où un intrus nous enverrait un paquet mal formé, avec une adresse IP qui n'est pas la nôtre. C'est spécialement faisable si l' | ||
- | o " | ||
- | Conclusion : dans le doute, je m' | ||
- | |||
- | Mais ce choix a un désavantage important : pour que ce script soit fonctionnel, | ||
- | |||
- | Pour des raisons de sécurité, je vous conseille de donner la propriété de ce fichier au root, et de le laisser en écriture uniquement pour le super utilisateur. | ||
- | Exemple : | ||
- | |||
- | [root@phoenix /]# chown root:root / | ||
- | [root@phoenix /]# chroot 755 / | ||
- | |||
- | (*): en fait, ce n'est pas une obligation absolue. Et cela dépend en partie de l' | ||
- | * Dans ce script, vous pouvez voir que les règles de port forwarding sont situées avant celles d'IP masquerading. Simple effet de style de ma part ? Non, pas du tout. Un paquet venant d' | ||
- | |||
- | iptables -t filter -A FORWARD -i $WAN_INTERFACE -o $LAN_INTERFACE -s $WAN_NETWORK -d $LAN_NETWORK \ | ||
- | -p $PF_PROTO --dport $PF_PORT -m state --state ! INVALID -j ACCEPT | ||
- | iptables -t filter -A FORWARD -i $WAN_INTERFACE -o $LAN_INTERFACE -s $WAN_NETWORK -d $LAN_NETWORK \ | ||
- | -p all -m state --state ESTABLISHED, | ||
- | |||
- | De même que pour les paquets sortants de la machine et ayant pour source le port 80 : | ||
- | iptables -t filter -A FORWARD -i $LAN_INTERFACE -o $WAN_INTERFACE -s $LAN_NETWORK -d $WAN_NETWORK \ | ||
- | -p $PF_PROTO --sport $PF_PORT -m state --state ESTABLISHED, | ||
- | 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 | ||
- | |||
- | Dans les 2 cas, la 1ère règle est une règle de port forwarding et la 2nd d'IP masquerading. Mais comme les 2nd règles sont plus générales que les premières, les statistiques de Netfilter (commande " | ||
- | Cet exemple est intéressant, | ||
- | * Notez enfin que les différents modules de Netfilter (" | ||
- | |||
- | |||
- | ===== Autres scripts ===== | ||
- | A titre d' | ||
- | Nom du script Description | ||
- | iptables-extrem-accept.sh Ce script vide toutes les chaînes prédéfinies et supprime toute les chaînes utilisateurs de toutes les tables. C'est utile si vous voulez revenir à une configuration de Netfilter complètement vierge, et aussi complètement insécurisée. Bref, c'est la configuration que vous avez probablement actuellement ! | ||
- | iptables-extrem-drop.sh Ce script est pour les ultra paranoïaques, | ||
- | |||
- | |||
- | ===== Tests d' | ||
- | Une fois que toutes vos règles iptables sont écrites, il vous faut vous-même tester la sécurité de votre Linux en pratiquant des tests d' | ||
- | |||
- | Dans le cadre du réseau proposé ici, il m'a été facile de tester les 2 interfaces réseaux de Phoenix, en lançant les tests depuis Paradise et Pirate. Cependant, dans le cadre d'une utilisation personnelle, | ||
- | |||
- | Il vous faut donc faire confiance à une personne externe à votre réseau, situé sur Internet, pour tester vos règles de Firewall. Pour cela, 3 possibilités : | ||
- | * Vous avez un accès en " | ||
- | * Vous demandez à un de vos amis de faire ce test pour vous. Encore faut il qu'il sache ce qu'est " | ||
- | * Enfin, vous pouvez faire faire ce test par un site web. Certains sites proposent gratuitement ce genre de prestation, entre autre pour vous proposer des solutions de firewall ... Windows® | ||
- | |||
- | Quelques soit ces sites, leurs tests ne sont souvent pas très poussés, et se limitent parfois qu'aux seuls ports ouverts par défaut sous Windows®. De plus, un simple test de "port scanning" | ||
- | |||
- | |||
- | ===== Sauvegarde des règles Netfilter ===== | ||
- | |||
- | Supposons que vous n' | ||
- | |||
- | [root@phoenix /]# iptables -t filter -A OUTPUT -o ppp0 -d 0.0.0.0/0 \ | ||
- | -p all -m state --state ! INVALID -j ACCEPT | ||
- | [root@phoenix /]# iptables -t filter -A INPUT -i ppp0 -s 0.0.0.0/0 \ | ||
- | -p all -m state --state RELATED, | ||
- | |||
- | Dans ce cas, vos règles Netfilter sont génériques, | ||
- | |||
- | [root@phoenix /]# / | ||
- | |||
- | Enfin, pour que le Netfilter soit opérationnel à chaque démarrage, il faut créer les liens symboliques adéquates dans le /etc/rc.d/ : | ||
- | |||
- | [root@phoenix /]# cd / | ||
- | [root@phoenix /]# ln -s ../ | ||
- | [root@phoenix /]# cd / | ||
- | [root@phoenix /]# ln -s ../ | ||
- | |||
- | Au démarrage, votre Linux lancera le script / | ||
- | Si à un moment vous avez besoin d' | ||
- | |||
- | [root@phoenix /]# / | ||
- | |||
- | |||
- | ====== Questions fréquentes ====== | ||
- | |||
- | **Question :** Existe t'il une interface graphique pour iptables ? | ||
- | | ||
- | **Réponse :** | ||
- | Oui firestarter | ||
- | sudo aptitude install firestarter | ||
- | |||
- | < | ||
- | |||
- | **Question :** Comment Voir les régles de firewall en détails : | ||
- | | ||
- | **Réponse :** | ||
- | iptables -L -v -n --line-numbers | ||
- | |||
- | < | ||
- | |||
- | **Question :** Comment forwarder des ports avec iptables ? | ||
- | |||
- | **Réponse :** | ||
- | iptables -t nat -A PREROUTING -p tcp --dport NUMERO_PORT_DESTINATION -i INTERFACE -j DNAT --to-destination IP_DESTINATION: | ||
- | |||
- | **Exemple :** Vous voulez forwarder le port 80 recu sur voter serveur sur l' | ||
- | Cela donne : | ||
- | iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth0 -j DNAT --to-destination 192.168.0.5: | ||
- | |||
- | < | ||
- | |||
- | **Question :** Comment ouvrir/ | ||
- | |||
- | **Réponse :** | ||
- | |||
- | **Ouverture d'un seul port :** | ||
- | iptables -A INPUT -p tcp --sport NUMERO_PORT -j ACCEPT | ||
- | |||
- | **Ouverture d'une plage de ports :** | ||
- | iptables -A INPUT -p tcp --sport NUMERO_PORT_DEBUT: | ||
- | |||
- | **Fermeture de port :** | ||
- | Pour interdire un port il suffit de mettre REJECT ou DENY à la place de ACCEPT | ||
- | |||
- | **Exemples :** | ||
- | iptables -t filter -A OUTPUT -o eth0 -s 192.168.1.0/ | ||
- | iptables -t filter -A INPUT -i eth0 -d 192.168.1.0/ | ||
- | |||
- | ou encore (plus sécurisé) : | ||
- | |||
- | iptables -A OUTPUT -o eth0 -s 192.168.1.0/ | ||
- | iptables -A INPUT -i eth0 -s 0.0.0.0/0 -d 192.168.1.0/ | ||
- | |||
- | < | ||
- | |||
- | |||
- | **Question :** Comment insérer une régle entre 2 autres ? | ||
- | |||
- | **Réponse :** Insertion d'une régle en 3éme position des régles sortantes | ||
- | |||
- | iptables -t filter -I OUTPUT 3 -o eth0 -s 192.168.1.0/ | ||
- | |||
- | < | ||
- | |||
- | **Question :** Comment supprimer une régle ? | ||
- | |||
- | **Réponse :** Suppréssion de la régle N°3 des régles sortantes | ||
- | iptables -t filter -D OUTPUT 3 | ||
- | |||
- | < | ||
- | |||
- | **Question :** Comment lancer la configuration d' | ||
- | |||
- | **Réponse :** | ||
- | |||
- | Editez le fichier de configuration / | ||
- | |||
- | # | ||
- | # | ||
- | auto lo | ||
- | iface lo inet loopback | ||
- | address 127.0.0.1 | ||
- | netmask 255.0.0.0 | ||
- | | ||
- | #Démarrage de la carte | ||
- | # | ||
- | auto eth0 | ||
- | # | ||
- | #Adressage statique | ||
- | # | ||
- | iface eth0 inet static | ||
- | address 192.168.1.112 | ||
- | netmask 255.255.255.0 | ||
- | gateway 192.168.1.1 | ||
- | # | ||
- | #Pare-feu configuré avec Webmin | ||
- | # | ||
- | **pre-up iptables-restore < / | ||
- | | ||
- | auto eth1 | ||
- | # | ||
- | #Adressage dynamique | ||
- | # | ||
- | iface eth1 inet dhcp | ||
- | | ||
- | auto wlan0 | ||
- | iface wlan0 inet static | ||
- | address 192.168.1.111 | ||
- | netmask 255.255.255.0 | ||
- | gateway 192.168.1.1 | ||
- | # | ||
- | # | ||
- | # | ||
- | wireless-essid apwifi1 | ||
- | |||
- | < | ||
- | |||
- | Comment sécuriser le port ssh ? | ||
- | |||
- | / | ||
- | / | ||
- | |||
- | Cela limite les tentatives de connexions à 3 et bloque l'ip pendant 10 min si elle n'a pas reussit à s' | ||
- | |||
- | < | ||
- | |||
- | **Question :** Comment empêcher un [[http:// | ||
- | |||
- | **Réponse :** | ||
- | / | ||
- | |||
- | **Exemple :** | ||
- | Vous voulez vous prémenir des attaques de l' | ||
- | / | ||
- | |||
- | Pour faire la même chose sur les adresses de type : 127.0.0.X : | ||
- | / | ||
- | |||
- | < | ||
- | |||
- | **Question :** Comment bloquer le ping de mon Firewall depuis internet? | ||
- | |||
- | **Réponse :** | ||
- | / | ||
- | |||
- | On va bloquer sur l' | ||
- | |||
- | Il faut savoir que iptable permet de bloquer les icmp type soit en nommant me type (Cf man iptable) soit en indiquant sont numéro. Dans notre cas : | ||
- | echo-request = 8 | ||
- | |||
- | Ce qui nous donnera : | ||
- | / | ||
- | |||
- | Attention cette politique est à adapter en fonction de la configuration de base de votre firewall. Certains accepteront toute requete icmp par défaut, d' | ||
- | |||
- | Et dans le cas ci-dessus, le ping n'est pas rejeter (-j REJECT) mais mis à la " | ||
- | |||
- | < | ||
- | |||
- | **Question :** Comment bloquer les ports en sortie de mon firewall | ||
- | |||
- | **Réponse :** | ||
- | |||
- | Par défaut Iptables n'a pas de port ouvert vers l' | ||
- | |||
- | Dans le cas ou vous avez fait un script acceptant tout en sortie (il est préférable de faire l' | ||
- | |||
- | Voici la conduite à suivre : | ||
- | |||
- | Vérifiez que ces 3 variables n' | ||
- | #interface interne (lan) | ||
- | InternalIF=eth0 | ||
- | #interface externe (internet) | ||
- | OuterIF=eth1 | ||
- | #source réseau (l' | ||
- | Lan=192.168.0.0/ | ||
- | |||
- | Vérifiez aussi que la chaine que vous allez créer n' | ||
- | Création d'une nouvelle chaine | ||
- | / | ||
- | / | ||
- | |||
- | Refus d'un port de sortie pour la classe d' | ||
- | / | ||
- | |||
- | Refus d'une plage de port de sortie pour la classe d' | ||
- | / | ||
- | |||
- | Refus d'un port pour une adresse spécifique | ||
- | / | ||
- | |||
- | PROTOCOLE peut prendre la valeur tcp ou udp en fonction du protocole que vous voulez bloquer. | ||
- | PORT est le numéro de port que vous voulez bloquer. | ||
- | |||
- | < | ||
- | |||
- | **Question :** Comment sécuriser la pile TCP/IP ? | ||
- | |||
- | **Réponse :** En passant des paramètres au kernel | ||
- | |||
- | En pratique, on peut ajouter à son script iptables (ou au fichier / | ||
- | net.ipv4.conf.all.nom_action=0/ | ||
- | # Ignore 'ICMP Redirects' | ||
- | echo " | ||
- | | ||
- | # Ignore 'ICMP Echo Request' | ||
- | echo " | ||
- | echo " | ||
- | | ||
- | # Ignore 'ICMP Bogus Response' | ||
- | echo " | ||
- | | ||
- | # Interdire ' | ||
- | echo " | ||
- | | ||
- | # Surveiller ' | ||
- | echo " | ||
- | | ||
- | # Se protéger de l'IP Spoofing bis | ||
- | echo " | ||
- | | ||
- | # Se protéger des attaques 'SYN Flood' | ||
- | echo " | ||
- | |||
- | < | ||
- | |||
- | **Question :** Comment bloquer MSN avec iptables ? | ||
- | |||
- | **Réponse :** | ||
- | Suite à la suggestion de Muzo, voici un petit tuto sur le blocage de MSN. | ||
- | Dans ma config, une MNF sert de passerelle vers le web, les postes du LAN ont acès au Web via le proxy squid de la MNF. | ||
- | Le port classique de MSN (1863) est bloqué et celui-ci ne peut donc que passer par l' | ||
- | |||
- | J' | ||
- | |||
- | Remarque : les paquets venant du proxy, c'est dans la chaîne OUTPUT qu'il faut bloquer et non dans la chaîne FORWARD (cette dernière est à utiliser si les machines ne passent pas par le proxy mais que le 1863 bloqué les empêche de se connecter normalement). | ||
- | |||
- | Il suffit de lancer ces règles iptables par exemple pour bloquer : | ||
- | Nouvelle cible pour logguer les paquets | ||
- | / | ||
- | / | ||
- | / | ||
- | Blocage des paquets entrants des gateways MS | ||
- | (cette règle est à supprimer si on veut laisser l' | ||
- | / | ||
- | Blocage des paquets sortants pour les machines d' | ||
- | / | ||
- | / | ||
- | |||
- | et pour débloquer : | ||
- | Déblocage des paquets sortants pour les machines d' | ||
- | / | ||
- | / | ||
- | Déblocage des paquets entrants des gateways MS | ||
- | (dans le cas où on l'a utilisée au dessus bien entendu) | ||
- | / | ||
- | Suppression de la cible | ||
- | / | ||
- | / | ||
- | |||
- | < | ||
- | |||
- | Script de réinitilisation du firewall en mode sécurisé en autorisant les ports 21,22,443, : | ||
- | !/bin/sh | ||
- | | ||
- | #on commence par vider toutes les regles | ||
- | iptables --flush | ||
- | | ||
- | #par defaut on supprime tous les paquets | ||
- | iptables -P INPUT DROP | ||
- | iptables -P OUTPUT DROP | ||
- | iptables -P FORWARD DROP | ||
- | | ||
- | # | ||
- | iptables -t filter -A OUTPUT -o lo -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT | ||
- | iptables -t filter -A INPUT -i lo -s 0.0.0.0/0 -d 0.0.0.0/0 -j ACCEPT | ||
- | | ||
- | # | ||
- | iptables -t filter -A OUTPUT -o eth0 -s 192.168.1.0/ | ||
- | iptables -t filter -A INPUT -i eth0 -s 192.168.1.0/ | ||
- | | ||
- | #on supprime les connections entrantes si elles n'ont pas été initié par ma machine | ||
- | iptables -A INPUT -m state --state NEW -j DROP | ||
- | | ||
- | #on accepte les connections entrantes si elles ont été initiées par notre machine et les connections sortantes venant de la machine sur les ports 21, | ||
- | | ||
- | iptables -A OUTPUT -o eth0 -s 192.168.1.0/ | ||
- | iptables -A INPUT -i eth0 -s 0.0.0.0/0 -d 192.168.1.0/ | ||
- | | ||
- | iptables -A OUTPUT -o eth0 -s 192.168.1.0/ | ||
- | iptables -A INPUT -i eth0 -s 0.0.0.0/0 -d 192.168.1.0/ | ||
- | | ||
- | iptables -A OUTPUT -o eth0 -s 192.168.1.0/ | ||
- | iptables -A INPUT -i eth0 -s 0.0.0.0/0 -d 192.168.1.0/ | ||
- | | ||
- | iptables -A OUTPUT -o eth0 -s 192.168.1.0/ | ||
- | iptables -A INPUT -i eth0 -s 0.0.0.0/0 -d 192.168.1.0/ | ||
- | | ||
- | iptables -A OUTPUT -o eth0 -s 192.168.1.0/ | ||
- | iptables -A INPUT -i eth0 -s 0.0.0.0/0 -d 192.168.1.0/ | ||
- | | ||
- | #pour bloquer les requetes ping sur notre machine | ||
- | # iptables -A INPUT --protocol icmp --icmp-type echo-request -j DROP | ||
- | | ||
- | # log / | ||
- | iptables -t filter -A INPUT -d 192.168.1.0/ | ||
- | |||
- | * Exemple de script firewall sur mon serveur actuel : | ||
- | |||
- | #!/bin/sh | ||
- | | ||
- | #on commence par vider toutes les regles | ||
- | iptables --flush | ||
- | | ||
- | #par defaut on supprime tous les paquets | ||
- | iptables -P INPUT DROP | ||
- | iptables -P OUTPUT DROP | ||
- | iptables -P FORWARD DROP | ||
- | | ||
- | # | ||
- | iptables -t filter -A OUTPUT -o lo -j ACCEPT | ||
- | iptables -t filter -A INPUT -i lo -j ACCEPT | ||
- | | ||
- | # ICMP (Ping) | ||
- | iptables -t filter -A INPUT -p icmp -j ACCEPT | ||
- | iptables -t filter -A OUTPUT -p icmp -j ACCEPT | ||
- | | ||
- | # Ne pas casser les connexions etablies | ||
- | iptables -A INPUT -m state --state RELATED, | ||
- | iptables -A OUTPUT -m state --state RELATED, | ||
- | | ||
- | ### FTP ### | ||
- | #-- Sortie OK --# | ||
- | | ||
- | iptables -A OUTPUT -o eth0 -p tcp --dport 21 -m state --state ! INVALID -j ACCEPT | ||
- | | ||
- | | ||
- | #-- Entrée Ok --# | ||
- | iptables -A INPUT -i eth0 -p tcp --dport 21 -m state --state ! INVALID -j ACCEPT | ||
- | | ||
- | | ||
- | ### SSH ### | ||
- | #-- Sortie OK --# | ||
- | | ||
- | iptables -A OUTPUT -o eth0 -p tcp --dport 22 -m state --state ! INVALID -j ACCEPT | ||
- | | ||
- | | ||
- | #-- Entrée Ok --# | ||
- | iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state ! INVALID -j ACCEPT | ||
- | | ||
- | | ||
- | ### HTTP / HTTPS ### | ||
- | #-- ENTREE OK --# | ||
- | iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state ! INVALID -j ACCEPT | ||
- | | ||
- | #-- Entree OK --# | ||
- | iptables -A INPUT -i eth0 -p tcp --dport 443 -m state --state ! INVALID -j ACCEPT | ||
- | | ||
- | | ||
- | ### DNS ### | ||
- | #-- Sortie OK --# | ||
- | iptables -A OUTPUT -o eth0 -p tcp --dport 53 -m state --state ! INVALID -j ACCEPT | ||
- | iptables -A OUTPUT -o eth0 -p udp --dport 53 -m state --state ! INVALID -j ACCEPT | ||
- | | ||
- | #-- Entrée Ok --# | ||
- | iptables -A INPUT -i eth0 -p tcp --dport 53 -m state --state ! INVALID -j ACCEPT | ||
- | iptables -A INPUT -i eth0 -p udp --dport 53 -m state --state ! INVALID -j ACCEPT | ||
- | | ||
- | | ||
- | ### messagerie ### | ||
- | #-- Sortie OK --# | ||
- | iptables -A OUTPUT -o eth0 -p tcp --dport 25 -m state --state ! INVALID -j ACCEPT | ||
- | #-- Entrée Ok --# | ||
- | iptables -A INPUT -i eth0 -p tcp --dport 25 -m state --state ! INVALID -j ACCEPT | ||
- | | ||
- | #-- Sortie OK --# | ||
- | iptables -A OUTPUT -o eth0 -p tcp --dport 110 -m state --state ! INVALID -j ACCEPT | ||
- | #-- Entrée Ok --# | ||
- | iptables -A INPUT -i eth0 -p tcp --dport 110 -m state --state ! INVALID -j ACCEPT | ||
- | | ||
- | #-- Sortie OK --# | ||
- | iptables -A OUTPUT -o eth0 -p tcp --dport 143 -m state --state ! INVALID -j ACCEPT | ||
- | #-- Entrée Ok --# | ||
- | iptables -A INPUT -i eth0 -p tcp --dport 143 -m state --state ! INVALID -j ACCEPT | ||
- | | ||
- | #-- Sortie OK --# | ||
- | iptables -A OUTPUT -o eth0 -p tcp --dport 995 -m state --state ! INVALID -j ACCEPT | ||
- | #-- Entrée Ok --# | ||
- | iptables -A INPUT -i eth0 -p tcp --dport 995 -m state --state ! INVALID -j ACCEPT | ||
- | | ||
- | | ||
- | ### Teamspeak ### | ||
- | #-- Sortie OK --# | ||
- | iptables -A OUTPUT -o eth0 -p udp --dport 8767 -m state --state ! INVALID -j ACCEPT | ||
- | #-- Entrée Ok --# | ||
- | iptables -A INPUT -i eth0 -p udp --dport 8767 -m state --state ! INVALID -j ACCEPT | ||
- | | ||
- | | ||
- | ### rtorrent ### | ||
- | #-- Sortie OK --# | ||
- | iptables -A OUTPUT -o eth0 -p tcp --dport 6666 -m state --state ! INVALID -j ACCEPT | ||
- | #-- Entrée Ok --# | ||
- | iptables -A INPUT -i eth0 -p tcp --dport 6666 -m state --state ! INVALID -j ACCEPT | ||
iptables.1237070845.txt.gz · Dernière modification : 2009/03/14 22:47 de root