Rutekan lalu lintas melalui antarmuka khusus untuk proses di linux

20

Apakah mungkin untuk mengarahkan lalu lintas yang digunakan oleh suatu proses melalui antarmuka tertentu?

Misalnya, lalu lintas jaringan dengan aplikasi unduhan harus selalu menggunakan antarmuka wlan0sedangkan semua aplikasi lain pada mesin harus menggunakan eth0.

Apakah mungkin untuk memiliki aturan semacam ini di Linux?

Suresh
sumber

Jawaban:

22

Ini dapat dilakukan dengan menggunakan Namespace Linux Network.

Berikut adalah artikel yang menjelaskan caranya. Pada dasarnya Anda membuat namespace jaringan dengan rute default yang berbeda dan menjalankan proses yang membutuhkannya. Anda menghubungkan namespace jaringan yang baru dibuat ke adaptor fisik dengan jembatan (tetapi tentu saja solusi lain mungkin).

Pembaruan: dari kernel 3.14 bahkan lebih mudah menggunakan grup kontrol, seperti yang dijelaskan dalam artikel ini . Kamu harus:

1) tentukan grup kontrol net_cls untuk membubuhi keterangan paket dari proses yang diberikan dengan classid (atau grup proses, perhatikan bahwa tidak ada hubungan orangtua-anak di antara mereka)

2) gunakan modul iptables cgroup (ditambahkan di Linux 3.14) untuk menandai paket

3) gunakan perutean kebijakan (aturan ip tambahkan fwmark ....) untuk membuat tabel perutean baru untuk paket yang ditandai

Keuntungannya adalah bahwa kita tidak perlu melakukan hal menjembatani dan semuanya jauh lebih dinamis berkat grup c.

chripell
sumber
14

Saya telah sooo berjuang dengan ini jadi inilah solusi SELESAI. Ini diuji pada Ubuntu 15 & 16. Anda terutama dapat menggunakannya dengan OpenVPN untuk merutekan aplikasi tertentu di luar antarmuka terowongan VPN.

Solusi "cgroup" lengkap

Bagaimana cara kerjanya?

  • Kernel Linux akan menempatkan aplikasi ke dalam kelompok kontrol . Lalu lintas jaringan dari aplikasi dalam cgroup ini akan diidentifikasi oleh ID kelas mereka di tingkat pengontrol jaringan.
  • iptables akan menandai lalu lintas ini dan memaksanya untuk keluar dengan IP yang tepat
  • ip route akan memproses traffic yang ditandai dalam tabel routing yang berbeda, dengan rute default ke gateway IP apa pun yang Anda inginkan.

Script otomatis

Saya telah membuat skrip novpn.sh untuk mengotomatiskan instalasi & jalankan dependensi. Diuji di Ubuntu.

Mulai VPN Anda terlebih dahulu.

wget https://gist.githubusercontent.com/kriswebdev/a8d291936fe4299fb17d3744497b1170/raw/cf8b37fbe6c3f50a0be825eb77cafa3e0134946f/novpn.sh
# If you don't use eth0, edit the script setting.
sudo chmod +x novpn.sh
./novpn.sh traceroute www.google.com
./novpn.sh --help

Cara Manual

Pertama, instal dukungan dan alat cgroup:

sudo apt-get install cgroup-lite cgmanager cgroup-tools

Reboot (mungkin tidak perlu).

Anda membutuhkan iptables 1.6 .0+. Dapatkan sumber rilis iptables 1.6.0 , ekstrak, lalu jalankan ini ( --disable-nftablesflag akan menghindari kesalahan) dari dir sumber iptables:

sudo apt-get install dh-autoreconf bison flex
./configure --prefix=/usr      \
            --sbindir=/sbin    \
            --disable-nftables \
            --enable-libipq    \
            --with-xtlibdir=/lib/xtables
make
sudo make install
iptables --version

Sekarang, konfigurasi sebenarnya. Tentukan grup kontrol yang bernama novpn. Proses dalam cgroup ini akan memiliki classid 0x00110011(11:11).

sudo su
mkdir /sys/fs/cgroup/net_cls/novpn
cd /sys/fs/cgroup/net_cls/novpn
echo 0x00110011 > net_cls.classid

Sekarang, kita anggap antarmuka yang ingin Anda gunakan untuk aplikasi tertentu adalah eth0dengan IP gateway 10.0.0.1. Ganti ini dengan apa yang Anda inginkan (dapatkan info dari ip route). Jalankan diam sebagai root:

# Add mark 11 on packets of classid 0x00110011
iptables -t mangle -A OUTPUT -m cgroup --cgroup 0x00110011 -j MARK --set-mark 11

# Force the packets to exit through eth0 with NAT
iptables -t nat -A POSTROUTING -m cgroup --cgroup 0x00110011 -o eth0 -j MASQUERADE

# Define a new "novpn" routing table
# DO THIS JUST ONCE !
echo 11 novpn >> /etc/iproute2/rt_tables

# Packets with mark 11 will use novpn
ip rule add fwmark 11 table novpn

# Novpn has a default gateway to the interface you want to use
ip route add default via 10.0.0.1 table novpn

