Routage sélectif ip route avec 2 liens ppp

Bonjour à tous,

Je reviens vers vous car je coince sur un problème, qui je pense, à déjà du être traité.
Mais malgré mes recherches et tests,cela ne fonctionne pas.

Voilà l’ architecture:

—ppp0—|-sshd-|
|Debian|-----Lan-------
—ppp1—|------|

2 liens ADSL chez Orange: oui je n’ai pas choisi, donc 2 ip fixes.
Une sur ppp0 et l’autre sur ppp1.
Derrière ce routeur Debian, on trouve un lan en 192.168.x.x qui est naté
Voilà le résultat de la commande ip route show:
default
nexthop via 217.128.xxx.xxx dev ppp0 weight 1
nexthop via 217.128.yyy.yyy dev ppp1 weight 1

192.168.200.0/24 dev eth1 proto kernel scope link src 192.168.200.10
193.253.160.A dev ppp0 proto kernel scope link src 217.128.xxx.xxx
193.253.160.A dev ppp1 proto kernel scope link src 217.128.yyy.yyy

Donc, je fais une sorte de partage de charge entre ppp0 et ppp1 grâce a un poids équivalent entre ppp0 et ppp1

je veux me connecter en ssh sur mon routeur de l’Internet.
Le problème est que la connexion arrive bien sur ppp0 mais le retour est dispaché entre ppp0 et ppp1 : problème!!!.
La solution est le routage sélectif avec ip route2 et iptables mais je coince.
Voilà ma démarche:

1)Marquer les paquet grâce à la table mangle :
iptables -t mangle -I OUTPUT -o ppp0 -p tcp --sport 22 -j MARK --set-mark 22

Le résultat:
Chain OUTPUT (policy ACCEPT 10493 packets, 675K bytes)
pkts bytes target prot opt in out source destination
552 79772 MARK tcp – any ppp0 anywhere anywhere tcp spt:ssh MARK set 0x16

Les paquets sont donc bien marqués.
2) Créer une entrée dans le fichier /etc/iproute2/rt_tables

reserved values

200 ssh
255 local
254 main
253 default
0 unspec

local

#1 inr.ruhep

  1. rajouter la règle de routage:
    ip rule list
    0: from all lookup local
    32765: from all fwmark 0x16 lookup ssh
    32766: from all lookup main
    32767: from all lookup default

  2. la table de routage sélective :
    ip route show table ssh
    default via 217.128.214.63 dev ppp0

Lorsque je connecte de l’extérieur, je vois repartir des paquets sur ppp1???

tcpdump -i ppp1 -n -t tcp port 22
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ppp1, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
IP 217.128.xxx.xxx.22 > 37.161.bbb.ccc.35291: Flags [S.], seq 2127963651, ack 592174929, win 14160, options [mss 1416,nop,nop,sackOK,nop,wscale 6], length 0

Est-ce bien sur la chaîne OUTPUT que je dois marquer les paquets car c’est peut être trop tard.
J’ai essayé d’autre marquages mais dans ce cas ils ne sont pas modifiés.

Merci de votre aide.

Merci d’utiliser les balises “Code” pour les commandes, fichiers et dessins en ASCII art.

Comme je l’avais déjà écrit dans ton sujet précédent, la solution la plus simple est le routage basé sur l’adresse source. Pas besoin d’iptables.
Si le paquet a l’adresse source de ppp0, alors forcer le routage par ppp0.
Si le paquet a l’adresse source de ppp1, alors forcer le routage par ppp1.

ip rule add from $IP_ppp0 table tab_ppp0 ip rule add from $IP_ppp1 table tab_ppp1
Je te laisse compléter les tables de routage.
PS : pas besoin de spécifier d’adresse de passerelle avec une liaison point à point, l’interface suffit.

[quote=“verhugues”]1)Marquer les paquet grâce à la table mangle :

Les paquets que tu veux rerouter sont initialement censés sortir par ppp1, donc ta règle qui ne traite que les paquets sortant déjà par ppp0 sera sans effet.

