กำหนดเส้นทางทราฟฟิกผ่านอินเตอร์เฟสเฉพาะสำหรับกระบวนการใน linux


19

เป็นไปได้หรือไม่ที่จะกำหนดเส้นทางการรับส่งข้อมูลที่ใช้โดยกระบวนการผ่านส่วนต่อประสานที่เฉพาะเจาะจง?

ตัวอย่างเช่นปริมาณการใช้เครือข่ายโดยแอปพลิเคชันดาวน์โหลดควรใช้อินเทอร์เฟซเสมอ wlan0 ในขณะที่แอปพลิเคชันอื่น ๆ ทั้งหมดบนเครื่องควรใช้ eth0.

เป็นไปได้ไหมที่จะมีกฎประเภทนี้ใน Linux?

คำตอบ:


20

สามารถทำได้โดยใช้ Linux Network Namespaces

นี่คือบทความ ที่อธิบายได้อย่างไร โดยทั่วไปคุณสร้างเนมสเปซเครือข่ายที่มีเส้นทางเริ่มต้นที่แตกต่างกันและเรียกใช้กระบวนการที่จำเป็นต้องมี คุณเชื่อมต่อเนมสเปซเครือข่ายที่สร้างขึ้นใหม่กับฟิสิคัลอะแด็ปเตอร์ด้วยบริดจ์ (แต่อาจมีโซลูชันอื่น ๆ ที่แน่นอน)

อัปเดต: จากเคอร์เนล 3.14 การใช้กลุ่มควบคุมทำได้ง่ายยิ่งขึ้นดังอธิบายใน บทความนี้ . คุณต้อง:

1) กำหนดกลุ่มควบคุม net_cls เพื่อใส่หมายเหตุประกอบแพ็กเก็ตจากกระบวนการที่กำหนดด้วย classid (หรือกลุ่มของกระบวนการโปรดทราบว่าไม่มีความสัมพันธ์ระหว่างผู้ปกครองกับลูก

2) ใช้โมดูล iptables cgroup (เพิ่มใน Linux 3.14) เพื่อ fwmark แพ็กเก็ต

3) ใช้การกำหนดเส้นทางนโยบาย (กฎ ip เพิ่ม fwmark .... ) เพื่อสร้างตารางเส้นทางใหม่สำหรับแพ็คเก็ตที่ทำเครื่องหมายไว้

ข้อได้เปรียบคือเราไม่ต้องทำสิ่งเชื่อมโยงและทุกสิ่งทุกอย่างมีพลังมากขึ้นขอบคุณกลุ่ม cg


12

ฉันพยายามอย่างหนักกับเรื่องนี้ดังนั้นนี่คือทางออกที่สมบูรณ์ ผ่านการทดสอบบน Ubuntu 15 & amp; 16. คุณสามารถใช้กับ OpenVPN โดยเฉพาะเพื่อกำหนดเส้นทางแอปบางอย่างนอกช่องสัญญาณ VPN

โซลูชัน "cgroup" ที่สมบูรณ์

มันทำงานอย่างไร

  • เคอร์เนล Linux จะนำแอปไปไว้ใน กลุ่มควบคุม . การรับส่งข้อมูลเครือข่ายจากแอปในกลุ่มนี้จะถูกระบุด้วยรหัสระดับของพวกเขาที่ระดับตัวควบคุมเครือข่าย
  • iptables จะทำเครื่องหมายการรับส่งข้อมูลนี้และบังคับให้ออกด้วย IP ที่ถูกต้อง
  • เส้นทาง ip จะประมวลผลปริมาณข้อมูลที่ทำเครื่องหมายไว้ในตารางเส้นทางที่แตกต่างกันโดยมีเส้นทางเริ่มต้นไปยังเกตเวย์ IP ที่คุณต้องการ

สคริปต์อัตโนมัติ

ฉันทำ novpn.sh สคริปต์เพื่อติดตั้งการอ้างอิงอัตโนมัติ & amp; วิ่ง. ทดสอบบน Ubuntu

เริ่ม VPN ของคุณก่อน

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

คู่มือ HowTo

ก่อนอื่นให้ติดตั้งการสนับสนุนและเครื่องมือ cgroup:

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

รีบูท (อาจไม่จำเป็น)

คุณต้องการ iptables 1.6 .0+ รับแหล่งปล่อย iptables 1.6.0 แยกมันออกมาแล้วเรียกใช้สิ่งนี้ ( --disable-nftables ธงจะหลีกเลี่ยงข้อผิดพลาด) จากแหล่ง iptables dir:

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

ตอนนี้การตั้งค่าจริง กำหนดกลุ่มควบคุมที่ชื่อ novpn. กระบวนการใน cgroup นี้จะมี 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

ตอนนี้เราจะสมมติว่าอินเทอร์เฟซที่คุณต้องการใช้สำหรับแอพเฉพาะคือ eth0 ด้วย IP เกตเวย์ของ 10.0.0.1. แทนที่ สิ่งเหล่านี้ตามสิ่งที่คุณต้องการ (รับข้อมูลจาก ip route ) ทำงานเหมือนราก:

# 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

สุดท้ายให้รันแอปของคุณบนอินเทอร์เฟซเฉพาะ:

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

หรือถ้าคุณต้องการย้ายกระบวนการที่กำลังทำงานอยู่ไปยัง cgroup ก็ดี ... คุณทำไม่ได้! ดูเหมือนว่าจะเกิดจากฟังก์ชัน NAT (masquerade): iptables -nvL -t nat ไม่ตรงกับเมื่อเปลี่ยนกลุ่ม cgroup แต่ 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

