Unix programını belirli bir ağ arayüzüne bağlayın


39

Soru: Ağ erişiminin belirli bir ağ arayüzü üzerinden bağlanmasını sağlarken bir programı nasıl başlatabilirim?

Durum: Aynı IP'ye sahip (192.168.1.1) iki farklı makineye erişmek, ancak iki farklı ağ arayüzü (eth1 ve eth2) aracılığıyla erişilebilir olmak istiyorum.

Örnek:

net-bind -D eth1 -exec {Program 192.168.1.1}
net-bind -D eth2 -exec {Program 192.168.1.1}

Yukarıdaki, primusrun ve optirun aracılığıyla yapılan donanım bağlamasından esinlenerek ne istediğimin bir yaklaşımıdır .

Zorluk: İlgili bir başlıkta önerildiği gibi , kullanılan arayüzler program tarafından değil, çekirdek tarafından seçilir (dolayısıyla yukarıdaki örnekte ön bağlama sözdizimi).

Tatmin edici olmayan bazı ilgili çözümler buldum. Kullanıcıya özel ağ kara liste yoluyla bağlanan ağ arayüzlerine dayanır; yani, işlemi sadece belirli bir ağ arayüzüne erişebilen bir kullanıcı olarak çalıştırmak.


Makinenizin, her ikisi de 192.168.1.0 olan iki farklı ağa bağlı olduğunu mu ima ediyorsunuz? Yönlendirme tablonuz neye benziyor? Bir işlemden görülebilen arayüzleri sınırlamak istiyorsanız, en hafif çözüm, daha ağır bir konteyner olan cgroups olacaktır.
lgeorget

Evet, her ikisi de aynı IP aralığında iki farklı ağ. Emin değilim, görünen arayüzleri kısıtlamak istemeyeceğim, hangisini varsayılan olarak kullanacağınızı belirleyeceğim. :)
Skeen

3
İstediğiniz şey bir nedenden ötürü zor: aynı IP alanını kullanarak birbirine bağlı iki ağın olması, aynı sayıda iki katlı bir binada asansör olması gibi. IP aralığı, çıktı arayüzünü değil, alanı tanımlayan şeydir. Yine de, hatalı ağ tasarımınızın etrafında iptables ile çalışmanın bir yolu olmalı.
lgeorget

Sistemimi iki farklı yerinde altyapıya bağlıyorum, çünkü bu tür altyapılar hiçbir zaman etkileşime girecek şekilde tasarlanmadı ve bu nedenle ağ tasarımı bu konuda kusurlu.
Skeen

1
NAT'lara olan savım, adres alanlarının tamamının genellikle NAT'ın arkasına gizlenmiş olduğu ve iki NAT'ted altyapısını bağladığımda çarpışma gerçekleştiğiydi. - Altyapıyı değiştirebilecek durumda değilim. - Ağ ad alanlarını sanal ağ arayüz çiftleriyle (ad alanında biri, kök ad alanında biri) fiziksel ad dizinine köprülemeyi ve ağ ad alanı içinde programları çalıştırmayı denedim. - Bu çalışıyor gibi görünüyor, ancak kök ad alanının ötesine erişemiyorum (yani makinenin dışında erişim yok).
Skeen

Yanıtlar:


34

Linux için bu, Superuser'de zaten cevaplandırılmıştır - Farklı işlemler için farklı ağ arayüzleri nasıl kullanılır? .

En popüler cevap, LD_PRELOADprogramın ağ bağlantısını değiştirmek için bir hile kullanır , ancak modern çekirdekler, ipprogram aracılığıyla ortaya çıkarılan 'ağ ad alanları' adı verilen çok daha esnek bir özelliği destekler . Bu cevap bunun nasıl kullanılacağını gösterir. Kendi deneylerime göre, aşağıdakileri yaptım (root olarak)

# Add a new namespace called test_ns
ip netns add test_ns

# Set test to use eth0, after this point eth0 is not usable by programs
# outside the namespace
ip link set eth0 netns test_ns

# Bring up eth0 inside test_ns
ip netns exec test_ns ip link set eth0 up

# Use dhcp to get an ipv4 address for eth0
ip netns exec test_ns dhclient eth0

