Come utilizzare interfacce di rete diverse per processi diversi?


59

Ho due interfacce di rete su un PC Linux e devo impostare manualmente l'interfaccia che verrà utilizzata da un determinato processo.

Il programma (Twinkle softphone) non ha un'opzione simile, quindi credo che debba essere impostato esternamente.

Come posso farlo?

Modifica: non sto cercando di associare un processo server a un'interfaccia specifica, ma piuttosto di fare in modo che un programma client contatta un server utilizzando un'interfaccia specifica.


i client usano anche bind / connect, guarda la documentazione di bind.c.txt su come forzare ircII (un programma client irc) su un determinato ip: 'Esempio in bash per usare il tuo IP virtuale come indirizzo sorgente in uscita per ircII: BIND_ADDR = "your-virt-ip" LD_PRELOAD =. / Bind.so ircII '
akira

Ho trovato un approccio diverso qui, spero sia utile (spero che al giorno d'oggi il routing delle politiche del kernel descritto sia abilitato di default): kindlund.wordpress.com/2007/11/19/…
Savvas

Risposte:


48

puoi sostituire il codice in fase di esecuzione usando LD_PRELOAD (@windows puoi usare una tecnica simile chiamata deviazioni , piuttosto elaborata). ciò che fa è informare il linker dinamico di caricare prima tutte le librerie nel processo che si desidera eseguire e quindi aggiungerne un po 'di più. normalmente lo usi in questo modo:

% LD_PRELOAD=./mylib.so ls

e con ciò cambi ciò che lsfa.

per il tuo problema proverei http://www.ryde.net/code/bind.c.txt , che puoi usare come:

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

ecco come lo costruisci:

% 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 più lungo è http://daniel-lange.com/archives/53-Binding-applications-to-a-specific-IP.html

hack e strumenti simili:


7
Wow, che diamine. +1
sinni800

1
Ciao, questo sembra davvero un bel trucco, ma non funziona per me. Ho due modem 3G che, quando collegati, aprono due interfacce (ppp0 e ppp1). Se provo a forzare uno dei due IP, finisco sempre per uscire con la stessa interfaccia (lo vedo perché ho due istanze di WireShark, una per ogni interfaccia). Ho anche rimosso le stampe di debug da bind.c e in effetti vedo che la libreria "sovraccaricata" è caricata, quindi non so perché non funzioni.
Andrea Spadaccini,

3
LD_PRELOAD viene ignorato se il tuo UID effettivo non è lo stesso del tuo UID reale.
Matthias Krull,

Il force_bindprogetto di Catalin M. Boie supporta ipv6
BurnsBA

Funziona benissimo ma ho dovuto aggiungere #include <arpa / inet.h> per avere successo.
anno

31

ip netns può farlo.

TL; DR: crea spazi dei nomi di rete, associa loro interfacce ed esegui "ip netns exec NAME cmd ..."

Controlla se la tua distribuzione supporta ip netns ... (Backtrack 5r3 no, mentre Kali no;))

IN PIÙ DETTAGLI:

#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

Perché è meglio che associare l'ip tramite LD_PRELOAD? Perché LD_PRELOAD non controlla la route utilizzata dai processi. Userà il primo percorso.

E dal momento che utilizza sempre la stessa route, passerà automaticamente all'interfaccia registrata sulla route (che non è ciò che vogliamo)


2
Prova ad aggiungere maggiori dettagli alla tua risposta.
Renju Chandran Chingath,

4
non farlo sul server remoto se eth0 è l'interfaccia di rete pubblica ..
ygrek

1
l'ultima riga dovrebbe essereip netns exec myNamespace firefox
meuh

1
Usa "sudo ip netns del <nomepace-nome>" per rimuovere lo spazio dei nomi quando necessario!
Eduardo Lucio,

1
@EduardoLucio dovrebbe essere possibile eseguirlo come: sudo ip netns exec myNamespace su -u someUser -c firefox
olivervbk

2

Non penso che sia possibile forzare un processo a utilizzare una determinata interfaccia.

Tuttavia, penso che potresti essere in grado di giocare con ipchain / iptables e forzare che una determinata porta che il tuo processo sta ascoltando otterrà solo i pacchetti che arrivano attraverso una particolare interfaccia.

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


2
I due posti più votati dimostrano il contrario.
Paul Gear,

2

Sulla base di @olivervbk la risposta qui sotto è la mia!

Esegui tutti i comandi come "root".

Usa il comando ...

ip a

... per scoprire il nome dell'interfaccia di rete che vorrai usare.

Esegui i comandi seguenti come modello ...

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] - Sostituisci con il nome dell'interfaccia di rete scelta.
  • [YOUR_USER]: sostituisci con il tuo nome utente.
  • [APP_NAME] - Nome dell'applicazione che verrà eseguita nello spazio dei nomi "[INTERFACE_NAME] _ns". Ad esempio: "Firefox".

