Linux'ta bir işlem için trafiği belirli bir arayüz üzerinden yönlendirin


20

Bir işlem tarafından kullanılan trafiği belirli bir arabirim üzerinden yönlendirmek mümkün müdür?

Örneğin, indirme uygulamasına göre ağ trafiği her zaman arayüzü kullanmalıdır, wlan0oysa makinedeki diğer tüm uygulamalar kullanmalıdır eth0.

Linux'ta bu tür bir kurala sahip olmak mümkün müdür?

Yanıtlar:


22

Linux Ağ Ad Alanları kullanılarak yapılabilir.

İşte nasıl olduğunu açıklayan bir makale . Temel olarak, farklı bir varsayılan rotayla bir ağ ad alanı oluşturur ve buna ihtiyaç duyan işlemleri çalıştırırsınız. Yeni oluşturulan ağ ad alanını bir köprüyle fiziksel bağdaştırıcıya bağlarsınız (ancak elbette başka çözümler de mümkündür).

Güncelleme: çekirdek 3.14'ten bu makalede açıklandığı gibi kontrol gruplarını kullanmak daha da kolay . Yapman gerek:

1) verilen bir süreçten paketlere bir sınıf kimliği (veya işlem grubu ile açıklama eklemek için bir net_cls kontrol grubu tanımlayın, aralarında ebeveyn-çocuk ilişkisi olmaması gerektiğini unutmayın)

2) paketleri işaretlemek için iptables cgroup modülünü kullanın (Linux 3.14'e eklendi)

3) işaretli paketler için yeni bir yönlendirme tablosu oluşturmak için ilke yönlendirmesini (ip kuralı ekleme fwmark ....) kullanın

Avantajı, köprüleme işini yapmak zorunda değiliz ve gruplar sayesinde her şey çok daha dinamik.


14

Ben sooo ile mücadele ettik bu yüzden İşte bir TAMAM çözüm. Ubuntu 15 ve 16'da test edilmiştir. Özellikle VPN tünel arayüzü dışındaki belirli uygulamaları yönlendirmek için OpenVPN ile kullanabilirsiniz.

Eksiksiz "grup" çözümü

Bu nasıl çalışır?

  • Linux çekirdeği uygulamayı bir kontrol grubuna koyacaktır . Bu gruptaki uygulamalardan gelen ağ trafiği, ağ denetleyicisi düzeyindeki sınıf kimlikleriyle tanımlanır.
  • iptables bu trafiği işaretler ve doğru IP ile çıkmaya zorlar
  • ip yolu, işaretli trafiği farklı bir yönlendirme tablosunda, istediğiniz ağ geçidi IP'sine varsayılan bir yolla işler.

Otomatik komut dosyası

Yükleme ve çalıştırma bağımlılıklarını otomatikleştirmek için bir novpn.sh betiği yaptım . Ubuntu üzerinde test edildi.

Önce VPN'nizi başlatın.

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

Manuel Nasıl Yapılır

İlk olarak, grup desteği ve araçlarını yükleyin:

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

Yeniden başlat (gerekli olmayabilir).

Iptables 1.6 .0+ gerekir . İptables 1.6.0 yayın kaynağını alın , ayıklayın, ardından --disable-nftablesiptables kaynak dizininden bu ( bayrak hataları önleyecektir) çalıştırın :

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

Şimdi, gerçek yapılandırma. Adlı bir kontrol grubu tanımlayın novpn. Bu gruptaki işlemlerin sınıfı 0x00110011(11:11) olacaktır.

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

Şimdi, belirli bir uygulama için kullanmak istediğiniz arayüzün eth0bir ağ geçidi IP'si olduğunu varsayalım 10.0.0.1. Bunları gerçekten istediğiniz şeyle değiştirin (bilgileri alın ip route). Hala root olarak çalıştır:

# 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

Son olarak, uygulamanızı belirli bir arayüzde çalıştırın:

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

Veya zaten çalışan bir işlemi gruba taşımak istiyorsanız, yapamazsınız! Bu NAT (maskeli balo) işlevinden kaynaklanıyor gibi görünüyor: iptables -nvL -t natgrup değiştirildiğinde eşleşmiyor, ancak eşleşiyor iptables -nvL -t mangle.