Accessoirement, ta sélection des paquets basée sur le port source est mauvaise, car si tu voulais accéder au routeur par ppp1 (au cas où ppp0 tombe par exemple) ça ne marcherait pas, tout paquet de réponse SSH étant renvoyé par ppp0.

Merci pour cet éclairage. J’utiliserai les balises.

J’ai mis en place cette configuration.

:~# ip rule list 0: from all lookup local 32764: from 217.128.xxx.xxx lookup ppp1 32765: from 217.128.yyy.yyy lookup ppp0 32766: from all lookup main 32767: from all lookup default

[code]:~# ip route show table ppp1
default dev ppp1 scope link

:~#ip route show table ppp0
default dev ppp0 scope link
[/code]

Cela fonctionne pour la connexion INPUT à ssh quelque soit l’interface d’entrée ppp0 ou ppp1.
Mais, j’ai un serveur Postfix sur le lan avec une redirection PREROUTING sur le routeur.

Schéma:

---ppp0---|---| smtp/imap | |---eth1-------|----- ---ppp1---|---|

Le problème est que dans ce cas, le routage sur l’adresse source ne fonctionne plus. Donc, je pense qu’il faut faire du routage sélectif sur le port source 25 ou 143 en PREROUTING. Mais j’ai aussi du 80 pour Mailman.

Est-ce ok pour toi?
Je vais tester ça demain.

Auparavant, sans la règle iproute2 sur les adresses sources, ce cas de figure fonctionnait…?

Cordialement

En effet la réécriture de l’adresse source finale a lieu après le routage, donc on ne peut se baser sur celle-ci pour le reroutage.

Même critique que dans dans ma réponse précédente. Il y a d’autres méthodes plus élégantes et universelles. Parmi elles :

  • L’option [mono]–ctorigdst[/mono] de la correspondance [mono]conntrack[/mono] d’iptables permet de sélectionner les paquets en fonction de l’adresse de destination originelle de la connexion à laquelle ils appartiennent.
  • Le couple [mono]connmark[/mono]/[mono]CONNMARK[/mono] permet de marquer une connexion et ses paquets. La technique classique consiste à marquer les connexions entrantes en fonction de l’interface d’entrée et à marquer les paquets de réponse sortants en fonction de la marque de connexion, puis d’utiliser la marque de paquet pour le routage.
  • Définir des adresses IP de destination “alias” différentes en fonction de l’interface d’entrée, afin de pouvoir faire du routage basé sur l’adresse source.

M’étonnerait. L’ajout des règles de routage par adresse source ne change rien au routage déjà en place, ces règles ne prenant en compte que les paquets émis par la passerelle elle-même. Si le routage se limitait à la route par défaut multipath citée plus haut, alors tu avais juste une chance sur deux de tomber sur la bonne interface.

Merci pour ces pistes.

J’avoue que c’est un peu flou entre connmark conntrack et iptables.
Mais je creuse…

Pour essayer de formaliser un peu la procédure:

  1. Je dois marquer la connexion entrante par ppp0 qui est a destination de la machine “postfix” dans le Lan car j’utilise le DNAT.
    C’est la première connexion qui est utilisé pour cela.
    Cible CONNMARK --set-mark de iptables ?

  2. Je dois recopier cette marque sur la connexion qui ressort du Lan par eth1.
    -j CONNMARK --restore-mark ?

  3. Ecrire une règle pour le routage de cette marque

C’est le --ctorigdst que je ne sais pas utiliser?

Est-ce un bon début?

Cordialement

Oui, c’est bien ça pour l’utilisation de CONNTRACK. Pour compléter, il faut ajouter le critère [mono]-m state --state NEW[/mono] car il suffit de marquer la connexion lors du premier paquet de celle-ci. Mais il me semble que l’utilisation de [mono]–ctorigdst[/mono] est encore plus simple car une seule règle suffit pour marquer les paquets de réponse sortants d’une connexion à l’adresse destination originelle spécifiée, par exemple :