คุณไม่สามารถยกเว้นโปรแกรมออกจากโฮสต์ WireGuard ที่มีอุโมงค์เต็มได้ด้วยการแก้ไขเส้นทาง เส้นทางเลือกเส้นทางตามปลายทาง และสิ่งที่คุณต้องการยกเว้นคือโปรเซส เคอร์เนลจึงไม่มีอะไรให้เปรียบเทียบ วิธีที่ใช้ได้คือให้บริบทเครือข่ายของตัวเองแก่โปรเซสนั้น คือเนมสเปซที่มีอินเทอร์เฟซ ที่อยู่ และเส้นทางเริ่มต้นของตัวเอง เชื่อมต่อกับโฮสต์ด้วยคู่ veth ผมรันบน Ubuntu 24.04 กับ wireguard-tools 1.0.20210914 และเนมสเปซไม่เคยเป็นปัญหา ปัญหาคือนโยบายการส่งต่อของโฮสต์กับกฎการทำเครื่องหมายของอุโมงค์

ก่อนอื่นเลือกชนิดของบริบทที่คุณต้องการ

ในทางปฏิบัติมีสองรูปแบบ ถ้าโฮสต์รันอุโมงค์เต็มและมีโปรแกรมหนึ่งต้องออกทางเส้นทาง ISP คุณจะสร้างเนมสเปซที่สอง เชื่อมต่อกับโฮสต์ และให้โฮสต์ส่งต่อและแปลทราฟฟิกให้ ถ้าเนมสเปซมีอินเทอร์เฟซ VPN อยู่แล้วและคุณต้องการเพียงคำสั่งที่เริ่มภายในนั้น นั่นคือกรณีip netns execทั่วไป และงานด้านเส้นทางส่วนใหญ่เสร็จแล้ว

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

ถ้าข้อกำหนดคือไม่มีอะไรออกจากอุโมงค์จริง ๆ ให้หยุดอุโมงค์แทน เนมสเปซมีไว้สำหรับกรณีผสม คือโปรแกรมหนึ่งออกนอก ที่เหลือทั้งหมดเข้าใน บนเครื่องเดียวกันในเวลาเดียวกัน

สร้างบริบทที่สองและเชื่อมต่อกับโฮสต์

ตัวอย่างการจัดวาง โฮสต์มีอินเทอร์เฟซ WireGuard ที่ถือเส้นทางเริ่มต้น และมีเนมสเปซเครือข่ายชื่อclearnetเชื่อมต่อกับโฮสต์ด้วยคู่ veth ที่อยู่ด้านล่างเป็นเพียงตัวอย่าง

ip netns add clearnet
ip link add veth-clear-out type veth peer name veth-clear-in
ip addr add 192.168.100.1/24 dev veth-clear-out
ip link set veth-clear-out up
ip link set veth-clear-in netns clearnet
ip netns exec clearnet ip addr add 192.168.100.2/24 dev veth-clear-in
ip netns exec clearnet ip link set veth-clear-in up
ip netns exec clearnet ip route add default via 192.168.100.1

ตอนนี้เนมสเปซนั้นเข้าถึงโฮสต์ได้และไม่ถึงอย่างอื่น โฮสต์ต้องส่งต่อทราฟฟิกและเขียนที่อยู่ต้นทางใหม่ เพราะ 192.168.100.0/24 เป็นส่วนตัวและเราเตอร์ด้านบนไม่มีเส้นทางกลับเข้าไป:

sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o <wan-interface> -j MASQUERADE

ยืนยันฝั่งเนมสเปซก่อนไปต่อip netns exec clearnet ip routeควรแสดงเส้นทาง veth และเส้นทางเริ่มต้นผ่าน 192.168.100.1 และ ping ไปยังที่อยู่นั้นควรตอบกลับ ถ้า ping ไปยังที่อยู่ของโฮสต์ล้มเหลว แสดงว่าที่อยู่หรือสถานะลิงก์ผิด และไม่มีกฎไฟร์วอลล์ใดช่วยได้

เมื่อชื่อถูกแก้ได้แต่ไม่มีอะไรกลับมา ให้อ่าน FORWARD

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

อ่านเชนก่อนเพิ่มอะไรลงไป:

iptables -S FORWARD
nft list chain inet filter forward

จากนั้นปล่อยทราฟฟิกทั้งสองทิศทาง พร้อมตัวนับ เพื่อให้รู้ว่ากฎเคยตรงกันหรือไม่:

iptables -A FORWARD -i veth-clear-out -o <wan-interface> -j ACCEPT
iptables -A FORWARD -i <wan-interface> -o veth-clear-out -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
watch -n1 'iptables -L FORWARD -v -n'

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

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

เก็บกฎการทำเครื่องหมายของอุโมงค์ให้ห่างจากเส้นทางใหม่

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