# 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

Kredi: Hiçbir yanıt beklendiği gibi çalışmıyordu, ancak bunların bir karışımı yaptı: chripell cevap evolware makalesi İşlem yönlendirmesi başına 2 alır: cgroups, iptables ve politika yönlendirmesini kullanma , Belirli bir işlemi nasıl OpenVPN bağlantısı üzerinden yapmam? , İptables temelinde OpenVPN için Kill switch


Mükemmel cevap için teşekkürler, nasıl apache ile çalışmasını sağlayabilirim? Denedim cgexec -g net_cls:novpn apache2ve değişken tanımsız hataların tüm listesini verdi!
razzak

2
Aynı hataları apache2doğrudan terminalden çalıştırarak alırsınız . Çünkü apache2normalde bir hizmet olarak başlatılır systemctl start apache2. Ancak, bu işe yaramaz cgexec. apache2Net_cls grubunun yayılması için çağrılan programın istenen ( ) sürecinin bir üst öğesi olması gerekir. Bu yüzden başlatma komut dosyasını bulmanız gerekir. Bu durumda, öyle sudo cgexec -g net_cls:novpn /usr/sbin/apache2ctl start. İle kontrol edin ./novpn.sh --list.
KrisWebDev

Artık Ubuntu 16.04'te çalışmıyor!
razzak

2
Ubuntu 16.04 üzerinde kullanıyorum ve iyi çalışıyor. Ubuntu 16'da arayüz adları değişti, yerine eth0başka bir şeyle değiştirmeniz gerekebilir enp7s0. Bilgileri ifconfigkomuttan alın .
KrisWebDev

Teşekkür ederim. Ancak cdmanager systemd ile bir çatışma nedeniyle kaldırıldığı için Ubuntu 18.04 üzerinde çalışmıyor
skonsoft


3

Mariusmatutiae ve KrisWebDev'in mükemmel cevaplarını birleştirerek KrisWebDev'in mükemmel novpn.shsenaryosunu kapsamlı bir şekilde değiştirdim . KrisWebDev'in komut dosyası daha spesifik bir kaşıntıyı (VPN içinde / dışında işlemleri yürütme ve taşıma) çizmek için tasarlanmış olsa da, sürümüm belirttiğiniz bir ağ ortamında herhangi bir komutu çalıştırmanıza izin veriyor. Bağlanacak arabirimi, varsayılan yolu belirleyebilir, kendi iptables kurallarınızı, statik rotalarınızı belirleyebilir, komutu çalıştırmadan önce her şeyin istediğiniz gibi çalıştığını doğrulamak için bir "test" belirtebilirsiniz ... vb.). İçinde komutları / işlemleri çalıştırabileceğiniz belirli sayıda ağ ortamını tanımlayabilmeniz için birden çok yapılandırma dosyası kullanmanıza olanak tanır.

Buraya bir özet olarak gönderdim: https://gist.github.com/level323/54a921216f0baaa163127d960bfebbf0

Hatta daha sonra cgroup / iptables / yönlendirme tablolarını temizleyebilir!

Geribildirim hoş geldiniz.

PS - Debian 8 için tasarlandı (Jessie)


Merhaba @allnatural, altnetworking.sh komut dosyanızı kullanmak istiyorum, ancak yapılandırma dosyasına ne koymalıyım?
17'de Cris70

0

Uygulama başına değil, hayır. Bağlantı noktası başına veya ip adresi vb. Başına yapabilir veya bir uygulamanın kendisi belirli bir ağ kartına bağlanabilir (ve kullanabilir).

Yine de bunu yapmak için bir kural ayarlayamazsınız.


Java uygulamam var, bu uygulamayı bir arayüze bağlamak mümkün mü?
Suresh

Kaynak koduna sahip olduğunuz ve dahili olanları yeniden programlayabileceğiniz bir Java uygulaması mı?
Majenko

Apache http kütüphanesini kullanan bir java uygulaması kaynak kodum var.
Suresh

Sonra stackoverflow.com'a gidip orada programcılara programınızı nasıl değiştireceğinizi soracağım. Hiç Java programlamamıştım.
Majenko
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.