เครดิต: ไม่มีคำตอบทำงานตามที่คาดไว้ แต่การผสมผสานของพวกเขาได้ทำ: คำตอบของ chripell บทความวิวัฒนาการ การกำหนดเส้นทางตามกระบวนการใช้เวลา 2: ใช้ cgroups, iptables และการกำหนดเส้นทางนโยบาย , ฉันจะทำให้กระบวนการเฉพาะไม่ผ่านการเชื่อมต่อ OpenVPN ได้อย่างไร , Kill switch สำหรับ OpenVPN บนพื้นฐานของ iptables


ขอบคุณสำหรับคำตอบที่ดีฉันจะทำให้ apache ทำงานได้อย่างไร ฉันเหนื่อย cgexec -g net_cls:novpn apache2 และให้ฉันรายการทั้งหมดของข้อผิดพลาดตัวแปรไม่ได้กำหนด!
razzak

2
คุณจะได้รับข้อผิดพลาดเดียวกันโดยการทำงาน apache2 โดยตรงจากสถานี นั่นเป็นเพราะ apache2 โดยปกติจะเปิดตัวเป็นบริการด้วย systemctl start apache2. อย่างไรก็ตามนั่นไม่สามารถใช้งานได้ cgexec. โปรแกรมที่ถูกเรียกจะต้องเป็น parent ของโปรแกรมที่ต้องการ ( apache2 ) กระบวนการสำหรับ net_cls cgroup เพื่อเผยแพร่ ดังนั้นคุณต้องค้นหาสคริปต์การเปิดตัว ในกรณีนี้มันเป็น sudo cgexec -g net_cls:novpn /usr/sbin/apache2ctl start. ตรวจสอบกับ ./novpn.sh --list.
KrisWebDev

ไม่ทำงานใน Ubuntu 16.04 อีกต่อไป!
razzak

2
ฉันใช้งานบน Ubuntu 16.04 และใช้งานได้ดี มีการเปลี่ยนแปลงชื่อส่วนต่อประสานใน Ubuntu 16 คุณอาจต้องเปลี่ยนแทน eth0 โดยชอบ enp7s0. รับข้อมูลจาก ifconfig คำสั่ง
KrisWebDev

3

การรวมคำตอบที่ยอดเยี่ยมของ mariusmatutiae และ KrisWebDev ฉันได้สร้างเวอร์ชั่นที่ดัดแปลงอย่างครอบคลุมของ KrisWebDev ที่ยอดเยี่ยม novpn.sh ต้นฉบับ ในขณะที่สคริปต์ของ KrisWebDev ได้รับการออกแบบมาเพื่อเกาเฉพาะเจาะจงมากขึ้น (ทำงานและเคลื่อนย้ายกระบวนการภายใน / ภายนอก VPN) รุ่นของฉันช่วยให้คุณสามารถเรียกใช้คำสั่งใด ๆ ในสภาพแวดล้อมเครือข่ายที่คุณระบุ คุณสามารถระบุอินเทอร์เฟซที่จะผูกกับเส้นทางเริ่มต้นระบุกฎ iptables ของคุณเส้นทางคงที่ระบุ "ทดสอบ" เพื่อยืนยันว่าทุกอย่างทำงานตามที่คุณต้องการก่อนที่จะเรียกใช้คำสั่ง ... ฯลฯ ) อนุญาตให้คุณใช้ไฟล์กำหนดค่าหลายไฟล์เพื่อให้คุณสามารถกำหนดจำนวนของสภาพแวดล้อมเครือข่ายเฉพาะใด ๆ ที่คุณสามารถเรียกใช้คำสั่ง / กระบวนการภายใน

ฉันโพสต์มันเป็นส่วนสำคัญที่นี่: https://gist.github.com/level323/54a921216f0baaa163127d960bfebbf0

มันยังสามารถล้างตาราง cgroup / iptables / routing ได้อีกด้วย!

ข้อเสนอแนะยินดีต้อนรับ

PS - มันออกแบบมาสำหรับ Debian 8 (Jessie)


สวัสดี @ allnatural ฉันต้องการใช้สคริปต์ altnetworking.sh ของคุณ แต่ฉันควรใส่อะไรลงในไฟล์กำหนดค่า
Cris70


0

ไม่ใช่ต่อแอปพลิเคชันหมายเลข คุณสามารถทำต่อพอร์ตหรือต่อที่อยู่ IP ฯลฯ หรือแอปพลิเคชันสามารถผูกกับ (และใช้) การ์ดเครือข่ายเฉพาะ

คุณไม่สามารถตั้งค่ากฎที่จะทำ


ฉันเป็นแอปพลิเคชัน java เป็นไปได้หรือไม่ที่จะผูกแอพนั้นเข้ากับอินเตอร์เฟส?
Suresh

แอปพลิเคชัน Java คุณมีซอร์สโค้ดสำหรับและสามารถตั้งโปรแกรม internals ใหม่ได้หรือไม่
Majenko

ฉันเป็นซอร์สโค้ดแอปพลิเคชัน java ที่ใช้ apache http ไลบรารี่
Suresh

จากนั้นฉันก็ตรงไปที่ stackoverflow.com และถามโปรแกรมเมอร์ว่าจะเปลี่ยนโปรแกรมของคุณอย่างไร ฉันไม่เคยตั้งโปรแกรมใน Java
Majenko
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.