สองส่วนเพิ่มเติมแยกเส้นทางออกจากกัน กลับไปแต่เนิ่น ๆ ในเชน mangle สำหรับซับเน็ตของเนมสเปซ และเพิ่มกฎตามต้นทางที่วางซับเน็ตนั้นในตารางหลัก:

iptables -t mangle -I PREROUTING -s 192.168.100.0/24 -j RETURN
ip rule add from 192.168.100.0/24 lookup main priority 100

ลำดับความสำคัญ 100 เรียงก่อนกฎของอุโมงค์บนโฮสต์ของผม ตารางปกติจึงตัดสินให้กับต้นทางนั้น อย่าลอกตัวเลขตาม ๆ กัน: ลำดับความสำคัญที่wg-quickติดตั้งนั้นต่างกันระหว่างเวอร์ชันและระหว่างการตั้งค่า IPv4 กับ IPv6 ดังนั้นให้รันip rule showแล้วเลือกลำดับความสำคัญที่ตกก่อนกฎของอุโมงค์บนเครื่องของคุณ

ตรวจสอบด้วยการค้นหาเฉพาะต้นทางแทนที่จะเชื่อรายการกฎ:

ip route get 1.1.1.1 from 192.168.100.2
ip netns exec clearnet ip route get 1.1.1.1

ถ้าคำสั่งแรกแสดงอินเทอร์เฟซ WireGuard แสดงว่ากฎใหม่ยังไม่นำหน้านโยบายของอุโมงค์ ถ้าแสดงอินเทอร์เฟซ WAN ขณะที่คำสั่งที่สองยังแสดงเส้นทางเริ่มต้น veth แสดงว่าโฮสต์กับเนมสเปซไม่ตรงกัน และคุณควรอ่านตารางเส้นทางทั้งสองใหม่

เริ่มโปรเซสที่เปิดการเชื่อมต่อ

การเริ่มคำสั่งเป็นเพียงบรรทัดเดียว แต่ให้เริ่มโปรเซสที่สร้างซ็อกเก็ตจริง ๆip netns exec clearnet curl -s https://ifconfig.meเป็นการทดสอบที่ซื่อตรงที่สุด: มันแสดงที่อยู่ที่เนมสเปซนำเสนอต่อโลก ไม่ใช่ที่อยู่ที่โฮสต์จะใช้

สำหรับบริการ ให้ผูกเนมสเปซตามพาธเพื่อให้โปรเซสอยู่ในนั้นตลอดชีวิต:

[Service]
NetworkNamespacePath=/run/netns/clearnet

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

readlink /proc/$(pgrep -f clearnet-profile | head -1)/ns/net
readlink /run/netns/clearnet

ผลลัพธ์ทั้งสองต้องตรงกัน การตรวจเดียวกันใช้ได้กับโปรแกรมที่ทำงานยาวนานทุกตัว และควรทำสักครั้งต่อแอปพลิเคชันแทนที่จะถือว่าตัวเรียกทำในสิ่งที่คุณตั้งใจ

การแก้ชื่อต้องมีการตัดสินใจของตัวเอง การสร้างเนมสเปซไม่ได้ให้การตั้งค่าตัวแก้ชื่อแก่เนมสเปซ ไฟล์ต่อเนมสเปซได้รับการสนับสนุนผ่าน/etc/netns/<name>/resolv.confและถ้าไม่มี คุณจะได้พฤติกรรมที่อ่านผิดได้ง่าย IPv6 ต้องได้รับการดูแลแบบเดียวกัน: ถ้าเนมสเปซไม่มีเส้นทางเริ่มต้น v6 ขณะที่แอปพลิเคชันชอบ v6 คำขออาจค้างก่อนถอยกลับ ซึ่งดูเหมือนอุโมงค์เสีย

ตรวจสอบกรอบ ไม่ใช่แค่ที่อยู่ขาออก

ที่อยู่สาธารณะที่ทำงานได้พิสูจน์เส้นทาง ไม่ใช่ข้อกำหนดทั้งหมด เดินส่วนที่เหลือตามลำดับนี้:

  • ip netns exec clearnet ip route get 1.1.1.1แสดงเส้นทางเริ่มต้น veth ไม่ใช่อินเทอร์เฟซ WireGuard
  • ตัวนับ FORWARD ของกฎทั้งสองเพิ่มขึ้นขณะคำขอทำงาน
  • โปรเซสของแอปพลิเคชันรายงาน inode ของเนมสเปซที่คุณคาดไว้
  • หลังรีบูต เนมสเปซมีอยู่ก่อนบริการเริ่ม unit ที่ทำงานก่อนจะล้มเหลว หรือแย่กว่านั้นคือทำงานนอกเนมสเปซ

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

บทความที่เกี่ยวข้อง