ผูกโปรแกรม unix เข้ากับอินเตอร์เฟสเครือข่ายเฉพาะ


39

คำถาม: ฉันจะเปิดโปรแกรมในขณะที่มั่นใจได้ว่าการเข้าถึงเครือข่ายนั้นจะถูกผูกไว้ผ่านอินเตอร์เฟซเครือข่ายเฉพาะ?

กรณี: ฉันต้องการเข้าถึงสองเครื่องที่แตกต่างด้วย IP เดียวกัน (192.168.1.1) แต่สามารถเข้าถึงได้ผ่านเครือข่ายอินเทอร์เฟซที่แตกต่างกันสองตัว (eth1 และ eth2)

ตัวอย่าง:

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

ข้างต้นเป็นประมาณของสิ่งที่ฉันต้องการแรงบันดาลใจจากฮาร์ดแวร์ผูกพันทำผ่านprimusrunและoptirun

ถาม:ตามที่แนะนำในเธรดที่เกี่ยวข้องอินเทอร์เฟซที่ใช้ไม่ได้ถูกเลือกโดยโปรแกรม แต่เป็นการใช้โดยเคอร์เนล

ฉันพบวิธีแก้ไขปัญหาที่เกี่ยวข้องซึ่งไม่น่าพอใจ พวกเขาจะขึ้นอยู่กับการเชื่อมต่อเครือข่ายที่มีผลผูกพันผ่านบัญชีดำเครือข่ายเฉพาะผู้ใช้; นั่นคือการเรียกใช้กระบวนการในฐานะผู้ใช้ที่สามารถเข้าถึงเครือข่ายอินเทอร์เฟซที่เฉพาะเจาะจงเท่านั้น


คุณหมายถึงว่าเครื่องของคุณเชื่อมต่อกับเครือข่ายที่ต่างกันสองเครือข่ายทั้ง 192.168.1.0 หรือไม่? ตารางเส้นทางของคุณมีลักษณะอย่างไร หากคุณต้องการ จำกัด อินเตอร์เฟสที่มองเห็นได้จากกระบวนการโซลูชันที่เบาที่สุดจะเป็น cgroups ซึ่งเป็นคอนเทนเนอร์ที่หนักกว่าหนึ่ง
lgeorget

ใช่สองเครือข่ายที่ต่างกันซึ่งอยู่ในช่วง IP เดียวกัน ฉันไม่แน่ใจว่าจะไม่ จำกัด อินเทอร์เฟซที่สามารถมองเห็นได้แค่บอกว่าจะใช้อันใดเป็นค่าเริ่มต้น :)
Skeen

3
สิ่งที่คุณถามนั้นเป็นเรื่องยากด้วยเหตุผลที่ดีเพียงประการเดียว: การมีเครือข่ายสองเครือข่ายเชื่อมต่อกันโดยใช้โดเมน IP เดียวกันนั้นเหมือนกับลิฟต์ในอาคารที่มีสองชั้นที่มีหมายเลขเดียวกัน ช่วง IP คือสิ่งที่ระบุโดเมนไม่ใช่อินเทอร์เฟซเอาท์พุท อย่างไรก็ตามต้องมีวิธีในการแก้ไขการออกแบบเครือข่ายที่มีข้อบกพร่องด้วย iptables
lgeorget

ฉันกำลังเชื่อมต่อระบบของฉันกับโครงสร้างพื้นฐานแบบสองแบบที่แตกต่างกันเช่นโครงสร้างพื้นฐานไม่เคยถูกออกแบบมาเพื่อโต้ตอบและด้วยเหตุนี้การออกแบบเครือข่ายจึงมีข้อบกพร่อง
Skeen