NOTA I: I flag "-b -u" nel comando "sudo" consentono all'applicazione di essere eseguita utilizzando l'utente (non "root") e in background rilasciando il terminale. Lo 2> /dev/null 1> /dev/null &snippet impedisce di stampare sul terminale gli output di "[APP_NAME]".
NOTA II: I valori di ip "10.1.1.10" e "10.1.1.1" sono arbitrari.
NOTA III: per funzionare per me ho dovuto eseguire il dhcpcd [INTERFACE_NAME]comando.

Per rimuovere lo spazio dei nomi usa ...

ip netns del [INTERFACE_NAME]_ns

... o...

ip -all netns delete

... per rimuovere ciò che esiste.


1

Di solito se un programma non ha opzioni per l'impostazione dell'interfaccia di ascolto, è in ascolto su TUTTE le interfacce. (Puoi verificarlo con lsof -i).

Creare le regole del firewall iptables che rilasciano il traffico in entrata puntato verso le sue porte su interfacce su cui non vuoi che sia visibile è la cosa più semplice da fare.


1

Alternativa I:

Utilizzo di ld_preload per forzare il gateway dell'interfaccia https://github.com/Intika-Linux-Network/App-Route-Jail

Forza un'applicazione a utilizzare un'interfaccia di rete specifica

Dobbiamo trovare quale gateway sta utilizzando l'interfaccia di rete, quindi forzare quel gateway per la nostra applicazione in jail e quindi forzare l'applicazione a legarsi a una specifica interfaccia di rete

  • Come trovare il gateway di interfaccia (ci sono molte soluzioni per trovare il gateway qui ci sono alcuni comandi che consentono di trovare il gateway usato)
$ 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

Per gateway applicazione

  • Crea App-Route-Jail
git clone https://github.com/Intika-Linux-Network/App-Route-Jail.git
cd Approute-Utils
chown 755 make.sh
./make.sh
  • Aggiungere una route per i futuri pacchetti contrassegnati (per l'applicazione jailed) in questo esempio 192.168.1.1viene utilizzata come gateway forzato, questa regola di route non influirà su altre applicazioni, questa manipolazione deve essere eseguita una sola volta all'avvio del sistema, ad esempio se si desidera usa questa soluzione ogni giorno
ip rule add fwmark 10 table 100
ip route add default via 192.168.1.1 table 100
  • Avviare l'applicazione che si desidera imprigionare
MARK=10 LD_PRELOAD=./mark.so firefox
  • Test dell'indirizzo IP pallido
MARK=10 LD_PRELOAD=./mark.so wget -qO- ifconfig.me

Alternativa II:

Firejail https://firejail.wordpress.com/ può forzare un'applicazione a utilizzare una rete specifica, ma la compatibilità è limitata.

firejail --dns=8.8.8.8 --net=eth0 --ip=192.168.1.1

Si noti che il segno non è possibile per gli utenti normali, è necessario eseguire come root.
jornane,

-2

Perché vorresti che un programma usasse un'interfaccia diversa da quella connessa al server per parlare con quel server? E se il sistema non utilizza l'interfaccia connessa a un server per parlare con quel server, si tratta di un problema a livello di sistema (tabella di routing) e non ha nulla a che fare con quale processo vuole parlare con quel server.

Server diversi su reti IP hanno indirizzi IP diversi. Il kernel dovrebbe sapere quale interfaccia utilizzare per raggiungere un determinato indirizzo IP in base alla tabella di routing. Se stai cercando di parlare con due server diversi che hanno lo stesso indirizzo IP, il sistema verrà confuso (perché, tra le altre cose, indicizza le connessioni internamente solo per indirizzo di destinazione). Puoi farlo funzionare, ma è una correzione a livello di sistema che comporta l'inserimento di un server in una rete logica separata che è connessa alla macchina solo tramite il software NAT.

Quindi, se hanno indirizzi IP diversi, utilizzare le route per selezionare l'interfaccia corretta. Se hanno lo stesso indirizzo IP, è necessario utilizzare NAT in modo che sembrino avere indirizzi IP diversi sul sistema.


3
In primo luogo, potrebbero esserci più percorsi validi tra client e server, ma con caratteristiche diverse adatte a diversi tipi di traffico; ad es. UMTS (dati cellulare) può costare denaro ma ha una portata maggiore rispetto al WiFi, ma entrambi sono più lenti di una connessione in fibra ottica. Se i provider upstream eseguono il filtro di origine (o NAT), non hai altra scelta che inviare l'interfaccia "giusta". In secondo luogo, influenzare il routing non è l'unico motivo per selezionare un indirizzo di origine. Anche quando entrambi gli indirizzi si trovano sulla stessa interfaccia, può essere utile controllare a cosa è associato l'avvio di connessioni, come il server

Un caso è se si hanno IP pubblici diversi e si desidera avviare un nuovo processo in ognuno per le connessioni in uscita.
Rfraile,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.