web-dev-qa-db-fra.com

Forcer le trafic IP local vers une interface externe

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 demandes à un serveur iperf, ftp, http à 192.168.1.1 ne devraient pas être simplement 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 que je pourrais alors faire NAT transfert de tout le trafic dirigé vers le faux 192.168.1.2 sur eth1, redirigé vers 192.168.1.1 en interne? Je me bats en fait 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 le faire avec Windows, je l'achèterai!

Éditer:

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?

31
calandoa

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 au 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
14
cmcginty

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 court-circuite 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 au-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 NAT scénario: deux nouveaux faux réseaux utilisés pour atteindre l'autre. A la sortie, source NAT vers votre faux réseau . En cours de route, 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 IP correctes et assurez-vous de l'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&R, et j'espère que cela aidera quiconque à trouver ce post à l'avenir.

28
Steve Kehlet

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/config des interfaces doit maintenant être accessible dans le contexte de l'espace de noms affecté - donc ils n'apparaîtront pas si vous exécutez un nu ip link 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 de la pile réseau, de l'interface, du 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).

19
Thomas Tannhäuser

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 transféré 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.

Peut-être qu'il est 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.

2
calandoa

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
1
RarkyMan

Beaucoup de choses à parcourir ici, donc je ne peux pas garantir totalement ma précision, mais la question d'origine semble chercher ce que l'on appelle technique "envoyer à soi-même" . La recherche liée montre ce que je pense être le correctif du noyau le mieux entreten 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 aussi regarder espaces de noms résea , fait avec les iproute2 "ip netns" . 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.

0
lkraav

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-fe

Routeur Linux LiveCD

Journal Linux - 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
Peter

Consultez cet article. Ici, les étapes détaillées sont mentionnées pour permettre l'accès Internet à une virtualbox vm en utilisant NAT forwarding.

http://jackal777.wordpress.com/2012/02/02/13/virtualbox-Host-only-networking-nat-for-internet-access/

0
Reynold