Bagaimana cara menggunakan antarmuka jaringan yang berbeda untuk proses yang berbeda?

59

Saya memiliki dua antarmuka jaringan pada PC Linux, dan saya perlu mengatur antarmuka secara manual yang akan digunakan proses tertentu.

Program ini tidak memiliki opsi serupa, jadi saya percaya bahwa itu harus diatur secara eksternal.

Bagaimana saya bisa melakukannya?

Sunting: Saya tidak mencoba untuk membuat proses server mengikat ke antarmuka tertentu, melainkan untuk membuat program klien menghubungi server menggunakan antarmuka tertentu.

Andrea Spadaccini
sumber
klien menggunakan bind / connect juga, lihat dokumentasi bind.c.txt tentang cara memaksa ircII (program irc-client) ke ip yang diberikan: 'Contoh dalam bash untuk menggunakan IP virtual Anda sebagai sumber alamat Anda untuk ircII: BIND_ADDR = "your-virt-ip" LD_PRELOAD =. / Bind.so ircII '
akira
Saya menemukan pendekatan yang berbeda di sini, saya harap ini membantu (Saya yakin berharap perutean kebijakan kernel yang dijelaskan diaktifkan secara default saat ini): kindlund.wordpress.com/2007/11/19/…
Savvas Radevic

Jawaban:

48

Anda dapat mengganti kode saat runtime dengan menggunakan LD_PRELOAD (@windows Anda dapat menggunakan teknik serupa yang disebut jalan memutar , cukup mewah). apa yang dilakukan adalah memberi tahu tautan dinamis untuk pertama-tama memuat semua lib ke dalam proses yang ingin Anda jalankan dan kemudian menambahkan lebih banyak di atasnya. Anda biasanya menggunakannya seperti ini:

% LD_PRELOAD=./mylib.so ls

dan dengan itu Anda mengubah apa yang lsdilakukannya.

untuk masalah Anda, saya akan mencoba http://www.ryde.net/code/bind.c.txt , yang dapat Anda gunakan seperti:

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

di sini adalah bagaimana Anda membangunnya:

% 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

howto yang lebih panjang adalah http://daniel-lange.com/archives/53-Binding-applications-to-a-specific-IP.html

peretasan dan alat serupa:

akira
sumber
7
Wow, apa-apaan ini. +1
sinni800
1
Hai, ini sepertinya trik yang sangat bagus, tetapi tidak berhasil untuk saya. Saya memiliki dua modem 3G yang, ketika terhubung, buka dua antarmuka (ppp0 dan ppp1). Jika saya mencoba memaksakan salah satu dari dua IP, saya selalu berakhir dengan antarmuka yang sama (saya melihatnya karena saya memiliki dua contoh wireshark, satu untuk setiap antarmuka). Saya juga menghapus cetakan debug dari bind.c dan memang saya melihat bahwa perpustakaan "kelebihan beban" dimuat, jadi saya tidak tahu mengapa itu tidak berhasil.
Andrea Spadaccini
3
LD_PRELOAD diabaikan jika UID efektif Anda tidak sama dengan UID asli Anda.
matthias krull
The force_bindproyek dengan Catalin M. Boie mendukung ipv6
BurnsBA
Bekerja dengan baik tetapi harus menambahkan #include <arpa / inet.h> agar kompilasi berhasil.
Umumkan
31

ip netns dapat melakukan ini.

TL; DR: Buat ruang nama jaringan, kaitkan antarmuka dengan mereka dan kemudian jalankan "ip netns exec NAME cmd ..."

Periksa apakah distro Anda mendukung ip netns ... (Backtrack 5r3 tidak, sedangkan Kali tidak;))

DALAM RINCIAN LEBIH LANJUT:

#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

Mengapa ini lebih baik daripada mengikat ip melalui LD_PRELOAD? Karena LD_PRELOAD tidak mengontrol rute yang digunakan proses. Ini akan menggunakan rute pertama.

Dan karena selalu menggunakan rute yang sama, itu akan default ke antarmuka yang terdaftar ke rute. (Yang bukan yang kita inginkan)

olivervbk
sumber
2
Silakan coba tambahkan rincian lebih lanjut ke jawaban Anda.
Renju Chandran chingath
4
jangan lakukan ini di server jauh jika eth0 adalah antarmuka jaringan publik ..
ygrek
1
baris terakhir adalahip netns exec myNamespace firefox
meuh
1
Gunakan "sudo ip netns del <namespace-name>" untuk menghapus namespace saat dibutuhkan!
Eduardo Lucio
1
@EduardoLucio harus dimungkinkan untuk mengeksekusinya seperti: sudo ip netns exec myNamespace su -u someUser -c firefox
olivervbk
2

Saya tidak berpikir mungkin untuk memaksa suatu proses untuk menggunakan antarmuka tertentu.

Namun, saya pikir Anda mungkin bisa bermain dengan ipchain / iptables dan memaksakan bahwa port tertentu yang didengarkan proses Anda hanya akan mendapatkan paket yang datang melalui antarmuka tertentu.

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

thetarro
sumber
2
Dua tulisan dengan suara lebih tinggi membuktikan sebaliknya.
Paul Gear
2

Berdasarkan @olivervbk, jawaban di bawah adalah milikku!

Jalankan semua perintah sebagai "root".

Gunakan perintah ...

ip a

... untuk mengetahui nama antarmuka jaringan yang ingin Anda gunakan.

Jalankan perintah di bawah ini sebagai templat ...

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] - Ganti dengan nama antarmuka jaringan yang dipilih.
  • [YOUR_USER] - Ganti dengan nama pengguna Anda.
  • [APP_NAME] - Nama aplikasi yang akan dieksekusi di namespace "[INTERFACE_NAME] _ns". Misalnya: "firefox".

