GNU/Linux >> Tutoriels Linux >  >> Linux

Forcer le trafic IP local vers une interface externe

Solution 1 :

J'ai utilisé avec succès ce qui suit sous Linux pour tester le débit sur une nouvelle carte 10 Gbps à double port en mode "loopback", c'est-à-dire un port branché directement sur l'autre. Tout cela n'est qu'un peu de vaudou juste pour forcer les paquets à sortir du fil, mais si vous ne le faites pas, Linux court-circuitera simplement le trafic via 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 scénario de double NAT :deux nouveaux faux réseaux utilisés pour atteindre l'autre. En sortant, sourcez le NAT sur votre faux réseau. Sur le chemin, fixez la destination. Et inversement 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

Indiquez 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 la mienne) :

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 mettre réellement des paquets sur le fil. Par exemple :

ping 10.60.1.1

sort eth2, l'adresse IP source 10.50.0.1 est NATée à 10.60.0.1, et lorsqu'elle entre dans eth3, la destination 10.60.1.1 est NATtée à 10.50.1.1. Et la réponse suit un parcours similaire.

Utilisez maintenant iperf pour tester le débit. Connectez-vous 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 se dirige vraiment vers le câble :

tcpdump -nn -i eth2 -c 500

Vous pouvez également regarder /proc/interrupts 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 message en cherchant comment faire cela, merci pour les questions et réponses, et j'espère que cela aidera quelqu'un d'autre à trouver ce message à l'avenir.

Solution 2 :

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 bidouiller avec iptables :)).

Créez des espaces de noms (le tout 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 doivent maintenant être accessibles dans le contexte de l'espace de noms attribué ; elles n'apparaîtront donc 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 de la pile réseau, de l'interface, du routage ... est isolé par les espaces de noms, de sorte que le noyau n'est pas en mesure de 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, il n'est pas nécessaire de supprimer les adresses IP attribuées).

Solution 3 :

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 NIC 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 souhaite envoyer du trafic bidirectionnel via les cartes réseau du 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 maintenant parler à 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 adresse IP. Pour ce faire, créez une route directe 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 fausses adresses IP sur votre PC local. Vous pouvez faire des choses en activant les proxy ARP pour 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

Solution 4 :

Ok, j'ai enfin réussi à paramétrer ma config.

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

Ma configuration est en fait composée d'un routeur que je peux connecter par 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, transmis à nouveau à 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.


Linux
  1. Variable externe dans Awk ?

  2. Python :obtenir la passerelle par défaut pour une interface locale/adresse IP sous Linux

  3. Obtenir des adresses d'interface réseau local en utilisant uniquement proc ?

  4. chmod un lecteur externe fraîchement monté pour configurer l'accès en écriture

  5. Forcer wget à expirer

Ouvrez les ports et acheminez le trafic à travers votre pare-feu

Comment ajouter un stockage externe à ownCloud 9

3 façons de configurer une interface réseau sous Linux

commande ip sous Linux avec des exemples

alternative d'abonnement redhat | Dépôt local

Trafic IP abandonné avec un serveur multirésident