กำหนดเส้นทางทราฟฟิกผ่านอินเตอร์เฟสเฉพาะสำหรับกระบวนการใน 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.