1
ข้อโต้แย้งของฉันที่มีต่อ NAT คือการเว้นวรรคที่อยู่ทั้งหมดมักจะซ่อนอยู่หลัง NAT และในขณะที่ฉันกำลังเชื่อมต่อโครงสร้างพื้นฐาน NAT'ted สองแห่งการปะทะกันก็เกิดขึ้น - ฉันไม่ได้อยู่ในตำแหน่งที่จะปรับเปลี่ยนโครงสร้างพื้นฐาน - ฉันลองใช้เนมสเปซเครือข่ายที่มีคู่ของอินเทอร์เฟซเครือข่ายเสมือน (หนึ่งในเนมสเปซ, หนึ่งในรูทสเปซรูท) เชื่อมโยงรูทเนมสเปซหนึ่งกับอินเทอร์เฟซกายภาพ - ดูเหมือนว่าจะใช้งานได้ แต่ฉันไม่ได้รับการเข้าถึงเกินรูทเนมสเปซ (เช่นไม่มีการเข้าถึงภายนอกตัวเครื่อง)
Skeen

คำตอบ:


34

สำหรับ Linux แล้วคำตอบนี้มีอยู่แล้วใน Superuser - วิธีใช้อินเตอร์เฟสเครือข่ายที่แตกต่างกันสำหรับกระบวนการที่แตกต่างกันอย่างไร .

คำตอบที่ได้รับความนิยมมากที่สุดใช้LD_PRELOADเคล็ดลับในการเปลี่ยนการเชื่อมโยงเครือข่ายสำหรับโปรแกรม แต่เมล็ดที่ทันสมัยรองรับคุณสมบัติที่ยืดหยุ่นกว่าที่เรียกว่า 'เนมสเปซเครือข่าย' ซึ่งแสดงผ่านipโปรแกรม คำตอบนี้แสดงวิธีใช้สิ่งนี้ จากการทดลองของฉันฉันได้ทำต่อไปนี้ (เป็น root):

# 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

นอกจากนี้ยังเป็นไปได้ที่จะจัดการเนมสเปซเครือข่ายในระดับหนึ่งด้วยคำสั่งunshareและ nsenterสิ่งนี้ช่วยให้คุณสามารถสร้างช่องว่างแยกต่างหากสำหรับ PID ผู้ใช้และจุดเชื่อมต่อ สำหรับข้อมูลเพิ่มเติมโปรดดู:


"หลังจากจุดนี้ eth0 ไม่สามารถใช้งานได้โดยโปรแกรมนอกเนมสเปซ" - ดังนั้นฉันจึงดึงการเชื่อมต่อสำหรับปัญหาอื่น ๆ ทั้งหมดในการทำเช่นนี้?
Skeen

1
@Skeen ใช่แล้วคุณน่าจะกดส่วนต่อประสานที่ไม่มีโปรแกรมอื่นเข้ามาใช้ใน namespace และใช้โปรแกรมหลักของคุณตามปกติ
แกรม

1
@Graerne; อินเทอร์เฟซทั้งสองกำลังถูกใช้อย่างแข็งขัน ฉันไม่สามารถลดอินเทอร์เฟซลงได้
Skeen

และเกตเวย์เริ่มต้นคืออะไร wvdialตัวอย่างเช่นดูเหมือนจะไม่ตั้งค่าเลย ... ดังนั้นจึงต้องมีการกำหนดในเนมสเปซเอง
Flash Thunder

คุณสามารถรวมคำแนะนำเกี่ยวกับวิธีการยกเลิกได้อย่างไร คุณเพิ่งip netns remove test_nsจะกลับสู่ภาวะปกติหรือไม่? หรือคุณต้องทำอะไรเป็นพิเศษ?
Multihunter

17

ฉันยอมรับคำตอบของแกรม นี่เป็นเพียงการติดตามเพื่ออธิบายการเปลี่ยนแปลงที่ฉันทำกับคำแนะนำของเขาเพื่อแก้ไขปัญหาของฉัน

