iptables --set-mark - Achemine différents ports à travers différentes interfaces

14

Petite histoire,
3 interfaces, eth0 (LAN), eth1 (ADSL), eth2 (4G).
eth0 -> eth1: fonctionne
(ports 80, 443, 4070) eth0 -> eth2: ne se produit pas


Il s'agit d'une représentation graphique de l'idée:

Port 80 et 443 via eth2
et le reste via eth1
entrez la description de l'image ici

Netscheme:

eth0: -ip 10.0.0.1 -net 10.0.0.0/8 -gw 10.0.0.1 (the servers own intf) 
eth1: -ip 192.168.1.74 -net 192.168.1.0/24 -gw 192.168.1.254 
eth2: -ip 192.168.1.91 -net 192.168.0.0/24 -gw 192.168.0.1 






Ce nouveau script redirige 22 et 4070 vers la bonne table, je pense.
Cependant, après avoir atteint cette table, il n'est pas redirigé vers eth2.




Ce script fonctionne, sauf pour 22 et 4070!

(Le port 80 n'est pas commenté et il fonctionne mais via eth1 qui est faux.)

modprobe iptable_nat
modprobe ip_conntrack

echo "1" > /proc/sys/net/ipv4/ip_forward

iptables -P INPUT ACCEPT
iptables -F INPUT
iptables -P OUTPUT ACCEPT
iptables -F OUTPUT
iptables -P FORWARD DROP
iptables -F FORWARD
iptables -F PREROUTING
iptables -t nat -F
iptables -t mangle -F
iptables -F
# This next line restores any issues trying to connect to something
# if you get weird ACK packets when trying to connect (at least i did)!
iptables -t mangle -A PREROUTING -p tcp -j CONNMARK --restore-mark
ip route flush table main

iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 22 -j MARK --set-mark 1
###  iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 80 -j MARK --set-mark 1
iptables -A PREROUTING -i eth0 -t mangle -p tcp --dport 4070 -j MARK --set-mark 1

## Setup routes
# LAN
route add -net 10.0.0.0 netmask 255.0.0.0 dev eth0
# ADSL
route add -net 192.168.1.0 netmask 255.255.255.0 dev eth1
# 4G (Only accessible if marking packages with \x01
route add -net 192.168.0.0 netmask 255.255.255.0 dev eth2
# Default via ADSL
## -- Does the same as ip route below? route add default gw 192.168.1.254


echo "201 eth2.out" >> /etc/iproute2/rt_tables

ip rule add fwmark 1 table eth2.out
ip route add default via 192.168.0.1 dev eth2 table eth2.out
ip route add default via 192.168.1.254 dev eth1



## Setup forwards
# From 4G to LAN
iptables -A FORWARD -i eth2 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From ADSL to LAN
iptables -A FORWARD -i eth1 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From LAN to ADSL (Default route out)
# - Note: If marked packages is sent to ADSL they will be mangled and rerouted to 4G
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE









Ancien script:


  Ignore everything below unless you're interested in retracing my steps!!




J'ai créé un script router.sh pour configurer mon environnement au cas où je ferais quelque chose de mal. J'ai 3 ports que je veux envoyer à une connexion 4G et le reste via une connexion ADSL fixe. Pour ce faire, j'ai demandé à iptables de modifier les paquets sur la route par défaut et de les envoyer via mon interface 4G si --dport == 443 | 80 | 4070

Cependant, cela ne fonctionne pas; Je suis toujours acheminé via ma ligne fixe, quoi qu'il arrive.

Voici à quoi ressemble mon script:

#!/bin/bash

## routing tables
# wireless = 4G via eth2
# adsl = adsl via eth1

modprobe iptable_nat
modprobe ip_conntrack

echo "1" > /proc/sys/net/ipv4/ip_forward

iptables -P INPUT ACCEPT
iptables -F INPUT
iptables -P OUTPUT ACCEPT
iptables -F OUTPUT
iptables -P FORWARD DROP
iptables -F FORWARD
iptables -t nat -F
ip route flush table main
ip route flush table wireless
ip route flush table adsl

## Setup routing tables
# ADSL
ip route add table adsl to 192.168.1.0/24 dev eth1
# 4G
ip route add table wireless to 192.168.0.0 dev eth2
ip rule add fwmark 0x1 table wireless

## Setup routes
# LAN
route add -net 10.0.0.0 netmask 255.0.0.0 dev eth0
# ADSL
route add -net 192.168.1.0 netmask 255.255.255.0 dev eth1
# 4G (Only accessible if marking packages with \x01
route add -net 192.168.0.0 netmask 255.255.255.0 dev eth2
# Default via ADSL
route add default gw 192.168.1.254


## Forward ports into the LAN
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 -j DNAT --to 10.0.0.3:80


## Lets mark all packets we want for 4G forward
# HTTPS
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# HTTP
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 80 -j MARK --set-mark 1
# Spotify
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 4070 -j MARK --set-mark 1

## Setup forwards
# From 4G to LAN
iptables -A FORWARD -i eth2 -o eth0 -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
# From ADSL to LAN
iptables -A FORWARD -i eth1 -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
# From LAN to ADSL (Default route out)
# - Note: If marked packages is sent to ADSL they will be mangled and rerouted to 4G
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
iptables -A FORWARD -j LOG
#iptables --table nat --append POSTROUTING --out-interface eth2 --jump SNAT --to-source "192.168.1.74"
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE

J'ai également essayé d'ajouter ces 3 au bas du script:

iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 80 -j SNAT --to "192.168.0.91"
iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 443 -j SNAT --to "192.168.0.91"
iptables -t nat -A POSTROUTING -o eth2 -p tcp --dport 4070 -j SNAT --to "192.168.0.91"

Également essayé sans succès:

iptables -A PREROUTING -t mangle -i eth0 -p tcp --dport 80 -j MARK --set-mark 1

Last but not least, essayé:

## Lets mark all packets we want for 4G forward
# HTTPS
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# HTTP
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 80 -j MARK --set-mark 1
# Spotify
iptables -A POSTROUTING -t mangle -o eth1 -p tcp --dport 4070 -j MARK --set-mark 1

Le routage fonctionne, je peux naviguer sur le Web, écouter de la musique et autres, mais je le fais via la mauvaise interface. Je recherche sur Google depuis longtemps et j'ai trouvé des morceaux pour comprendre ce que je fais et pourquoi je le fais. Je pourrais faire la mise en forme du trafic via tc mais si c'est possible via le marquage des packages dans iptables, cela m'aiderait beaucoup.

Je suppose que je fais mal l'ordre sur les différentes règles, principalement la partie MASQUERADE ? ou si cela devait même être là?

Quelqu'un peut-il expliquer comment le port DNAT dit, tcp: 80 à partir d'une interface externe (un ou les deux protocoles) à un espace d'adressage 10.0.0.0 interne?



Les sorties:

root@Netbridge:~# route -n Kernel IP routing table Destination    

Gateway         Genmask         Flags Metric Ref    Use Iface<br>
0.0.0.0         192.168.1.254   0.0.0.0         UG    0      0        0 eth1<br>
10.0.0.0        0.0.0.0         255.0.0.0       U     0      0        0 eth0<br>
192.168.0.0     0.0.0.0         255.255.255.0   U     0      0        0 eth2<br>
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 eth1


root@Netbridge:~# ifconfig

eth0      Link encap:Ethernet  HWaddr 00:0c:29:7e:9e:4e  
          inet addr:10.0.0.1  Bcast:10.255.255.255  Mask:255.0.0.0

eth1      Link encap:Ethernet  HWaddr 00:0c:29:7e:9e:58  
          inet addr:192.168.1.74  Bcast:192.168.1.255  Mask:255.255.255.0

eth2      Link encap:Ethernet  HWaddr 00:0c:29:7e:9e:62  
          inet addr:192.168.0.91  Bcast:192.168.0.255  Mask:255.255.255.0

Suivre ces instructions:
trafic de sortie sur différentes interfaces basées sur la destination par
iptables-forward-specific-port-to-specific-nic
Parmi quelques autres threads liés.

Torxed
la source
Je suis désolé, mais y a-t-il une raison pour ne pas lier apache uniquement à localhostet à l'adresse de l' eth2interface?
Jan Marek,
@JanMarek: Il n'y a aucune mention d'apache ici. Et pour votre information, lier un socket à l' ethXadresse IP d'un empêchera les hôtes du ethXLAN d'accéder au serveur local à l'aide ethYde l'adresse IP et n'empêchera pas les hôtes d' ethYaccéder au serveur à l'aide ethXde l'adresse IP. N'oubliez pas que Linux utilise un modèle d'hôte faible.
BatchyX
OK, il y a peut-être plus de serveurs Web, pas seulement un serveur Apache ... Je pense cependant que lier le serveur Web sur l'interface eth2 peut être une solution simple. Mais je peux me tromper, je sais.
Jan Marek

Réponses:

5

BatchyX donne déjà de très bonnes explications sur iptables et le routage, donc je vais exercer ma paresse et aller directement au script.

Il doit NAT tout le trafic vers le port 80,443,22,4070 à 192.168.0.91. Tout le reste sera NAT jusqu'à 192.168.1.254.

Je refais mes tests et finis par suivre ce guide . Ce qui manque dans ce guide, ce sont les 3 dernières lignes de mon script. Ce que j'ai découvert depuis un autre port, mais j'ai perdu la trace de ce lien.

Il s'agit d'un script de travail testé.

Besoin d'une route par défaut

Une chose que je n'ai pas mise dans le script est la configuration de la route par défaut. Ça devrait être

route add default gw 192.168.1.254

Dans ce cas route -n, ce devrait être la seule route par défaut (Dest: 0.0.0.0)

0.0.0.0    192.168.1.254    0.0.0.0    UG    0    0    0    eth1

fw-router.sh

# Réinitialiser / Rincer les iptables
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P ENTRÉE ACCEPTER
iptables -P AVANCE ACCEPTER
iptables -P SORTIE ACCEPTER

# Reset / Flush / Setup IP Route (tableau 4)
ip route flush table 4
ip route afficher la table principale | grep -Ev ^ par défaut | en lisant ROUTE; do ip route add table 4 $ ROUTE; terminé
ip route add table 4 default via 192.168.0.1

#Mark Packet avec D.Port correspondant
iptables -t mangle -A PREROUTING -p tcp --dport 22 -s 10.0.0.0/24 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p tcp --dport 80 -s 10.0.0.0/24 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p tcp --dport 443 -s 10.0.0.0/24 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -p tcp --dport 4070 -s 10.0.0.0/24 -j MARK --set-mark 4

#SNAT Rules
iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to-source 192.168.1.74
iptables -t nat -A POSTROUTING -o eth2 -j SNAT --to-source 192.168.0.91

# Route IP
règle ip ajouter fwmark 4 tableau 4
cache de vidage de route ip

#IP Stack
#Ceci est la partie manquante du guide
echo 1> / proc / sys / net / ipv4 / ip_forward
pour f dans / proc / sys / net / ipv4 / conf / * / rp_filter; faire écho 0> $ f; terminé
echo 0> / proc / sys / net / ipv4 / route / flush

PS1: En bref, MASQUERADEne fonctionne pas (dans la plupart des cas, et certainement dans votre cas) pour NAT avec plusieurs adresses IP externes qui ont besoin d'une sorte d'équilibrage de charge ou nécessitent DNAT pour gérer le trafic entrant. Vous avez besoin SNATd'un contrôle de direction.

PS2: Pure iptables n'est pas suffisant.

John Siu
la source
Tout d'abord, merci d'aller directement au script :) Je vais essayer ce soir car je reviens à l'environnement dans lequel cela fonctionnera!
Torxed
hmm, peut nécessiter une révision lourde. Faites-moi savoir le résultat.
John Siu
Révisé, devrait fonctionner maintenant.
John Siu
Doux, je vous répondrai dans quelques
instants
Je t'aime, tellement de maux de tête et tu l'as résolu! Je vous remercie!
Torxed
6