# Ping google from inside the namespace
ip netns exec test_ns ping www.google.co.uk

Ağ ad alanlarını unshareve nsenterkomutlarıyla bir dereceye kadar yönetmek de mümkündür . Bu, PID'ler, kullanıcılar ve bağlama noktaları için ayrı alanlar da oluşturmanıza olanak sağlar. Daha fazla bilgi için bakınız:


"bu noktadan sonra eth0, ad alanı dışındaki programlar tarafından kullanılamaz" - Yani bunu yaparken diğer tüm sorunların bağlantısını keserim?
Skeen

1
@Skeen, evet, öyleyse, muhtemelen başka hiçbir programın ad alanına kullanmadığı ve ana programınızı normal şekilde kullandığı bir arayüzü zorlarsınız.
Graeme

1
@Graerne; Her iki arayüz de aktif olarak kullanılıyor; Arayüzleri sökmeyi göze alamam.
Skeen

ve varsayılan ağ geçidi ne? wvdialörneğin, hiç ayarlanmış gibi görünmüyor ... yani ad alanında kendisinin tanımlanması gerekiyor
Flash Thunder,

Bunu nasıl geri alacağınızla ilgili talimatları ekler misiniz? Sadece ip netns remove test_nsnormale dönmek için mi? Yoksa özel bir şey yapmak zorunda mısın?
Multihunter

17

Graeme'nin cevabını kabul ediyorum; bu sadece benim sorunumu çözmek için önerisinde yaptığı değişiklikleri açıklamak için bir takip.

Fiziksel arayüzü isim boşluğuna bağlamak yerine, bir ucunu ağ isim alanında ve bir ucunu kökte olmak üzere sanal bir ağ arayüzü çifti oluşturdum. Paketler daha sonra bu sanal ağ üzerinden ad alanından kök ad alanına ve daha sonra fiziksel arayüze yönlendirilir. - Böylece, tüm sıradan veri transferlerimi çalıştırabilirim ve ayrıca sadece belirli bir arayüze erişebilen süreçleri başlatırım.

# Create the eth0 network namespace
ip netns add eth0_ns

# Create the virtual network pair
ip link add v_eth0a type veth peer name v_eth0b

# Move v_eth0a to the eth0_ns namespace, the virtual pair is now split
# between two network namespaces.
ip link set v_eth0a netns eth0_ns

# Configure the ends of the virtual network pairs
ip netns exec eth0_ns ifconfig v_eth0a up {{NAMESPACE_IP}} netmask {{NAMESPACE_NETMASK}}
ifconfig v_eth0b up {{ROOT_NS_IP}} netmask {{ROOT_NS_NETMASK}}

# Setup routing from namespace to root
ip netns exec eth0_ns route add default gw {{ROOT_NS_IP}} dev v_eth0a

# Setup IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -s {{ROUTE_SOURCE}}/24 -o {{NETWORK_INTERFACE}} -j SNAT --to-source {{ROUTE_TARGET}}

Arabirimler eth0 ve eth1 için kurulduktan sonra, kendi ad alanları eth0_ns ve eth1_ns ile, belirtilen arabirim üzerinden programlar;

ip netns exec eth0_ns fish
ip netns exec eth1_ns fish

4
Aferin! Ayrıca bir köprü aygıtı oluşturabilir ve varsayılan ad alanını ve sanal çiftin fiziksel aygıtlardan biriyle köprü oluşturabilirsiniz. Bu olsa da eşdeğer görünüyor.
Graeme

1
Sanal ve fiziksel aygıtı köprülemeyi denedim; Bu çözümü kullanarak dış ağa ulaşamadım.
Skeen

2
Yaptım ama sadece yeni isim alanından. Yaptığım sorunun ağ yöneticisiyle ilgili olduğunu düşünüyorum, ancak çözemedim ya da cevabımı güncellerdim.
Graeme

Aynı sorunu yaşıyorum, ancak bu çözümü kullanamadım. Son adımda {{ROUTE_SOURCE}} ve {{ROUTE_TARGET}} 'a tam olarak ne girmeliyim?
litov