แทนที่จะสร้างการเชื่อมต่ออินเทอร์เฟซแบบฟิสิคัลภายในเนมสเปซฉันสร้างคู่เน็ตเวิร์กอินเตอร์เฟสเสมือนโดยมีปลายด้านหนึ่งในเนมสเปซเครือข่ายและอีกอันในรูท จากนั้นแพ็กเกจจะถูกกำหนดเส้นทางผ่านเครือข่ายเสมือนนี้จากเนมสเปซไปยังรูทเนมสเปซแล้วไปยังอินเทอร์เฟซทางกายภาพ - ด้วยเหตุนี้ฉันจึงสามารถเรียกใช้การถ่ายโอนข้อมูลทั่วไปทั้งหมดของฉันและนอกจากนี้กระบวนการเริ่มต้นซึ่งสามารถเข้าถึงอินเทอร์เฟซเฉพาะเท่านั้น

# 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}}

เมื่ออินเตอร์เฟสได้รับการตั้งค่าสำหรับ eth0 และ eth1 ด้วยเนมสเปซตามลำดับของพวกเขา eth0_ns และ eth1_ns โปรแกรมสามารถทำงานได้บนอินเตอร์เฟสที่ระบุผ่าน;

ip netns exec eth0_ns fish
ip netns exec eth1_ns fish

4
ทำได้ดี! ฉันคิดว่าคุณสามารถสร้างอุปกรณ์บริดจ์และเชื่อมต่อเนมสเปซเริ่มต้นและของคู่เสมือนกับอุปกรณ์ทางกายภาพได้ นี้ดูเหมือนว่าเทียบเท่า
แกรม

1
ฉันลองเชื่อมอุปกรณ์เสมือนและฟิสิคัลแล้ว; ฉันไม่สามารถเข้าถึงเครือข่ายภายนอกโดยใช้โซลูชันนั้น
Skeen

2
ฉันทำ แต่จากเนมสเปซใหม่เท่านั้น ฉันคิดว่าปัญหาที่ฉันเกี่ยวข้องกับตัวจัดการเครือข่ายฉันไม่ได้คิดออกว่าจะปรับปรุงคำตอบของฉันหรือไม่
แกรม

ฉันมีปัญหาเดียวกัน แต่ฉันล้มเหลวในการใช้วิธีแก้ไขปัญหานั้น ฉันควรป้อนอะไรใน {{ROUTE_SOURCE}} และ {{ROUTE_TARGET}} ในขั้นตอนสุดท้าย
litov

@Graeme อย่างน้อยบน Ubuntu ผมสามารถที่จะได้รับกลับมาเชื่อมต่อทั้งใน namespace เช่นเดียวกับ namespace โลกโดยการออกdhclient <bridge>ต่อที่นี่
Chris Hunt

3

โซลูชันที่ 1: การโหลดไลบรารีเฉพาะล่วงหน้า

  • แอพ -Rail -Jail : ใช้ ld_preload เพื่อบังคับให้อินเตอร์เฟสเกตเวย์ (ความคิดที่ยอดเยี่ยม แต่ต้องใช้ความสามารถในการรูทหรือการทำเครื่องหมาย) มีรายละเอียดเกี่ยวกับโน้ตย่อ

  • Proxyboundใช้งาน: ใช้ LD_PRELOAD เพื่อบังคับให้ผู้รับมอบฉันทะเพื่อการประยุกต์ใช้ที่เฉพาะเจาะจง (นี้เป็นใช้ proxy แทนของอินเตอร์เฟซ)

  • Force-Bind : มีคุณสมบัติมากมาย แต่การเชื่อมโยงรั่วไหล (ไม่น่าเชื่อถือ)

  • Bind-Interface-IP : การเชื่อมต่อที่ง่ายและรั่วไหลเกินไป (ไม่น่าเชื่อถือ)

  • Bind-IP : วิธีที่ง่ายเกินไปและการเชื่อมต่อการรั่วไหล (ไม่น่าเชื่อถือ)