CATATAN I: Tanda "-b -u" pada perintah "sudo" memungkinkan aplikasi untuk berjalan menggunakan pengguna Anda (bukan "root") dan di latar belakang melepaskan terminal. The 2> /dev/null 1> /dev/null &potongan adalah untuk mencegah output dari "[APP_NAME]" yang dicetak di terminal.
CATATAN II: Nilai-nilai ip "10.1.1.10" dan "10.1.1.1" adalah arbitrer.
CATATAN III: Untuk bekerja untuk saya, saya harus menjalankan dhcpcd [INTERFACE_NAME]perintah.

Untuk menghapus namespace gunakan ...

ip netns del [INTERFACE_NAME]_ns

... atau...

ip -all netns delete

... untuk menghapus semua yang ada.

Eduardo Lucio
sumber
1

Biasanya jika suatu program tidak memiliki opsi untuk mengatur antarmuka mendengarkan, itu mendengarkan pada SEMUA antarmuka. (Anda dapat memverifikasi ini dengan lsof -i).

Membuat aturan firewall iptables yang menjatuhkan lalu lintas masuk ke port-portnya pada antarmuka yang tidak Anda inginkan terlihat adalah hal yang paling mudah untuk dilakukan.

LawrenceC
sumber
1

Alternatif I:

Menggunakan ld_preload untuk memaksa antarmuka gateway https://github.com/Intika-Linux-Network/App-Route-Jail

Memaksa aplikasi untuk menggunakan antarmuka jaringan tertentu

Kita perlu menemukan gateway apa yang digunakan antarmuka jaringan kemudian memaksa gateway itu ke aplikasi kita yang dipenjara dan dengan demikian memaksa aplikasi untuk mengikat ke antarmuka jaringan tertentu

  • Cara menemukan antarmuka gateway (ada banyak solusi untuk menemukan gateway di sini adalah beberapa perintah yang memungkinkan untuk menemukan gateway yang digunakan)
$ 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 gerbang aplikasi

  • Bangun App-Route-Jail
git clone https://github.com/Intika-Linux-Network/App-Route-Jail.git
cd Approute-Utils
chown 755 make.sh
./make.sh
  • Tambahkan rute untuk paket yang ditandai di masa depan (untuk aplikasi yang dipenjara) dalam contoh 192.168.1.1ini digunakan sebagai gateway paksa, aturan rute ini tidak akan mempengaruhi aplikasi lain, manipulasi ini harus dilakukan hanya sekali pada boot sistem misalnya jika Anda ingin gunakan solusi ini setiap hari
ip rule add fwmark 10 table 100
ip route add default via 192.168.1.1 table 100
  • Mulai aplikasi yang ingin dipenjara
MARK=10 LD_PRELOAD=./mark.so firefox
  • Menguji alamat IP lemah
MARK=10 LD_PRELOAD=./mark.so wget -qO- ifconfig.me

Alternatif II:

Firejail https://firejail.wordpress.com/ dapat memaksa aplikasi untuk menggunakan jaringan tertentu, tetapi kompatibilitasnya terbatas.

firejail --dns=8.8.8.8 --net=eth0 --ip=192.168.1.1
intika
sumber
Perhatikan bahwa tanda itu tidak mungkin untuk pengguna normal, Anda harus menjalankannya sebagai root.
jornane
-2

Mengapa Anda ingin program menggunakan antarmuka selain yang terhubung ke server untuk berbicara dengan server itu? Dan jika sistem tidak menggunakan antarmuka yang terhubung ke server untuk berbicara ke server itu, itu adalah masalah tingkat-tabel (tabel routing) dan tidak ada hubungannya dengan proses yang ingin berbicara dengan server itu.

Server yang berbeda pada jaringan IP memiliki alamat IP yang berbeda. Kernel harus mengetahui antarmuka mana yang digunakan untuk mencapai alamat IP tertentu berdasarkan tabel routing. Jika Anda mencoba berbicara dengan dua server berbeda yang memiliki alamat IP yang sama, sistem akan menjadi bingung (karena, antara lain, itu hanya mengindeks koneksi secara internal berdasarkan alamat tujuan). Anda dapat membuatnya bekerja, tetapi ini adalah perbaikan tingkat sistem yang melibatkan penempatan satu server di jaringan logis terpisah yang hanya terhubung ke mesin melalui perangkat lunak NAT.

Jadi jika mereka memiliki alamat IP yang berbeda, gunakan rute untuk memilih antarmuka yang benar. Jika mereka memiliki alamat IP yang sama, Anda perlu menggunakan NAT sehingga mereka tampaknya memiliki alamat IP yang berbeda untuk sistem.

David Schwartz
sumber
3
Pertama, mungkin ada beberapa rute yang valid antara klien & server, tetapi dengan karakteristik berbeda yang cocok untuk berbagai jenis lalu lintas; mis. UMTS (Data Seluler) mungkin membutuhkan biaya tetapi memiliki jangkauan lebih besar dari WiFi, tetapi keduanya lebih lambat dari koneksi serat. Jika penyedia upstream melakukan pemfilteran sumber (atau NAT), Anda tidak punya pilihan selain mengirimkan antarmuka yang 'benar'. Kedua, mempengaruhi perutean bukan satu-satunya alasan untuk memilih alamat sumber. Bahkan ketika kedua alamat berada pada antarmuka yang sama, akan berguna untuk mengontrol yang terikat ketika memulai koneksi, sebagai server
Satu kasus adalah jika Anda memiliki IP publik yang berbeda dan Anda ingin meluncurkan proses baru di masing-masing untuk koneksi keluar.
Rfraile