ทำไม nftables จึงไม่เห็นทราฟฟิกระหว่างไคลเอนต์ของ OpenVPN
ทราฟฟิกระหว่างเพียร์ถูกส่งภายในโปรเซส VPN ดังนั้นตัวนับการส่งต่อจึงไม่ขยับเลย การจะนับมันได้ต้องเลือกระหว่างเส้นทางเคอร์เนลกับเส้นทางโปรเซส
ไคลเอนต์สองตัวบนเซิร์ฟเวอร์เดียวแลกเปลี่ยนไฟล์ การถ่ายโอนสำเร็จ และทุกกฎการส่งต่อที่ชี้ไปยังอุโมงค์รายงานว่าไม่มีแพ็กเก็ตเลย กฎไม่ได้เสียและเชนก็ไม่ได้วางผิดที่ เมื่อเปิดการส่งต่อระหว่างเพียร์ แพ็กเก็ตจะถูกส่งภายในโปรเซสของเซิร์ฟเวอร์และสแตกของโฮสต์ไม่เคยกลายเป็นเราเตอร์ ดังนั้นไฟร์วอลล์ของเคอร์เนลจึงไม่มีอะไรให้นับ การเข้าใจการแยกนี้เป็นตัวกำหนดว่าคุณจะเก็บทางลัดไว้หรือสร้างเส้นทางผ่านเคอร์เนลใหม่
ติดตามแพ็กเก็ตหนึ่งตัวผ่านเซิร์ฟเวอร์
ในอุโมงค์ที่กำหนดเส้นทาง เดมอนส่งแพ็กเก็ตที่ถอดรหัสแล้วของไคลเอนต์แต่ละรายให้อุปกรณ์อุโมงค์ จากนั้นโฮสต์กำหนดเส้นทางให้ ฮุกการส่งต่อทำงาน และกฎที่ตรงกับอุปกรณ์อุโมงค์สามารถนับหรือทิ้งทราฟฟิกได้ นี่คือเส้นทางที่ตัวอย่างไฟร์วอลล์ส่วนใหญ่อาศัย
| Forwarding path | Who decides | What the host firewall sees |
|---|---|---|
| Kernel routing between clients | Host routing table and forward rules | Every inner packet, with interface names |
| Peer forwarding inside the server process | The VPN daemon's own peer table | Only the outer encrypted transport |
ทางลัดตัดโฮสต์ออกจากตรงกลาง แพ็กเก็ตที่ถอดรหัสแล้วของเซสชันหนึ่งถูกส่งให้อีกเซสชันภายในเดมอน และแพ็กเก็ตชั้นในไม่เคยถูกปล่อยออกทางอุปกรณ์อุโมงค์และโฮสต์ก็ไม่กำหนดเส้นทางให้ ทราฟฟิกที่ห่อหุ้มยังคงข้ามอินเทอร์เฟซทางกายภาพ การดักจับจากภายนอกจึงดูคึกคักในขณะที่กฎภายในยังเงียบ การดักจับบนอุปกรณ์อุโมงค์ไม่แสดงอะไรเลย ซึ่งทำให้ใครก็ตามที่คาดว่าจะเห็นการถ่ายโอนตรงนั้นประหลาดใจ ความไม่สมมาตรนี้คือวิธีที่เร็วที่สุดในการจำทางลัดจากภายนอกเดมอน
การทดสอบด้วยตัวนับที่ชี้ขาดว่าเส้นทางใดถูกใช้
ติดตัวนับไว้ที่กฎที่ควรมีผล รันการถ่ายโอนระหว่างไคลเอนต์สองรายที่กฎนั้นควรบล็อก แล้วอ่านตัวนับภายหลัง
sudo nft list ruleset
sudo nft add rule inet filter forward iifname "tun0" oifname "tun0" counter accept
sudo nft list chain inet filter forward
หากการถ่ายโอนสำเร็จและตัวนับยังเป็นศูนย์ แสดงว่าเคอร์เนลไม่เคยจัดการแพ็กเก็ตเหล่านั้นเลย และการแก้ไขกฎไม่ว่าจะมากเพียงใดก็ไม่เปลี่ยนสิ่งนี้ ทำการทดสอบเดิมซ้ำกับบริการบนเซิร์ฟเวอร์เอง เพราะโฟลว์นั้นผ่านสแตกของโฮสต์จริงและตัวนับขยับ การเปรียบเทียบผลสองอย่างคือสิ่งที่ให้คำตอบ
รายละเอียดสองอย่างป้องกันการอ่านผิด ชื่ออินเทอร์เฟซที่เขียนไว้ในป้ายชื่อเชนไม่ได้กรองอะไรด้วยตัวเอง เพราะการจับคู่เกิดขึ้นที่ฟิลด์อินเทอร์เฟซภายในกฎ และการออกแบบบริดจ์เลเยอร์ 2 ก็ทำงานต่างออกไปอีก ที่นั่นไคลเอนต์ใช้โดเมนกระจายเสียงร่วมกัน การค้นหาเพียร์จึงเป็นเรื่องคาดหมาย ไม่ใช่ข้อบกพร่องในการกำหนดเส้นทาง
สวิตช์ไม่ใช่รายการควบคุมการเข้าถึง
นี่คือส่วนที่กินเวลาครึ่งวัน การส่งต่อระหว่างเพียร์เป็นการตั้งค่าเดียวที่เปิดหรือปิด และตราบใดที่เปิดอยู่เดมอนก็เป็นจุดส่งต่อเพียงจุดเดียว ไฟร์วอลล์ของโฮสต์ไม่อาจระบุได้ว่าใครเข้าถึงใครได้ และไฟล์รายไคลเอนต์ไม่ได้เปลี่ยนสวิตช์ให้เป็นเมทริกซ์นโยบาย
หากคุณต้องการกฎรายเพียร์ ทางเลือกคือระหว่างการยอมสละทางลัด กับ การยอมสละไฟร์วอลล์ของโฮสต์ในฐานะเครื่องมือควบคุม การปิดมันจะคืนการส่งต่อของเคอร์เนล ซึ่งต้องเปิดการส่งต่อ IP บนเซิร์ฟเวอร์และต้องมีกฎชัดเจนสำหรับโฟลว์ที่ต้องการ การเปิดไว้หมายความว่านโยบายอยู่ในคอนฟิกูเรชันของเดมอน ซึ่งในทางปฏิบัติคือเพียร์ทั้งหมดหรือไม่เลย
โปรเซสเซิร์ฟเวอร์แยกกันที่มีพูลแอดเดรสและพอร์ตของตัวเองคือทางสายกลางที่ทำได้จริง แต่ละโปรเซสมีการตัดสินใจเข้าถึงเพียงหนึ่งเดียว สองกลุ่มจึงมีกฎต่างกันได้โดยไม่ต้องมีเมทริกซ์นโยบาย โฮสต์สามารถกำหนดเส้นทางระหว่างพูลได้เมื่อต้องการ และไฟร์วอลล์จะเห็นโฟลว์เหล่านั้นเพราะมันข้ามโฮสต์ ต้นทุนคือพอร์ตเพิ่ม ใบรับรองเพิ่ม และโปรไฟล์ต่อกลุ่ม
การเลือกจุดส่งต่อ
เลือกการส่งต่อผ่านเคอร์เนลเมื่อไฟร์วอลล์เป็นเครื่องยนต์นโยบาย เมื่อต้องการบันทึกทีละโฟลว์ หรือเมื่อการบัญชีมีความสำคัญ ต้นทุนคืออัตราส่งผ่านสแตกของโฮสต์และกฎที่ต้องดูแลมากขึ้น ข้อดีคือเครื่องมือที่มีอยู่ทุกอย่าง ตั้งแต่ตัวนับจนถึงตัวส่งออกโฟลว์ กลับมาอธิบายทราฟฟิกได้อีกครั้ง บนเซิร์ฟเวอร์เล็กต้นทุนนี้มองไม่เห็น บนรีเลย์ที่ทำงานหนักไม่เป็นเช่นนั้น
เลือกการส่งต่อภายในโปรเซสเมื่อทราฟฟิกระหว่างเพียร์ถูกอนุญาตทั้งหมดหรือถูกห้ามทั้งหมด และเซิร์ฟเวอร์ถูกออกแบบมาสำหรับสิ่งนั้น ต้นทุนคือตัวนับ วินัยคิว และการติดตามการเชื่อมต่อไม่อธิบายโฟลว์ภายในอีกต่อไป ซึ่งยอมรับได้เฉพาะเมื่อไม่มีใครพึ่งพาสิ่งเหล่านั้นในภายหลัง
ไม่ว่าคุณจะเลือกสิ่งใด จงเขียนไว้ข้างกฎไฟร์วอลล์ ชุดกฎที่ดูเหมือนอนุญาตทราฟฟิกระหว่างเพียร์ในขณะที่เดมอนตัดสินเองอยู่แล้วทำให้คนถัดไปที่ต้องแก้ปัญหาการถ่ายโอนล้มเหลวเข้าใจผิด ใครที่อ่านแต่กฎจะคิดว่าเคอร์เนลคือประตู
สิ่งที่ต้องตรวจสอบก่อนแก้ไขกฎ
อ่านคอนฟิกูเรชันที่เซิร์ฟเวอร์โหลดจริง ไม่ใช่ไฟล์ที่คุณจำได้ว่าแก้ไข และยืนยันว่ามีตัวเลือกเพียร์หรือไม่ หากคุณเปลี่ยนมัน ต้องแน่ใจว่าบริการโหลดใหม่ ไม่ใช่เพียงเขียนไฟล์บนดิสก์ใหม่
จากนั้นทำการทดสอบซ้ำด้วยโฟลว์จากไคลเอนต์ไปยังเซิร์ฟเวอร์เพื่อพิสูจน์ว่ากฎตรงกันตั้งแต่แรก และตรวจสอบเส้นทางที่ถูกส่งไป เพราะเส้นทางที่หายไปดูเหมือนการบล็อกของไฟร์วอลล์จากฝั่งไคลเอนต์ทุกประการ เปลี่ยนลำดับกฎเมื่อคุณรู้แล้วว่าจุดส่งต่อใดถือการตัดสินใจ