โซลูชันที่สอง: ผู้ใช้ Linux

  • พื้นที่ผู้ใช้ linux แบบคลาสสิกip-netns : โซลูชันที่ยอดเยี่ยม แต่ต้องการรูทและส่วนต่อประสานสามารถอยู่ได้ในพื้นที่ผู้ใช้เดียวเท่านั้น

  • Firejail : Firejail สามารถบังคับให้แอปพลิเคชันใช้เครือข่ายเฉพาะ แต่ความเข้ากันได้นั้นมี จำกัด (ตัวอย่างเช่นไม่สามารถใช้งานได้กับอินเตอร์เฟสอินเตอร์เฟส) firejail ไม่ต้องการรูทfirejail --dns=8.8.8.8 --noprofile --net=eth0 --ip=192.168.1.1 app-command

  • Firejail with netns : Firejail สามารถบังคับให้แอปพลิเคชันใช้พื้นที่ผู้ใช้เฉพาะที่สร้างขึ้นแยกจากกันทำให้เราตั้งชื่อช่องว่างโดยไม่ต้องรูทfirejail --dns=8.8.8.8 --noprofile --netns=nameOfyourNS app-command

  • Firejail พร้อมมาสเคอเรดและบริดจ์ : Firejail สามารถบังคับให้แอปพลิเคชันใช้อินเทอร์เฟซเฉพาะกับ iptables masqueradeได้ดีและไม่ต้องใช้ root แต่ต้องใช้ ip_forward และอาจบ่งบอกถึงความปลอดภัยfirejail --net=br0 firefox

โซลูชันที่สาม: iptables Linux

iptables สามารถนำมาใช้เพื่อการนี้แต่นี้ต้อง ip_forward และสามารถบ่งบอกถึงผลกระทบต่อการรักษาความปลอดภัยหากไม่ได้กำหนดค่าอย่างถูกต้องตัวอย่างเช่น 1 , 2 ตัวอย่าง , ตัวอย่างเช่น 3 , ตัวอย่าง 4

การแก้ปัญหา (I, II & III) บันทึก:

Wireguard

หากคุณใช้ VPN (โดยเฉพาะ wireguard) และคุณต้องการใช้โซลูชันนี้กับอินเตอร์เฟส wireguard ( wireguard พร้อมพื้นที่ผู้ใช้ ) คุณสามารถทำตามคำแนะนำที่เชื่อมโยงเพื่อสร้างพื้นที่ผู้ใช้ที่มีส่วนต่อประสาน wg (และ จำกัด อยู่ที่อินเตอร์เฟส vpn ) นอกจากนี้ยังสามารถรวมกับfirejail --netns=containerเพื่อให้สามารถใช้พื้นที่ผู้ใช้โดยไม่ต้องรูท

วิธีค้นหาอินเตอร์เฟสเกตเวย์

มีวิธีแก้ปัญหามากมายในการค้นหาเกตเวย์ที่นี่คือคำสั่งบางอย่างที่อนุญาตให้ค้นหาเกตเวย์ที่ใช้

$ 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

  • สร้าง App-Route-Jail
git clone https://github.com/Intika-Linux-Network/App-Route-Jail.git
cd Approute-Utils
chown 755 make.sh
./make.sh
  • เพิ่มเส้นทางสำหรับแพ็คเก็ตที่ถูกทำเครื่องหมายในอนาคต (สำหรับแอปพลิเคชันที่ถูกจำคุก) ในตัวอย่าง192.168.1.1นี้ใช้เป็นเกตเวย์บังคับ, กฎเส้นทางนี้จะไม่ส่งผลกระทบต่อแอปพลิเคชันอื่น ๆ การจัดการนี้จะต้องทำเพียงครั้งเดียว ใช้วิธีนี้ทุกวัน
ip rule add fwmark 10 table 100
ip route add default via 192.168.1.1 table 100
  • เริ่มแอปพลิเคชันที่คุณต้องการติดคุก
MARK=10 LD_PRELOAD=./mark.so firefox
  • ทดสอบที่อยู่ IP wan
MARK=10 LD_PRELOAD=./mark.so wget -qO- ifconfig.me
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.