Trafic de sortie sur différentes interfaces en fonction du port de destination

23

Ma question est essentiellement la même que Autoriser uniquement un certain trafic sortant sur certaines interfaces .

J'ai deux interfaces eth1(10.0.0.2) et wlan0(192.168.0.2). Mon itinéraire par défaut est pour eth1. Disons que je veux que tout le trafic https passe wlan0. Maintenant, si j'utilise la solution suggérée dans l'autre question, le trafic https passera wlan0, mais aura toujours l'adresse source de eth1(10.0.0.2). Étant donné que cette adresse n'est pas routable pour la wlan0passerelle, les réponses ne reviendront jamais. Le moyen le plus simple serait de définir correctement le bind-addr dans l'application, mais dans ce cas, il n'est pas applicable.

Je pense que je dois réécrire le src-addr:

# first mark it so that iproute can route it through wlan0
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# now rewrite the src-addr
iptables -A POSTROUTING -t nat -o wlan0 -p tcp --dport 443 -j SNAT --to 192.168.0.2

Maintenant, tcpdump voit les paquets sortants très bien et les paquets entrants arrivent pour 192.168.0.2, mais ils ne se retrouvent probablement jamais dans l'application, car tout ce que j'ai pu voir, c'est que l'application renvoie le paquet SYN, bien que le SYN- ACK a déjà été reçu.

J'ai donc pensé que je devais peut-être aussi réécrire l'adresse entrante:

iptables -A PREROUTING -t nat -i wlan0 -p tcp --sport 443 -j DNAT --to 10.0.0.2

mais cela n'a pas fonctionné non plus. Je suis donc un peu coincé ici. Aucune suggestion?

rumpel
la source

Réponses:

24

Tu es proche.

La raison réelle pour laquelle l'application ne voit pas le trafic de retour est due à la protection intégrée contre l'usurpation d'adresse IP du noyau. Autrement dit, le trafic de retour ne correspond pas à la table de routage et est donc supprimé. Vous pouvez résoudre ce problème en désactivant la protection contre l'usurpation d'identité comme suit:

sudo sysctl net.ipv4.conf.wlan0.rp_filter=0

Mais je ne le recommanderais pas. La manière la plus appropriée consiste à créer une autre instance de routage.

  1. La marque est nécessaire. Garde le.
  2. Le NAT source est également nécessaire.
  3. Le DNAT final n'est pas nécessaire, vous pouvez donc le supprimer.

Assurez-vous que le iproutepackage est installé. Si vous avez la ipcommande, vous êtes défini (ce qui ressemble à vous, mais si ce n'est pas le cas en premier).

Modifiez /etc/iproute2/rt_tableset ajoutez un nouveau tableau en ajoutant la ligne suivante:

200 wlan-route

Vous devez ensuite configurer votre nouvelle table de routage nommée wlan-routeavec une passerelle par défaut et créer des règles pour envoyer conditionnellement du trafic vers cette table. Je suppose que votre passerelle par défaut est 192.168.0.1. Naturellement, cela doit correspondre à votre réseau actuel, et pas seulement à mes hypothèses.

ip route add default via 192.168.0.1 dev wlan0 table wlan-route
ip rule add fwmark 0x1 table wlan-route

Votre script annoté final ressemblerait à ceci:

# Populate secondary routing table
ip route add default via 192.168.0.1 dev wlan0 table wlan-route
# Anything with this fwmark will use the secondary routing table
ip rule add fwmark 0x1 table wlan-route
# Mark these packets so that iproute can route it through wlan-route
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# now rewrite the src-addr
iptables -A POSTROUTING -t nat -o wlan0 -p tcp --dport 443 -j SNAT --to 192.168.0.2
bahamat
la source
Merci d'avoir pris le temps d'examiner cela. Cependant, c'est déjà ce que j'utilisais (comme décrit dans l'autre question), j'ai donc configuré l'itinéraire supplémentaire, mais c'est toujours le même. Les SYN-ACK reviennent à 192.168.0.2 mais n'atteignent apparemment jamais l'application.
rumpel
Revenez en arrière et relisez ma réponse. J'en ai parlé.
bahamat
La partie sur la protection contre l'usurpation d'identité? Aucun changement même après avoir essayé. Désolé, lisez-le plusieurs fois, mais je n'ai pas encore compris ce qui me manque.
rumpel
Vous devez ajouter une srcoption aux ip routecommandes pour spécifier l'adresse source correcte.
David Schwartz
@DavidSchwartz: le POSTROUTING SNATprendra soin de cela.
bahamat
8

la solution de bahamat est correcte; cependant, veuillez noter que la seule façon pour moi de faire ce travail était de désactiver le rp_filter pour chaque interface du système, pas seulement les deux (eth1 et wlan0 dans ce cas) impliqués dans le NAT.

for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > $f; done
echo 1 > /proc/sys/net/ipv4/route/flush

(voir la note IMPORTANTE à la fin de cette page: Guide de routage avancé - le lien qui y est affiché n'existe plus, mais je l'ai trouvé via la machine de renvoi)

Davide C
la source
Merci pour ces réponses, moi aussi, je ne pouvais que faire fonctionner la solution bahamats en tenant compte de votre réponse.
Dynalon
pour moi sur une boîte ubuntu 12.04 LTS assez standard, en plus de désactiver rp_filter et de vider le cache de route, j'ai également dû retirer le nom de l'interface des arguments iptables. n'a pas eu assez de temps pour chercher pourquoi.
Costin Gușă
0

Une suggestion: vous devez toujours utiliser --sportau lieu de --dportdans la chaîne de sortie.

Les NAT changent le dportet cela rendra votre règle inutilisable.

user73451
la source
2
Y a-t-il quelque chose que je ne reçois pas? Le dport, comme dans le port de destination, ne peut pas changer. C'est le port du service que la session essaie d'atteindre, par exemple http, ssh, smtp. Soit vous avez confondu sport et sport, soit il me manque quelque chose d'évident. : P
Quelqu'un le
0

Je pense que ci-dessous est nécessaire:

ip ru add from 192.168.0.2 table 3 prio 300
ip ro add table 3 default via 192.168.0.1 dev wlan0
user181234
la source