Forcer le trafic IP local vers une interface externe


30

J'ai une machine avec plusieurs interfaces que je peux configurer comme je veux, par exemple:

  • eth1: 192.168.1.1
  • eth2: 192.168.2.2

Je voudrais transmettre tout le trafic envoyé à l'une de ces adresses locales via l'autre interface. Par exemple, toutes les requêtes vers un serveur iperf, ftp, http à 192.168.1.1 ne doivent pas être uniquement acheminées en interne, mais transmises via eth2 (et le réseau externe se chargera de réacheminer le paquet vers eth1).

J'ai essayé et regardé plusieurs commandes, comme iptables, ip route, etc ... mais rien n'a fonctionné.

Le comportement le plus proche que j'ai pu avoir a été fait avec:

ip route change to 192.168.1.1/24 dev eth2

qui envoie tous les 192.168.1.x sur eth2, à l'exception de 192.168.1.1 qui est toujours routé en interne. Peut-être puis-je alors faire le transfert NAT de tout le trafic dirigé vers le faux 192.168.1.2 sur eth1, redirigé vers 192.168.1.1 en interne? Je suis en fait aux prises avec iptables, mais c'est trop difficile pour moi.

Le but de cette configuration est de faire des tests de pilotes d'interface sans utiliser deux PC.

J'utilise Linux, mais si vous savez comment faire cela avec Windows, je l'achèterai!

Modifier:

Le réseau externe n'est qu'un câble croisé entre eth1 et eth2. Disons que j'ai un serveur http sur ma machine. Maintenant, je veux accéder à ce serveur à partir de la même machine, mais je veux forcer le trafic TCP / IP à passer par ce câble eth1 / eth2. Comment dois-je configurer mes interfaces pour cela?


Êtes-vous en train de dire que vous souhaitez que tout le trafic soit mis en miroir via les interfaces 1 et 2, mais uniquement renvoyé à l'interface 2 à partir d'un autre routeur? Cela ne pourrait-il pas faire des trucs assez bizarres sur le réseau? Serait-il préférable de diriger le trafic en miroir de l'interface 2 vers un autre système qui vient de perdre du trafic et ensuite vous pouvez le surveiller, ou utiliser un logiciel de virtualisation pour capturer le trafic? Peut-être que je manque quelque chose dans la description.
Bart Silverstrim

On dirait qu'il veut générer un paquet pour, disons, 192.168.1.1 qui est l'IP de eth1. Mais au lieu que la pile Linux reçoive ce paquet entièrement en interne, il veut que le paquet soit expulsé eth2 (qui sera remis en externe dans eth1 puis dans la pile Linux). Je ne sais pas si c'est possible; une fois que la couche réseau détecte que l'adresse est une interface interne, elle aura peu de raisons de regarder les tables de routage. Quelqu'un d'autre sait peut-être mieux.
PP.

Réponses:


14

J'ai développé la réponse de caladona car je ne pouvais pas voir les paquets de réponse. Pour cet exemple:

  1. Sur mon PC local, j'ai des cartes réseau sur différents sous-réseaux, 192.168.1 / 24 , 192.168.2 / 24
  2. Un routeur / PC externe a accès aux deux sous-réseaux.
  3. Je veux envoyer du trafic bidirectionnel sur les cartes réseau sur le PC local.
  4. La configuration nécessite deux adresses IP inutilisées pour chaque sous-réseau.

Les routes iptables du PC local sont définies sur le trafic sortant SNAT et DNAT vers la «fausse» IP.

iptables -t nat -A POSTROUTING -d 192.168.1.100 -s 192.168.2.0/24 -j SNAT --to-source      192.168.2.100
iptables -t nat -A PREROUTING  -d 192.168.1.100 -i eth0           -j DNAT --to-destination 192.168.1.1
iptables -t nat -A POSTROUTING -d 192.168.2.100 -s 192.168.1.0/24 -j SNAT --to-source      192.168.1.100
iptables -t nat -A PREROUTING  -d 192.168.2.100 -i eth1           -j DNAT --to-destination 192.168.2.1

Les règles font ce qui suit:

  1. Réécrire la source 192.168.2.1 en 192.168.2.100 sur les paquets sortants
  2. Réécrire la destination 192.168.1.100 en 192.168.1.1 sur les paquets entrants
  3. Réécrire la source 192.168.1.1 en 192.168.1.100 sur les paquets sortants
  4. Réécrire la destination 192.168.2.100 en 192.168.2.1 sur les paquets entrants

Pour résumer, le système local peut désormais communiquer avec une machine «virtuelle» avec les adresses 192.168.1.100 et 192.168.2.100.

Ensuite, vous devez forcer votre PC local à utiliser le routeur externe pour atteindre votre fausse IP. Pour ce faire, créez un itinéraire direct vers les adresses IP via le routeur. Vous voulez vous assurer que vous forcez les paquets sur l'opposé du sous-réseau de destination.

