Comment utiliser différentes interfaces réseau pour différents processus?

59

J'ai deux interfaces réseau sur un PC Linux et je dois définir manuellement l'interface qu'un processus donné utilisera.

Le programme (softphone Twinkle) n'a pas une option similaire, donc je crois qu'il doit être configuré en externe.

Comment puis-je le faire?

Edit: je n'essaie pas de lier un processus serveur à une interface spécifique, mais plutôt de faire contacter un programme client par un serveur via une interface spécifique.

Andrea Spadaccini
la source
Les clients utilisent également bind / connect. Consultez la documentation de bind.c.txt pour savoir comment forcer ircII (un programme client irc) à une adresse IP donnée: 'Exemple sous bash pour utiliser votre adresse IP virtuelle comme adresse de départ pour ircII: BIND_ADDR = "votre-adresse-virtuelle" LD_PRELOAD =. / Bind.so ircII '
akira le
J'ai trouvé une approche différente ici, j'espère que cela sera utile (j'espère bien que le routage de la politique du noyau décrit est activé par défaut de nos jours): kindlund.wordpress.com/2007/11/19/…
Savvas Radevic, le

Réponses:

48

vous pouvez remplacer le code à l'exécution à l'aide de LD_PRELOAD (@windows, vous pouvez utiliser une technique similaire appelée détours , assez sophistiquée). cela a pour effet d'informer l'éditeur de liens dynamique de charger d'abord toutes les bibliothèques dans le processus que vous voulez exécuter, puis d'en ajouter un peu plus. vous l'utilisez normalement comme ceci:

% LD_PRELOAD=./mylib.so ls

et par là vous changez ce qui lsfait.

pour votre problème, je voudrais essayer http://www.ryde.net/code/bind.c.txt , que vous pouvez utiliser comme:

% BIND_ADDR="ip_of_ethX" LD_PRELOAD=./bind.so twinkle

voici comment vous le construisez:

% wget http://www.ryde.net/code/bind.c.txt -O bind.c
% gcc -nostartfiles -fpic -shared bind.c -o bind.so -ldl -D_GNU_SOURCE

un howto plus long est http://daniel-lange.com/archives/53-Binding-applications-to-a-specific-IP.html

hacks et outils similaires:

Akira
la source
7
Wow, qu'est-ce qui se passe. +1
sinni800
1
Bonjour, cela semble être un très beau tour, mais ça ne marche pas pour moi. J'ai deux modems 3G qui, une fois connectés, ouvrent deux interfaces (ppp0 et ppp1). Si j'essaie de forcer l'une des deux adresses IP, je finis toujours par sortir avec la même interface (je le vois car j'ai deux instances de Wireshark, une pour chaque interface). J'ai également supprimé les impressions de débogage de bind.c et je constate en effet que la bibliothèque "surchargée" est chargée, donc je ne sais pas pourquoi cela ne fonctionne pas.
Andrea Spadaccini
3
LD_PRELOAD est ignoré si votre UID effectif n’est pas le même que votre UID réel.
Matthias Krull
Le force_bindprojet de Catalin M. Boie soutient ipv6
BurnsBA le
Fonctionne très bien, mais a dû ajouter #include <arpa / inet.h> pour que la compilation réussisse.
anno
31

IP Netns peut le faire.

TL; DR: Créez des espaces de noms réseau, associez-leur des interfaces, puis exécutez "ip netns exec NAME cmd ..."

Il suffit de vérifier si votre distribution prend en charge les réseaux IP ... (Backtrack 5r3, contrairement à Kali;))

EN PLUS DE DÉTAILS:

#create netns
ip netns add myNamespace
#link iface to netns
ip link set eth0 netns myNamespace
#set ip address in namespace
ip netns exec myNamespace ifconfig eth0 192.168.0.10/24 up
#set loopback (may be needed by process run in this namespace)
ip netns exec myNamespace ifconfig lo 127.0.0.1/8 up
#set route in namespace
ip netns exec myNamespace route add default gw 192.168.0.1
#force firefox to run inside namespace (using eth0 as outgoing interface and the route)
ip netns exec myNamespace firefox

