Soucis de redirection de paquet avec NAT

Bonjour (ou Bonsoir) !

Etant en stage de fin d’année, mon maître de stage m’a confié une petite tâche concernant un routage à mettre en place sur un réseau particulier.

Pour commencer, je vous ai réalisé une “magnifique” illustration de la topologie du réseau (j’ai essayé de m’appliquer le plus possible et j’y ai figuré que les éléments importants!)

Le but de l’opération est de pouvoir accéder au poste PC1 depuis Internet en passant par le routeur (donc par le réseau 192.168.0.0 et non le 172.16.0.0). Le firewall du routeur est déjà configuré pour accepter les connexions HTTP.
Pour être encore plus clair, quand je tape l’adresse A.B.C.D sur mon navigateur, je dois tomber sur la page d’accueil du PC1 (il s’agit d’un logiciel de vidéo-surveillance).

Pour l’instant, j’ai réussi à mettre en place un DNAT pour rediriger les paquets du serveur linux au PC1 depuis l’interface Eth2 mais j’arrive à y accéder seulement si j’utilise une route spécifique vers ce routeur : Par exemple, mon adresse IP internet commence par 80.X.X.X donc si j’utilise cette commande :

J’arrive à accéder à la page et tout marche…

Mais l’adresse IP d’internet est dynamique et change tout le temps (ça je le savais) donc j’ai voulu mettre une 2éme rouge par défaut avec un metric de 1 sur ce réseau (192.168.0.0). Cependant, les paquets qui sont envoyés au PC1 vont être envoyé sur le réseau 172.16.0.0 !
Donc je pense que je dois mettre en place un NAT sur le serveur Linux qui redirige les paquets (avec un IP source de 10.145.7.17) vers le port eth2 ! J’ai essayé plusieurs choses mais en vain …
Car j’ai utilisé le NAT sur du matériel Cisco principalement mais sur du Linux … je n’arrive pas à savoir la différence entre POSTROUTING/PREROUTING/FORWARD (l’un est rentrant, l’autre sortant? :confused: ) et ce fameux MASQUERADE que je n’arrive pas à mettre en oeuvre car je pense qu’il est utile dans mon cas (vu que je dois faire une connexion avec l’extérieur …)

Voili, voilou, je m’en remet à vous et je voudrais savoir quelles sont les solutions que vous me proposeriez ? Je serais disponible toute l’après-midi! Merci d’avance.

Dvlad

J’ai ma petite idée quand à la réponse.
Mais j’attend de voir ce que va répondre Pascal Hambourg qui connaît très bien iptables.

Ensuite, pour faire cela, je ne vois pas l’intérêt d’un 2d routeur, surtout que tu connais l’ip extérieur de ton firewall Debian. Bref, pour moi, tu te compliques les choses, mais je peux me tromper.
C’est pour cela que je préfères attendre sa réponse.

[quote=“PengouinPdt”]
Ensuite, pour faire cela, je ne vois pas l’intérêt d’un 2d routeur, surtout que tu connais l’ip extérieur de ton firewall Debian. Bref, pour moi, tu te compliques les choses, mais je peux me tromper.
C’est pour cela que je préfères attendre sa réponse.[/quote]

Ce n’est pas moi qui est l’origine de cette topologie. D’ailleurs, elle est dupliquée sur 15 sites : mon maître de stage doit avoir une explication à cela (par exemple, sur mes notes, vers le réseau 172.17.1.0, c’est là où se trouve la Wifi). Il voulait séparer différents trafics pour résumer :023

Quand je réalise cette commande sur le serveur Linux :

iptables -t nat -D PREROUTING -p tcp --dport 80 -i eth2 -j DNAT --to 192.168.0.1

Quand on demande l’adresse A.B.C.D, je reçois bien la page du PC1 mais j’ai toujours ce problème de routage pour internet!
Pour info, voici ma table de routage du serveur Debian :

[code]
debian:~# ip route list
192.168.0.0/24 dev eth2 proto kernel scope link src 192.168.0.2
10.145.7.0/24 dev eth0 proto kernel scope link src 10.145.7.12
172.17.1.0/24 dev eth1 proto kernel scope link src 172.17.1.2
10.0.0.0/8 via 10.145.7.20 dev eth0
default via 172.17.1.1 dev eth1
default via 192.168.0.1 dev eth2 metric 1