ip route 192.168.1.100 via $ROUTER_2_SUBNET_IP 
ip route 192.168.2.100 via $ROUTER_1_SUBNET_IP

Enfin, pour que tout cela fonctionne, le routeur externe doit savoir comment atteindre les adresses IP truquées sur votre PC local. Vous pouvez effectuer des actions minces en activant les ARP proxy sur votre système.

echo 1 | sudo tee /proc/sys/net/ipv4/conf/all/proxy_arp
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

Avec cette configuration, vous pouvez désormais traiter les fausses adresses IP comme un véritable système sur votre PC local. L'envoi de données vers le sous-réseau .1 forcera les paquets à sortir de l'interface .2. L'envoi de données au sous-réseau .2 forcera les paquets à sortir de l'interface .1.

ping 192.168.1.100
ping 192.168.2.100

Bien mieux à votre façon! Notez que j'ai également besoin d'un ip_forward pour que les trucs ARP fonctionnent: echo 1> / proc / sys / net / ipv4 / ip_forward
calandoa

28

J'ai utilisé avec succès les éléments suivants sous Linux pour tester le débit sur une nouvelle carte 10 Gbits / s double port en mode "loopback", c'est-à-dire qu'un port est branché directement sur l'autre. C'est juste un peu de vaudou juste pour forcer les paquets à sortir du fil, mais si vous ne le faites pas, Linux ne fera que court-circuiter le trafic à travers le noyau (d'où la question de l'OP). Dans la réponse de Casey ci-dessus, je ne sais pas s'il était vraiment nécessaire d'avoir un routeur externe ou non ci-dessus, mais ce qui suit est complètement autonome. Les deux interfaces sont eth2 et eth3.

Attribuez des adresses IP aux interfaces et placez-les sur des réseaux distincts:

ifconfig eth2 10.50.0.1/24
ifconfig eth3 10.50.1.1/24

Ensuite, nous allons mettre en place un double scénario NAT: deux nouveaux faux réseaux utilisés pour atteindre l'autre. En sortant, sourcez NAT sur votre faux réseau. En chemin, fixez la destination. Et vice versa pour l'autre réseau:

# nat source IP 10.50.0.1 -> 10.60.0.1 when going to 10.60.1.1
iptables -t nat -A POSTROUTING -s 10.50.0.1 -d 10.60.1.1 -j SNAT --to-source 10.60.0.1

# nat inbound 10.60.0.1 -> 10.50.0.1
iptables -t nat -A PREROUTING -d 10.60.0.1 -j DNAT --to-destination 10.50.0.1

# nat source IP 10.50.1.1 -> 10.60.1.1 when going to 10.60.0.1
iptables -t nat -A POSTROUTING -s 10.50.1.1 -d 10.60.0.1 -j SNAT --to-source 10.60.1.1

# nat inbound 10.60.1.1 -> 10.50.1.1
iptables -t nat -A PREROUTING -d 10.60.1.1 -j DNAT --to-destination 10.50.1.1

Dites maintenant au système comment accéder à chaque faux réseau et préremplissez les entrées arp (assurez-vous de remplacer vos adresses MAC, n'utilisez pas les miennes):

ip route add 10.60.1.1 dev eth2
arp -i eth2 -s 10.60.1.1 00:1B:21:C1:F6:0F # eth3's mac address

ip route add 10.60.0.1 dev eth3 
arp -i eth3 -s 10.60.0.1 00:1B:21:C1:F6:0E # eth2's mac address

Cela trompe suffisamment Linux pour réellement mettre des paquets sur le fil. Par exemple:

ping 10.60.1.1

s'éteint eth2, l'IP source 10.50.0.1 devient NATted à 10.60.0.1, et comme il arrive dans eth3 la destination 10.60.1.1 obtient NATted à 10.50.1.1. Et la réponse prend un voyage similaire.

Utilisez maintenant iperf pour tester le débit. Liez aux adresses IP correctes et assurez-vous de l'adresse IP que vous contactez (la fausse adresse de l'autre extrémité):

# server
./iperf -B 10.50.1.1 -s

# client: your destination is the other end's fake address
./iperf -B 10.50.0.1 -c 10.60.1.1 -t 60 -i 10

Assurez-vous que le trafic sort vraiment du câble:

tcpdump -nn -i eth2 -c 500

Vous pouvez également regarder / proc / interruptions juste pour être absolument sûr que la carte est utilisée:

while true ; do egrep 'eth2|eth3' /proc/interrupts ; sleep 1 ; done

Quoi qu'il en soit, j'ai trouvé ce post en cherchant comment le faire, merci pour les gars de Q&A, et j'espère que cela aidera quiconque à trouver ce post à l'avenir.