Pourquoi est-ce mieux que de lier l'ip via LD_PRELOAD? Parce que LD_PRELOAD ne contrôle pas la route utilisée par les processus. Il utilisera le premier itinéraire.

Et comme il utilise toujours le même itinéraire, il utilisera par défaut l'interface enregistrée pour cet itinéraire (ce qui n'est pas ce que nous souhaitons).

olivervbk
la source
2
Essayez d’ajouter plus de détails à votre réponse.
Renju Chandran Chingath,
4
ne faites pas cela sur le serveur distant si eth0 est l'interface réseau publique ..
mercredi
1
la dernière ligne devrait êtreip netns exec myNamespace firefox
meuh
1
Utilisez "sudo ip netns del <nom-espace-noms>" pour supprimer l’espace-noms en cas de besoin!
Eduardo Lucio
1
@EduardoLucio il devrait être possible de l'exécuter comme: sudo ip netns exec myNamespace su -u someUser -c firefox
olivervbk
2

Je ne pense pas qu'il soit possible de forcer un processus à utiliser une certaine interface.

Cependant, je pense que vous pourrez peut-être jouer avec ipchain / iptables et forcer un port particulier sur lequel votre processus est en écoute n'obtiendra que les paquets provenant d'une interface particulière.

HOWTO utile: http://tldp.org/HOWTO/IPCHAINS-HOWTO.html

thétarro
la source
2
Les deux postes les plus votés prouvent le contraire.
Paul Gear
2

Basé sur @olivervbk, la réponse ci-dessous est mon!

Exécutez toutes les commandes en tant que "root".

Utilisez la commande ...

ip a

... pour connaître le nom de l'interface réseau que vous souhaitez utiliser.

Exécutez les commandes ci-dessous en tant que modèle ...

ip netns add [INTERFACE_NAME]_ns
ip link set dev [INTERFACE_NAME] netns [INTERFACE_NAME]_ns
ip netns exec [INTERFACE_NAME]_ns ifconfig [INTERFACE_NAME] 10.1.1.10/24 up
ip netns exec [INTERFACE_NAME]_ns ifconfig lo 127.0.0.1/8 up
ip netns exec [INTERFACE_NAME]_ns route add default gw 10.1.1.1
ip netns exec [INTERFACE_NAME]_ns dhcpcd [INTERFACE_NAME]
ip netns exec [INTERFACE_NAME]_ns sudo -b -u [YOUR_USER] [APP_NAME] 2> /dev/null 1> /dev/null &
  • [INTERFACE_NAME] - Remplacez-le par le nom de l'interface réseau choisie.
  • [YOUR_USER] - Remplacez-le par votre nom d'utilisateur.
  • [NOM_APP] - Nom de l'application qui sera exécutée dans l'espace de noms "[NOM INTERFACE] _ns". Exemple: "firefox".

REMARQUE I: Les indicateurs "-b -u" de la commande "sudo" permettent à l'application de s'exécuter avec votre utilisateur (et non "root") et en arrière-plan en libérant le terminal. L' 2> /dev/null 1> /dev/null &extrait de code empêche les sorties de "[APP_NAME]" d'être imprimées sur le terminal.
NOTE II: Les valeurs de ip "10.1.1.10" et "10.1.1.1" sont arbitraires.
NOTE III: Pour travailler pour moi, je devais exécuter la dhcpcd [INTERFACE_NAME]commande.

Pour supprimer l'espace de noms, utilisez ...

ip netns del [INTERFACE_NAME]_ns

... ou...

ip -all netns delete

... pour supprimer tout ce qui existe.

Eduardo Lucio
la source
1

Généralement, si un programme n'a pas d'option pour configurer une interface d'écoute, il écoute sur TOUTES les interfaces. (Vous pouvez le vérifier avec lsof -i).

La meilleure chose à faire consiste à créer des règles de pare-feu iptables qui suppriment le trafic entrant pointé vers ses ports sur des interfaces sur lesquelles vous ne voulez pas qu'il soit visible.

LawrenceC
la source
1

Alternative I:

Utilisation de ld_preload pour forcer la passerelle d'interface https://github.com/Intika-Linux-Network/App-Route-Jail

Forcer une application à utiliser une interface réseau spécifique

Nous devons trouver quelle passerelle est utilisée par l'interface réseau, puis forcer cette passerelle vers notre application emprisonnée et ainsi forcer l'application à se lier à une interface réseau spécifique.

  • Comment trouver la passerelle d'interface (il existe de nombreuses solutions pour trouver la passerelle, voici quelques commandes permettant de trouver la passerelle utilisée)
$ route
$ route -n
$ ip rule list
$ ip route show
$ netstat -rn
$ cat /etc/network/interfaces
$ cat /etc/sysconfig/network-scripts/ifcfg-eth0
$ traceroute www.google.com
$ ip route show 0.0.0.0/0 dev eth0

Par passerelle d'application

  • Construire App-Route-Jail
git clone https://github.com/Intika-Linux-Network/App-Route-Jail.git
cd Approute-Utils
chown 755 make.sh
./make.sh
  • Ajouter une route pour les futurs paquets marqués (pour l'application jailed) dans cet exemple 192.168.1.1est utilisé comme passerelle forcée, cette règle de route n'affectera pas les autres applications, cette manipulation doit être effectuée une seule fois au démarrage du système par exemple si vous souhaitez utiliser cette solution quotidiennement
ip rule add fwmark 10 table 100
ip route add default via 192.168.1.1 table 100
  • Démarrer l'application que vous voulez emprisonner
MARK=10 LD_PRELOAD=./mark.so firefox
  • Test de l'adresse IP wan
MARK=10 LD_PRELOAD=./mark.so wget -qO- ifconfig.me

Alternative II:

Firejail https://firejail.wordpress.com/ peut forcer une application à utiliser un réseau spécifique, mais la compatibilité est limitée.

firejail --dns=8.8.8.8 --net=eth0 --ip=192.168.1.1
intika
la source
Notez que cette marque n'est pas possible pour les utilisateurs normaux, vous devez l'exécuter en tant que root.
Jornane
-2

Pourquoi voudriez-vous qu'un programme utilise une interface autre que celle connectée au serveur pour communiquer avec ce serveur? Et si le système n’utilise pas l’interface connectée à un serveur pour communiquer avec ce serveur, il s’agit d’un problème lié au système (table de routage) et n’a aucun rapport avec le processus qui souhaite communiquer avec ce serveur.

Différents serveurs sur les réseaux IP ont des adresses IP différentes. Le noyau doit savoir quelle interface utiliser pour atteindre une adresse IP particulière en fonction de la table de routage. Si vous essayez de parler à deux serveurs différents ayant la même adresse IP, le système sera confus (entre autres choses, il indexe uniquement les connexions en interne par adresse de destination). Cela peut fonctionner, mais c'est un correctif au niveau du système impliquant de placer un serveur dans un réseau logique séparé qui est uniquement connecté à la machine via le logiciel NAT.

Par conséquent, s’ils ont des adresses IP différentes, utilisez les itinéraires pour sélectionner la bonne interface. S'ils ont la même adresse IP, vous devez utiliser NAT afin qu'ils semblent avoir des adresses IP différentes pour le système.

David Schwartz
la source
3
Premièrement, il peut y avoir plusieurs routes valides entre le client et le serveur, mais avec des caractéristiques différentes adaptées à différents types de trafic; Par exemple, l'UMTS (données cellulaires) peut coûter de l'argent mais a une portée plus grande que le WiFi, mais les deux sont plus lents qu'une connexion par fibre. Si les fournisseurs en amont effectuent un filtrage de source (ou NAT), vous n'avez pas d'autre choix que d'envoyer la «bonne» interface. Deuxièmement, influencer le routage n'est pas la seule raison de choisir une adresse source. Même si les deux adresses sont sur la même interface, il peut être utile de contrôler le lien avec lequel établir les connexions, car le serveur
Dans un cas, vous avez différentes adresses IP publiques et vous souhaitez lancer un nouveau processus dans chacune d'elles pour les connexions sortantes.
Rfraile