@Graeme, Ubuntu I en az düzenlenmek suretiyle ad yanı sıra genel ad hem de bağlantı geri almak başardı dhclient <bridge>başına burada .
Chris Hunt

3

Çözüm I: Belirli bir kütüphaneyi önceden yükleme

  • App-Route-Jail : arabirim ağ geçidini zorlamak için ld_preload kullanın (harika fikir ancak kök veya işaret yetenekleri gerektirir) kullanımı aşağıdaki notlarda detaylandırılmıştır

  • Proxybound : Proxy'yi belirli bir uygulamaya zorlamak için ld_preload kullanın (bu, arabirim yerine proxy kullanıyor)

  • Zorla Zorla : birçok özelliğe sahip ancak bağlayıcı sızıntılar (güvenilir değil)

  • Bind-Interface-IP : çok basit ve sızıntı bağlantıları (güvenilir değil)

  • Bind-IP : yol çok basit ve sızıntı bağlantıları (güvenilir değil)

Çözüm II: Linux kullanıcı alanı

  • Klasik linux kullanıcı alanı ip ağları : harika bir çözüm ancak root ve arayüz gerektiren tek bir kullanıcı alanında sadece var olabilir

  • Firejail : Firejail, bir uygulamayı belirli bir ağ kullanmaya zorlayabilir, ancak uyumluluk sınırlıdır (örneğin, tun arayüzlerle uyumlu değildir). ateşböceği kök gerektirmezfirejail --dns=8.8.8.8 --noprofile --net=eth0 --ip=192.168.1.1 app-command

  • Ağları olan Firejail : Firejail, bir uygulamayı ayrı olarak oluşturulmuş belirli bir kullanıcı alanını kullanmaya zorlayabilir, bu da root olmadan boşluk isimlendirmemize izin verir.firejail --dns=8.8.8.8 --noprofile --netns=nameOfyourNS app-command

  • Maskeli ve köprülü Firejail: Firejail, bir uygulamayı iptables masquerade ile belirli bir arabirim kullanmaya zorlayabilir , bu harika ve kök gerektirmez ancak bu ip_forward gerektirir ve güvenlik etkisi doğurabilirfirejail --net=br0 firefox

Çözüm III: Linux iptables

Iptables bu amaç için kullanılabilir, ancak bu ip_forward gerektirir ve doğru yapılandırılmamışsa güvenlik etkisi anlamına gelebilir, örnek 1 , örnek 2 , örnek 3 , örnek 4

Çözümler (I, II ve III) notları:

Wireguard

Bir VPN kullanıyorsanız (özellikle kablolu koruma kullanıyorsanız) ve bu çözümü bir kablolu koruma arabirimine ( kullanıcı alanı olan kablolu koruma ) uygulamak istiyorsanız, bir wg arayüzü içeren (ve böylece bir vpn arayüzü ile sınırlı olan) bir kullanıcı alanı oluşturma talimatını verilen bağlantıyı takip edebilirsiniz. ) Ayrıca bu firejail --netns=container, kullanıcı alanını root kullanmadan kullanabilmek için de kullanılabilir.

Arabirim ağ geçidi nasıl bulunur

Burada ağ geçidini bulmak için birçok çözüm var, kullanılan ağ geçidini bulmaya izin veren bazı komutlar

$ 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

App-Route-Jail nasıl kullanılır?

  • App-Route-Jail oluşturun
git clone https://github.com/Intika-Linux-Network/App-Route-Jail.git
cd Approute-Utils
chown 755 make.sh
./make.sh
  • Gelecekteki işaretli paketler için (hapsedilmiş uygulama için) bir rota ekleyin, bu örnekte 192.168.1.1zorunlu ağ geçidi olarak kullanılır, bu rota kuralı diğer uygulamaları etkilemez, bu manipülasyon örneğin bir sistem önyüklemesinde sadece bir kez yapılmalı, örneğin bu çözümü her gün kullanın
ip rule add fwmark 10 table 100
ip route add default via 192.168.1.1 table 100
  • Hapse atmak istediğiniz uygulamayı başlatın
MARK=10 LD_PRELOAD=./mark.so firefox
  • Wan IP adresini test etme
MARK=10 LD_PRELOAD=./mark.so wget -qO- ifconfig.me
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.