+1 Excellente solution - cela ne nécessite même pas d'activer le transfert IP! C'est exactement ce dont j'avais besoin en ce moment (pour les tests de 10 Go via le bouclage).
Nils

16

Comme toujours - je suis un peu en retard - mais de nos jours, on pourrait utiliser des espaces de noms réseau pour isoler les interfaces et empêcher tout transfert local (et jouer avec iptables :)).

Créez des espaces de noms (tout cela avec les autorisations requises, par exemple en tant que root):

ip netns add ns_server
ip netns add ns_client

Notez que l'état / la configuration des interfaces doit maintenant être accessible dans le contexte de l'espace de noms affecté - donc elles n'apparaîtront pas si vous exécutez un lien IP nu car il est exécuté dans le contexte de l'espace de noms par défaut. L'exécution d'une commande dans un espace de noms peut être effectuée à l'aide de

ip netns exec <namespace-name> <command>

comme préfixe.

Attribuez maintenant des espaces de noms aux interfaces, appliquez la configuration et configurez les interfaces:

ip link set eth1 netns ns_server
ip netns exec ns_server ip addr add dev eth1 192.168.1.1/24
ip netns exec ns_server ip link set dev eth1 up
ip link set eth2 netns ns_client
ip netns exec ns_client ip addr add dev eth2 192.168.1.2/24
ip netns exec ns_client ip link set dev eth2 up

Vous pouvez maintenant exécuter les applications dans l'espace de noms - pour l'exécution du serveur iperf

ip netns exec ns_server iperf -s -B 192.168.1.1

et le client:

ip netns exec ns_client iperf -c 192.168.1.1 -B 192.168.1.2

Le trafic sera désormais envoyé via les interfaces physiques car l'ensemble pile réseau, interface, routage ... est isolé par les espaces de noms, de sorte que le noyau ne peut pas faire correspondre les adresses utilisées dans le trafic avec les interfaces locales (disponibles).

Si vous avez terminé vos expériences, supprimez simplement les espaces de noms:

ip netns del <namespace-name>

Les interfaces seront réaffectées à l'espace de noms par défaut et toute configuration effectuée dans l'espace de noms disparaît (par exemple, pas besoin de supprimer les adresses IP attribuées).


C'est beaucoup plus simple que la magie double nat qui est suggérée, et ne nécessite aucune coordination avec les autres ordinateurs du réseau ni aucune topologie physique. Ma seule demande serait que vous ajoutiez des commandes pour ajouter des itinéraires.
Huckle

2

Ok, j'ai finalement réussi à mettre en place ma config.

L'idée est d'utiliser une autre fausse adresse, pour forcer le routage de cette fausse adresse vers l'interface 2, puis de traduire la fausse adresse avec la vraie adresse 2 avec NAT / iptables.

Ma configuration est en fait composée d'un routeur que je peux telnet entre IF1 (interface 1) et IF2

Dans ma configuration, FAKE_ADDR et IF1_ADDR sont sur le même sous-réseau.

ifconfig $IF1 $IF1_ADDR netmask 255.255.255.0
ifconfig $IF2 $IF2_ADDR netmask 255.255.255.0

iptables -t nat -A PREROUTING -d $FAKE_ADDR -i $IF2 -j DNAT --to-destination $IF2_ADDR
iptables -t nat -A POSTROUTING -s $IF2_ADDR -d $IF1_ADDR/24 -j SNAT --to-source $FAKE_ADDR

route add $FAKE_ADDR gw $ROUTER_ADDR

Et sur le routeur:

route add $FAKE_ADDR gw $IF2_ADDR

Si j'envoie quelque chose à FAKE_ADDR, pkt est transmis via IF1 au routeur, à nouveau transmis à IF2, puis FAKE_IP est remplacé par IF2_ADDR. Le paquet est traité par le serveur, le résultat est renvoyé à IF1_ADDR, depuis IF2_ADDR qui est remplacé par FAKE_ADDR.

Il est peut-être possible d'utiliser une configuration plus simple avec un seul câble croisé, mais comme je n'ai pas essayé, je préfère donner ma solution de travail.


si le routeur envoie $ FAKE_ADDR à $ IF2_ADDR, votre règle DNAT ne doit-elle pas être "-i $ IF2" au lieu de "-i $ IF1"?
cmcginty

Tu as raison Casey, correction faite.
calandoa

1

La réponse donnée ci-dessus par Thomas Tannhäuser était parfaite!

J'ai eu une situation similaire: une seule machine avec deux interfaces enet. Mon plan était d'utiliser une interface comme serveur (récepteur) et l'autre comme client (expéditeur). Chaque interface serait attachée au routeur et iperf conduirait le trafic à travers le routeur pour mesurer le débit, le PPS, le retard, etc.

