comment éviter de routage local pile dans Linux
J'ai l'environnement suivant: 2 hôtes, chacune avec 2 interfaces Ethernet connecté à l'autre (comme sur le schéma ci-dessous):
+---------+ +---------+
| (1)+---------------+(2) |
| host1 | | host2 |
| | | |
| (3)+---------------+(4) |
+---------+ +---------+
Je voudrais écrire client/serveur socket outil qui va ouvrir à la fois le client et le serveur de sockets sur host1.
Je voudrais client pour l'envoi de paquets TCP à travers l'interface (1) et server pour écouter sur l'interface (3), que les paquets passent par host2.
Normalement Linux pile route les paquets à travers cette pile TCP/IP locale sans envoi de ceux host2.
J'ai essayé d'utiliser SO_BINDTODEVICE option pour à la fois serveur et client, et il semble que le serveur est en effet lié à l'interface (3) et n'est pas à l'écoute localhost trafic. J'ai vérifié que le client de host1 ne pouvait pas être acceptée alors que le client de host2.
Malheureusement client les paquets ne sont pas en envoyer (même tcpdump sur l'interface(1) de ne pas voir les paquets) par le biais de l'interface (1) à l'interface (2).
Bien sûr, le routage est correct (je peux faire un ping (2) de (1), (4) à partir de (1), (4) à partir de (3) et ainsi de suite).
Ma question est de savoir si c'est possible d'être mis en œuvre sans l'aide personnalisé de la pile TCP/IP?
Peut-être que je devrais essayer de changer l'adresse IP de destination (à partir de client) à partir de l'extérieur du réseau (et seront ensuite envoyés à l'aide de la passerelle par défaut de l'interface (1) - interface (2)) et puis dans postrouting modifier ces nouveau à ceux d'origine? Est une telle solution est possible de travailler?
J'écris mon application en C sous Debian.
L'ajout d'un peu plus de détails et précisions:
- bien sûr, les deux paires (1)--(2) et (3)--(4) sont des sous-réseaux différents
- ce que je veux réaliser est (1)-->(2)-->(4)-->(3)
- host2 est blackbox, donc je ne peux pas installer n'importe quel paquet de transitaire (qui va ouvrir socket d'écoute sur l'interface (2) et avant ceux de (3) à (4)) - c'est pétantes ce que je veux éviter
Le problème principal semble être de livraison locale. Quand j'ouvre prise sur host1 et voulez vous connecter à la prise, qui est à l'écoute sur d'autres adresse de l'hôte dans le noyau utilise juste pile locale pour livrer les paquets. Voir netfilter schéma ci-dessous:
--->[1]--->[ROUTE]--->[3]--->[4]--->
| ^
| |
| [ROUTE]
v |
[2] [5]
| ^
| |
v |
Les paquets passent par [5] NF_IP_LOCAL_OUT et [2] NF_IP_LOCAL_IN alors que je veux les forcer à aller à [4].
Vous n'avez certainement pas besoin d'un custom pile TCP pour cela. Pas sûr qu'il s'agit de la meilleure façon, mais vous pourriez le faire certains de traduction d'adresse réseau sur host2 qui serait une carte unique adresse IP à l'adresse de l'interface (3), et assurez-vous que les paquets à (3) de host2 sont acheminés via (4). Host1 serait alors de vous connecter à cette adresse IP unique.
Si un socket se connecte à partir de (1) à (2) sur une autre machine et une autre socket se connecte (4) à (3) sur la première machine, pourquoi le Linux pile TCP ignorer l'envoi de paquets via le réseau? Comment la pile TCP éventuellement savoir à propos de cette inhabituelle de la topologie et comment pourrait-il en éventuellement connaître votre intention?
Pensez-y de cette façon: Vous voulez laisser votre femme (qui est dans la pièce d'à côté) à savoir que le dîner est prêt, mais elle est en colère contre vous et ne pas vous parler. Si vous décidez d'appeler ta mère et dis-lui de dire à son voisin d'appeler votre femme. Vous composez votre mère. Maintenant... qui téléphone pensez-vous de l'anneau? Pensez-vous qu'il est raisonnable de supposer que la compagnie de téléphone, feront de votre femme de la sonnerie du téléphone?
Permet d'ajouter des adresses IP pour obtenir des éclaircissements. Supposons que l'adresse IP de l'interface (1) est 192.168.1.1 et l'adresse IP de l'interface (3) est 192.168.10.1. Quand j'ai ouvert socket et souhaitez connecter 192.168.10.1 noyau savez que c'est l'adresse locale de l'interface d'autres sur host1. Si le noyau Linux est la compagnie de téléphone, il sait exactement ce que je veux appeler ma femme. Le point est de savoir comment le forcer à appeler ma mère , pour appeler le voisin d'abord au lieu de l'appel direct.
OriginalL'auteur codewarrior | 2011-12-16
Vous devez vous connecter pour publier un commentaire.
Non testé (devrait fonctionner, mais j'ai peut-être raté quelque chose):
Linux dispose de plusieurs tables de routage. Tableau local contient certaines routes que le noyau ajoute automatiquement pour chaque adresse IP ajoutées à l'hôte. Vous pouvez les voir avec
ip route show table local
. Itinéraires étiquetés comme local indiquer les itinéraires locaux qui vont par le biais de l'interface de bouclage. Vous pouvez supprimer l'itinéraire et ajouter un normal unicast route pour le remplacer:Maintenant votre 1ère case essaie d'envoyer des datagrammes IP pour l'adresse IP, comme si c'était une adresse distante, e.g: il utilisera le protocole ARP. Donc, votre 2ème case n'aurez qu'à répondre aux requêtes ARP si il agit comme un routeur ou faire du proxy-ARP, ou vous aurez à ajouter une association pour le cache ARP:
Ensuite, vous aurez probablement à désactiver rp_filter sur les interfaces:
De nouveau, si cela ne fonctionne pas, vous pourriez probablement mettre en place quelque chose avec L2 NAT, à l'aide de ebtables.
unicast
au lieu delocal
sur ce deuxièmeip
ligne?est le nom de la table. Je n'ai pas fait de spécifier le type de route dans un commande, pour la première, l'IP sera probablement suffisant pour sélectionner une voie unique à supprimer, pour le second unicast est le type de parcours par défaut.
et oui, j'ai testé la partie, le paquet est vu sur
tcpdump -ni eth0
. Je n'ai pas tester l'ensemble de l'installation, je suis trop paresseux pour cela. De toute façon, l'OP doit probablement ni leARP
partie ni larp_filter
.comment avez-vous bind socket client à l'interface spécifique? J'ai essayé de modifier les tables de routage locales, mais encore mon client paquets sont perdus quelque part par le kernell (ne peut pas voir quoi que ce soit sur l'interface (1)).
vous n'avez pas besoin de se lier à une interface de routage s'occupe de tout. Au moins les datagrammes IP doit être envoyé à l'aide de l'interface spécifiée, je n'ai pas mis en place un deuxième système, donc n'ai pas testé la réception de la partie, permettre
log_martians
et de regarder la journalisation du noyau.OriginalL'auteur ninjalj
Pour très semblable à la tâche que je suis en utilisant un tel script:
OriginalL'auteur Nikolay Bryskin
Vous pouvez affecter différents sous-réseaux (1)-(2) et (3)-(4) paires, et ont host2 transférer les paquets à partir de (2) à (3). Le client sur host1 de connexion à l'adresse de (2), de sorte que le réseau local de la pile ne saura pas que le serveur cible est effectivement en cours d'exécution en local trop.
Vous avez besoin d' quelque chose pour refléter les paquets envoyés à partir de l'interface (1) à l'interface (3) - un pc agir comme un routeur linksys coffret d'installation avec nat, quoi que ce soit. Faire preuve de créativité.
Le problème est avec l'envoi de paquets de host1 de nouveau. Même si le routage est mis à envoyer tous les paquets par le biais de la passerelle par défaut définie à l'interface (2) causes que les paquets envoyer à la deuxième interface de la même périphérique ne sont pas acheminés à l'aide de la passerelle par défaut. Si je bind socket client explicitement à l'interfece (1) les paquets sont rejetés par le noyau (même tcpdump exécuter sur l'interface (1) de ne pas voir les paquets). Donc, le problème ne semble pas être avec le routage lui-même, mais plutôt avec une pile locale de livraison.
Que quelque chose doit ne soit la traduction d'adresse réseau, ou de faire l'utilisation de proxy, de sorte que l'adresse de destination du client n'est pas sur la même machine.
OriginalL'auteur Nikolai Fetissov