# Unset reverse path filtering for all interfaces, or at least for "eth0" and "all"
for i in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > $i; done

Terakhir, jalankan aplikasi Anda pada antarmuka spesifik:

exit
sudo cgcreate -t $USER:$USER -a $USER:$USER -g net_cls:novpn
cgexec -g net_cls:novpn traceroute www.google.com
# Close all Firefox windows first
cgexec -g net_cls:novpn firefox

Atau jika Anda ingin memindahkan proses yang sudah berjalan ke cgroup, well ... Anda tidak bisa! Itu tampaknya karena fungsi NAT (masquerade): iptables -nvL -t nattidak cocok ketika cgroup diaktifkan, tetapi iptables -nvL -t mangletidak cocok.

# Get PID of the process (we'll then suppose it's 1234)
pidof firefox
# Add to cgroup - THIS DOESN'T WORK! Silently fails to produce the final result.
sudo echo 1234 > /sys/fs/cgroup/net_cls/novpn/tasks
# Remove - but this works...
sudo echo 1234 > /sys/fs/cgroup/net_cls

Kredit: Tidak ada jawaban yang berfungsi seperti yang diharapkan, tetapi campurannya memang: artikel chripell answer evolware Per proses routing mengambil 2: menggunakan cgroup, iptables dan kebijakan routing , Bagaimana cara membuat proses tertentu TIDAK melalui koneksi OpenVPN? , Bunuh sakelar untuk OpenVPN berdasarkan iptables

KrisWebDev
sumber
Terima kasih atas jawaban yang bagus, bagaimana cara membuatnya bekerja dengan apache? Saya mencoba cgexec -g net_cls:novpn apache2dan memberi saya seluruh daftar variabel tidak terdefinisi variabel!
razzak
2
Anda akan mendapatkan kesalahan yang sama dengan menjalankan apache2langsung dari terminal. Itu karena apache2biasanya diluncurkan sebagai layanan, dengan systemctl start apache2. Namun, itu tidak akan berhasil cgexec. Program yang dipanggil harus merupakan induk dari proses ( apache2) yang diinginkan untuk disebarluaskan oleh net_cls cgroup. Jadi, Anda perlu menemukan skrip peluncuran. Dalam hal ini, ini sudo cgexec -g net_cls:novpn /usr/sbin/apache2ctl start. Periksa dengan ./novpn.sh --list.
KrisWebDev
Itu tidak berfungsi di ubuntu 16.04 lagi!
razzak
2
Saya menggunakannya di Ubuntu 16.04 dan berfungsi dengan baik. Nama antarmuka telah berubah di Ubuntu 16, Anda dapat mengganti kebutuhan untuk mengganti eth0dengan sesuatu seperti enp7s0. Dapatkan info dari ifconfigperintah.
KrisWebDev
Terima kasih. Tetapi itu tidak berfungsi di Ubuntu 18.04 karena cpmanager telah dihapus karena konflik dengan systemd
skonsoft
3

Menggabungkan jawaban yang sangat baik dari mariusmatutiae dan KrisWebDev Saya telah membuat versi modifikasi yang luar biasa dari novpn.shscript KrisWebDev . Sementara skrip KrisWebDev dirancang untuk menggaruk gatal yang lebih spesifik (proses berjalan dan bergerak di dalam / di luar VPN), versi saya memungkinkan Anda untuk menjalankan perintah apa pun di lingkungan jaringan yang Anda tentukan. Anda dapat menentukan antarmuka yang akan diikat, rute default, tentukan aturan iptables Anda sendiri, rute statis, tentukan "tes" untuk mengonfirmasi semuanya beroperasi sesuai keinginan sebelum menjalankan perintah ... dll). Ini memungkinkan Anda untuk menggunakan banyak file konfigurasi sehingga Anda dapat menentukan sejumlah lingkungan jaringan tertentu yang dapat Anda jalankan perintah / proses di dalamnya.

Saya mempostingnya sebagai intisari di sini: https://gist.github.com/level323/54a921216f0baaa163127d960bfebbf0

Ia bahkan dapat membersihkan tabel cgroup / iptables / routing sesudahnya!

Umpan balik.

PS - Ini dirancang untuk Debian 8 (Jessie)

semuanya alami
sumber
Hai @allnatural, saya ingin menggunakan skrip altnetworking.sh Anda, tetapi apa yang harus saya masukkan ke file konfigurasi?
Cris70
0

Tidak per aplikasi, tidak. Anda dapat melakukannya per port atau per ip-address dll, atau aplikasi itu sendiri dapat mengikat (dan menggunakan) kartu jaringan tertentu.

Anda tidak dapat membuat aturan untuk melakukannya.

Majenko
sumber
Saya punya aplikasi java, apakah mungkin untuk mengikat aplikasi itu ke antarmuka?
Suresh
Aplikasi Java Anda memiliki kode sumber untuk dan dapat memprogram ulang internal?
Majenko
Saya punya kode sumber aplikasi java yang menggunakan pustaka http apache.
Suresh
Lalu saya akan menuju ke stackoverflow.com dan bertanya kepada programmer di sana bagaimana mengubah program Anda. Saya belum pernah memprogram di Jawa.
Majenko