Malheureusement, l'approche iptables n'était pas intuitive et était lourde de problèmes. Après quelques heures frustrantes, j'ai abandonné ce plan d'attaque. Inspiré par la suggestion de Thomas, j'ai fait quelques devoirs sur les espaces de noms IP Linux et j'ai commencé à apprécier la simplicité et l'élégance de cette solution.

Vous trouverez ci-dessous une liste des commandes exactes que j'ai utilisées pour configurer mon Fedora FC26 pour servir à ce titre. Les deux interfaces sont enp1s0 et enp3s0. Le routeur a deux interfaces avec les adresses 192.168.2.112 et 172.16.16.2. Chaque connecteur FC26 ENET est directement câblé à l'interface de routeur correspondante.

# How to configure the IP Namespaces
ip netns add iperf-server
ip netns add iperf-client
ip link set enp1s0 netns iperf-server
ip link set enp3s0 netns iperf-client
ip netns exec iperf-server ip addr add dev enp1s0 192.168.2.139/20
ip netns exec iperf-client ip addr add dev enp3s0 172.16.16.2/24
ip netns exec iperf-client ip link set dev enp3s0 up
ip netns exec iperf-server ip link set dev enp1s0 up
ip netns exec iperf-server route add default gw 192.168.2.112
ip netns exec iperf-client route add default gw 172.16.16.1

# Test the interfaces and network using ping
ip netns exec iperf-client ping -c1 172.16.16.1
ip netns exec iperf-server ping -c1 192.168.2.112
ip netns exec iperf-server ping -c1 172.16.16.2
ip netns exec iperf-client ping -c1 192.168.2.139

# Start Iperf Server for UDP test
ip netns exec iperf-server iperf -u -s
# Run Client against Iperf server for UDP test
ip netns exec iperf-client iperf -u -c 192.168.2.139

0

Il semble que vous souhaitiez transformer votre boîtier Linux en boîtier de type routeur / pont / passerelle / pare-feu. Les ressources suivantes peuvent être ce que vous recherchez:

Le projet de routeur Linux

Liste des distributions de routeur ou de pare-feu

Routeur Linux LiveCD

Linux Journal - Le routeur Linux

Mise à jour basée sur de plus amples informations:

Je ne pense pas que vous allez pouvoir faire ce que vous voulez. L'OS va toujours regarder sa table de routage interne et «voir» les deux adresses IP localement. Il acheminera ensuite le trafic dans le système d'exploitation et ne le mettra jamais sur le câble. Vous aurez besoin d'une deuxième machine ou de deux machines virtuelles (consultez Xen ).


0

Beaucoup de choses à parcourir ici, donc je ne peux pas garantir totalement ma précision, mais la question initiale semble chercher ce que l'on appelle la technique "envoyer à soi" . La recherche liée montre ce que je pense être le correctif du noyau le mieux maintenu en tant que lien supérieur + discussions et correctifs avec d'autres approches sur diverses listes de diffusion, en particulier. LKML.

Je pense que l'on devrait également regarder les espaces de noms de réseau , fait avec les "ip netns" d'iproute2 . Cela nécessite également une interface supplémentaire et une magie de routage, donc peut-être même pas moins complexe que le massif iptables hoopla dans les autres réponses.

Les commentaires sont les bienvenus si quelqu'un a trouvé quelque chose d'utile avec ceux-ci - le comment, le quoi, le où de votre implémentation.



-1

voici comment je l'ai fait fonctionner pour IPV6

ips statiques assignés

/sbin/ifconfig eth1 inet6 add 2001:db8::1/127 
/sbin/ifconfig eth3 inet6 add 2001:db8::2/127 

configurer des itinéraires d'hôte uniquement vers des adresses "FAKE"

ip -6 route add 2001:db8::2/128 dev eth1 metric 1
ip -6 route add 2001:db8::1/128 dev eth3 metric 1

rempli la table des voisins ... comme l'arp

ip -6 neighbor add 2001:db8::1 lladdr 90:e2:ba:0d:75:e8 dev eth3 # eth1's mac address
ip -6 neighbor add 2001:db8::2 lladdr 90:e2:ba:0d:75:e9 dev eth1 # eth3's mac address

ajouté les entrées ip6tables

ip6tables -t nat -A POSTROUTING -s 2001:db8::1 -d 2013::2 -j SNAT --to-source 2001:db8::1
ip6tables -t nat -A PREROUTING -d 2001:db8::1 -j DNAT --to-destination 2001:db8::1
ip6tables -t nat -A POSTROUTING -s 2001:db8::2 -d 2013::1 -j SNAT --to-source 2001:db8::2
ip6tables -t nat -A PREROUTING -d 2001:db8::2 -j DNAT --to-destination 2001:db8::2

Quelle distribution utilisez-vous? La dernière fois que j'ai vérifié, le noyau n'a pas de table NAT pour IPv6.
fukawi2
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.