[code]
Si je remplace le 172.17.1.1 / eth1 par 192.168.0.1 / eth2, ça marche parfaitement … mais ce n’est pas le but ! :005
J’espère qu’un petit NAT pourra résoudre ça mais j’suis pas sûr de mon coup … :confused:

Pour résumer le plus simple de ce que je veux faire :

Quelle est la commande qui permet de rediriger les paquets venant de 10.145.7.17 depuis eth0 vers eth2 ?

J’ai essayé cette commande :

 iptables -t filter -A OUTPUT -s 10.145.7.17 -p tcp --dport 80 -o eth1 -j REJECT

Mais cela ne marche toujours pas … :think:

Je viens de comprendre que ce n’est pas une question de NAT ici mais plutôt une question de FILTRAGE, du coup je me suis penché sur des commandes comme celle-ci :

iptables -t filter -A OUTPUT -s 10.145.7.17 -p tcp --dport 80 -o eth1 -j REJECT
iptables -t filter -A OUTPUT -s 10.145.7.17 -p tcp --dport 80 -o eth2 -j ACCEPT

Mais ça ne marche toujours pas … :cry:

[quote=“Darkvlad”]Pour résumer le plus simple de ce que je veux faire :

Quelle est la commande qui permet de rediriger les paquets venant de 10.145.7.17 depuis eth0 vers eth2 ?

J’ai essayé cette commande :
(…)
Mais ça ne marche toujours pas … :cry:[/quote]

C’est normal que ça ne marche pas, tu cibles avec les chaînes INPUT et OUTPUT dans la table filter, qui n’ont pour propos que d’interagir avec le flux à destination de la machine locale et/ou étant la source.

Par la table filter, table par défaut, tu dois utiliser FORWARD pour transmettre d’un réseau à l’autre.

C’est d’ailleurs assez bien expliqué sur cette doc d’Inet !

Il te faut activer cette option, au niveau du système :

Alors, de deux manières pour le rendre définitif :

  • l’une tu l’écris dans ton script iptables afin qu’il soit chargé
  • l’autre - mieux - tu écris son équivalent dans le fichier /etc/sysctl.conf :

puis tu l’actives en mode administrateur avec la commande ‘sysctl -w’

Cela étant fait, tu créés tes régles iptables en utilisant la chaîne FORWARD, de ce style.
Voici un exemple de règles très minimalistes, basé sur ton cas, à appliquer à ton serveur Debian :

# fwd in
iptables A FORWARD -i eth2 -o eth0 -m conntrack ! --ctstate INVALID -j ACCEPT
# fwd out 
iptables A FORWARD -i eth0 -o eth2-m conntrack ! --ctstate INVALID -j ACCEPT
# table nat : masquerade
iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE

ATTENTION : C’est très minimaliste, dans le sens, où cela laisse passer tout !!!
D’autant que nous ne savons pas comment tu as initialiser tes tables !

Sachant que normalement la cible MASQUERADE n’est à utiliser que dans le cas où l’IP extérieure est dynamique. Ce qui signifie d’utiliser en lieu et place les cibles DNAT/SNAT dans la table nat - là, je t’avoue, je ne maîtrise pas le sujet ; parce que je ne m’y suis pas mis correctement dessus. C’est ce que tu devrais utiliser dans ton cas.