Remarque: je n'ai considéré que le premier script, en ignorant l'ancien.

  • Vous n'avez pas besoin de modprobe les modules netfilter à la main avec les iptables actuels. Cela n'est nécessaire que pour les suiveurs de connexion personnalisés.
  • Ne vous mélangez pas routeet ip route. C'est du mal pur. Utilisez-le ippartout et oubliez ifconfigetroute
  • /etc/iproute2/rt_tablesn'est pas réinitialisé lors des redémarrages. Ajouter la même entrée encore et encore n'est pas une bonne idée, vous ne devez le faire qu'une seule fois. N'oubliez pas que rt_tablesdéfinissez simplement des alias de nom en valeurs numériques, cela ne modifie aucune configuration.

  • Maintenant pour iptables: Dans votre FORWARDchaîne, vous déposez des paquets provenant du LAN vers la 4G. C'est mauvais. le FORWARDcrochet est utilisé une fois le routage terminé. À ce stade, tout le routage des stratégies est effectué, et on sait déjà si le paquet doit être envoyé vers la 4G ou l'ADSL. Il n'y a pas de réacheminement effectué dans FORWARDou après FORWARD(eh bien, techniquement, le réacheminement peut être effectué après POSTROUTINGdans les cas graves, mais revenons au fait).

Maintenant pour votre routage: n'oubliez pas qu'Ubuntu active le filtrage de chemin inverse par défaut. Le filtrage de chemin inverse fonctionne comme suit: Lorsque le noyau reçoit un paquet (qu'il soit transféré ou non) d'une interface A, il inversera l'adresse source et l'adresse de destination, et vérifiera si le paquet résultant doit être acheminé via l'interface A. Si ce n'est pas le cas, le paquet est abandonné en tant que tentative d'usurpation d'adresse.

Pour les paquets reçus de eth0, ce n'est pas un problème. Pour les paquets reçus de eth1, ce n'est pas non plus un problème, car lors de l'inversion de l'adresse IP source et de l'adresse IP de destination, le noyau utilise la route par défaut dans le tableau main. Pour les paquets reçus de eth2, que vous ne marquez pas, c'est un problème, car le noyau atteindra la route par défaut dans la table mainet considérera que ces paquets auraient dû être reçus de eth1. La solution la plus simple consiste à désactiver le filtrage de chemin inverse sur eth1:

sysctl -w net.ipv4.conf.eth1.rp_filter=0
BatchyX
la source
Tous les bons commentaires et oui, il y a une logique défectueuse de ma part, par exemple en ajoutant à rt_tables à chaque fois et surtout pas en effaçant certaines tables aussi bien que je devrais mais j'y arriverai :) Je vais tout essayer et voir si cela fonctionne, si oui, +50 pour vous et surtout vous avez sauvé un homme derrière d'être coupé en morceaux et en paix! :)
Torxed
1
Le script ci-dessous fonctionne mais vous méritez également toute la gratitude, vous m'avez donné une ou deux choses à penser et rp_filter = 0 a beaucoup aidé! : D
Torxed
@BatchyX très instructif, votez pour vous aussi.
John Siu
@Torxed Le message que j'ai vu mentionner l'interface rp_filter pour TOUT doit être désactivé. Je ne sais pas si cela fonctionne autrement.
John Siu
@JohnSiu: Il vous suffit de désactiver le filtre rp sur les interfaces où il est problématique. Dans ce cas, c'est eth1, car il n'y a pas de route vers cette interface lorsque les marques ne sont pas définies. eth2 n'a pas un tel problème, car la route par défaut va dans cette interface. Pour eth0, il est en fait utile de garder le filtre rp activé, sinon, quelqu'un sur le LAN pourrait forger un paquet IP avec une adresse source sur Internet et une adresse de destination sur le LAN, et le routeur l'accepterait volontiers et transmettrait revenir à ... eth0.
BatchyX