Merci de ta réponse explicative, depuis mon dernier post j’ai fais pas mal de recherche :

  • Je n’arrivais pas à mettre l’ip forwarding à 1 avec les commandes proposées sur le net mais la première que tu proposes marche : merci !
  • Je suis d’accord pour le FILTER, j’ai vite lâché l’affaire car ce n’est pas du tout ce que je recherchais (j’ai trouvé un site assez sympa qui expliquais bien en détail : Iptables Wiki
  • Au sujet de ton code :

[code]# fwd in
iptables -A FORWARD -i eth2 -o eth0 -m conntrack ! --ctstate INVALID -j ACCEPT

fwd out

iptables -A FORWARD -i eth0 -o eth2 -m conntrack ! --ctstate INVALID -j ACCEPT

table nat : masquerade

iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE[/code]

Pour le MASQUERADE, il n’y a pas besoin vu que l’interface extérieur du routeur est statique mais doit-on le faire pour la debian? (Je pense que non vu que ça marche avec des routes statiques).
Mais par contre, je ne comprends absolument pas tes règles : conntrack? ctstate? *fonce sur internet :unamused: *
D’ailleurs, je ne savais pas qu’on pouvait mettre -i et -o sur la même ligne donc du coup, je vais essayer en m’inspirant de ton code : merci encore !

Il me reste 45 min à résoudre ce truc (oui oui, mon maître de stage me met un peu la pression là :005 )

Purée de la part de BackTrack, le coup du Wiki, les explications sont très, voire trop, minimalistes.
Tu en apprendras vraiment plus avec Inet ou la doc d’Allard-Jacquin.

Concernant les correspondances ‘conntrack’ et ‘cstate’, c’est l’équivalent des vieilles correspondances ‘state’, tout en assurant un suivi de connexion. Accessible à partir des kernels 2.5 et >.

Concernant la cible MASQUERADE, tu en as besoin, ou plutôt dans ton cas des cibles DNAT/SNAT de la table nat, puisque tu es en ip statique. :wink:

D’accord mais j’ai toujours du mal à visualiser comment obliger la Debian à envoyer les paquets venant de 10.145.717 sur eth2 (et non eth1 qui est de base).

J’essaye d’interdire les paquets venant de PC1 sur eth1 mais j’ai bien peur qu’il les supprime au lieu de les rediriger vers eth2 … :confused:

Pour le SNAT, c’est :

iptables -t nat -A POSTROUTING -o eth2 -j SNAT --to-source ip_eth2

Cela devrait fonctionner !
(mais je ne suis pas sûr de moi …)

[quote=“Darkvlad”]D’accord mais j’ai toujours du mal à visualiser comment obliger la Debian à envoyer les paquets venant de 10.145.717 sur eth2 (et non eth1 qui est de base).

J’essaye d’interdire les paquets venant de PC1 sur eth1 mais j’ai bien peur qu’il les supprime au lieu de les rediriger vers eth2 … :confused:[/quote]

Parce que tu n’as pas compris tes flux d’entrées/sorties réseaux !

Si tu les interdit : soit tu les supprimes avec la cible DROP, soit tu les rejettes avec la cible REJECT.
Mais pourquoi les interdire !?
Parce que par défaut, tu ne veux pas communiquer avec … c’est normalement le cas lors de l’initialisation de tes règles iptables.

iptables -P INPUT   DROP
iptables -P FORWARD DROP
iptables -P OUTPUT  DROP

Là, rien ne passe, dans la table filter.

Quand tu forwardes, pour faire passer ton flux réseau ‘externe’, vers ton flux réseau ‘interne’, il te faut t’y prendre de cette manière, voire ma réponse, à-propos des cibles FORWARD.

Tu peux très bien les modifier pour n’accepter que le flux tcp, et sur le port 80, particulièrement.
Comme tu peux très bien les modifier pour n’accepter de sortir que les connexions qui sont établies ou relatives ;p
Je te laisse trouver :wink:

J’ai utilisé ces commandes :

iptables -A FORWARD -p tcp --dport 80 -i eth0 -o eth2 -m conntrack ! --ctstate INVALID -j ACCEPT
iptables -A FORWARD -p tcp --dport 80 -i eth2 -o eth0 -m conntrack ! --ctstate INVALID -j ACCEPT
iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth2 -j DNAT --to-destination 10.145.7.17
iptables -t nat -A POSTROUTING -p tcp --dport 80 -o eth2 -j SNAT --to-source 192.168.0.2
ip route add default via 192.168.0.1 dev eth2 metric 1

Ça ne marche pas … :cry:

Justement, j’avais rajouté “-p tcp --dport 80” et ça ne marche pas, avec ou sans … j’suis vraiment une bille ! :laughing:

Oui mais si j’applique ces règles, les personnes qui se trouvent sur le réseau 10.145.7.0 n’auront plus accès à internet depuis 172.16.0.0 non? :confused:

Comment sont tes règles de la cible FORWARD ?

Restitue l’ensemble des cibles FORWARD, PREROUTING et POSTROUTING, stp

Je vous met les 2 :

[code]debian:~# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT tcp – anywhere anywhere tcp dpt:www ! ctstate INVALID
ACCEPT tcp – anywhere anywhere tcp dpt:www ! ctstate INVALID

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

[code]debian:~# iptables -L -t nat
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT tcp – anywhere anywhere tcp dpt:www to:10.145.7.17
DNAT tcp – anywhere anywhere tcp dpt:www to:10.145.7.17

Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
SNAT all – anywhere anywhere to:192.168.0.2

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

Ce n’est pas un problème de NAT, ni de filtrage. C’est un problème de routage.

Solution simple : tous les paquets émis par PC1 à destination de l’extérieur sont routés vers le routeur avec firewall. Il faut pour cela mettre en place une règle de routage avancé basée sur l’adresse source.

ip rule add from 10.145.7.17 table 99 ip route add 192.168.0.0/24 dev eth2 table 99 ip route add 10.145.7.0/24 dev eth0 table 99 ip route add 172.17.1.0/24 dev eth1 table 99 ip route add 10.0.0.0/8 via 10.145.7.20 dev eth0 table 99 ip route add default via 192.168.0.1 dev eth2 table 99
En gros, on peuple la table de routage 99 avec les mêmes routes que la table principale sauf pour la route par défaut, et on dit que les paquets émis depuis 10.145.7.17 doivent être routés en suivant cette table.

Effet de bord : toutes les communications de PC1 vers internet utiliseront aussi cette route par défaut.
EDIT : j’ai rajouté les " table 99" manquants dans les routes.

Note a soi-même :

Ne pas utiliser :

iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP

quand on configure la Debian à distance avec Putty … :blush: La Debian refuse tout maintenant … bon bah …

Mais sinon PascalHambourg, j’aime bien votre idée! Faudra que je m’y penche demain !

So simple!

Euh, juste :

ip route add 10.0.0.0/8 via 10.145.7.20 dev eth0 table 99

ne devrait pas être plutôt :

Pourquoi ‘20’ ?

[quote=“Darkvlad”]Note a soi-même :

Ne pas utiliser :

iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP

quand on configure la Debian à distance avec Putty … :blush: La Debian refuse tout maintenant … bon bah …

(…)[/quote]

Ehehhh, Normal !
il te faut créer une règle pour faire entrer le flux sur ton serveur Debian, sur le proto ssh :wink:

Deuxième solution : marquer les paquets émis par PC1 appartenant à une connexion dont l’adresse destination originelle est l’adresse d’eth2. Ce n’est possible qu’avec du double NAT : le routeur redirige le port 80 vers l’adresse de la machine Debian et celle-ci redirige le port 80 vers l’adresse IP de PC1. Si le routeur redirige directement vers PC1, le suivi de connexion de netfilter n’aura pas de trace de l’interface d’arrivée et il faut utiliser une autre méthode.
En pratique, on reprend les commandes ip route de la première méthode, on modifie la commande ip rule et on ajoute un règle iptables :

iptables -t mangle -A PREROUTING -s 10.145.7.17 -m conntrack --ctorigdst 192.168.0.2 -j MARK --set-mark 1 ip rule add fwmark 1 table 99

PengouinPdt : Je n’en sais rien, je n’ai fait que reprendre le contenu de la table de routage originelle. Le réseau 10.0.0.0/8 n’est pas montré sur le schéma.

Troisième solution : marquer les connexions vers PC1 qui arrivent par eth2, et router les paquets retour par eth2. Cela fonctionne même avec un simple NAT direct du routeur vers PC1, et n’affecte que les connexions reçues par eth2. Le contenu de la table 99 est le même que ci-dessus ou bien on peut ne laisser que la route par défaut.
Les règles iptables et de routage :

iptables -t mangle -A FORWARD -i eth2 ! -s 192.168.0.0/24 -d 10.145.7.17 -j CONNMARK --set-mark 1 iptables -t mangle -A PREROUTING -i eth0 -j CONNMARK --restore-mark ip rule add fwmark 1 table 99

Petite note importante : pour que toutes ces solutions fonctionnent, il faut que rp_filter soit désactivé sur l’interface eth2. Je te laisse chercher comment vérifier et modifier le cas échéant.

Re!

J’ai dû me déplacer sur le site pour redémarrer la Debian physiquement pour qu’elle puisse reprendre ces configurations d’origine (ça m’apprendra tiens!)
Sinon pour PascalHambourg, je vais essayer d’opter pour ta première solution qui m’a l’air simpliste et je te remercie pour l’attention que vous portez pour moi.
Je vous donnerai des nouvelles au plus vite dès demain matin !

[quote]
Petite note importante : pour que toutes ces solutions fonctionnent, il faut que rp_filter soit désactivé sur l’interface eth2. Je te laisse chercher comment vérifier et modifier le cas échéant.[/quote]

Je pense que je peux y arriver … :mrgreen: