การเลือกเส้นทางตามต้นทางสำหรับสองพูล VPN: สิ่งที่กฎของคุณมองข้าม
กฎรูปแบบ from จับคู่กับที่อยู่ไคลเอนต์ก่อนที่ SNAT จะเขียนใหม่ และการทดสอบจากเกตเวย์ไม่ตรงกับทั้งสองแบบ รันการค้นหาต่อพูลแล้วอ่านลำดับความสำคัญแทน
สองพูลไคลเอนต์ เกตเวย์หนึ่งตัว และแผนดูเหมือนจะง่าย: กฎข้อหนึ่งส่งพูลแรกออกทางอัปลิงก์เร็ว อีกข้อส่งพูลที่สองผ่านอุโมงค์ของพาร์ตเนอร์ จากนั้นกฎก็อยู่ครบ แต่พูลที่สองก็ยังออกทางเส้นทางเริ่มต้นอยู่ดี กฎไม่ได้เสีย ปัญหาคือต้นทางของแพ็กเก็ตไม่ใช่สิ่งที่ผู้เขียนคาดไว้ในจังหวะที่ทำการค้นหา เพราะการแปลงที่อยู่กับการค้นหาเกิดขึ้นคนละจุดในเส้นทางของแพ็กเก็ตเดียวกัน และลำดับกลับตรงข้ามกับภาพในหัวที่คนส่วนใหญ่ วาด
การค้นหาเกิดขึ้นก่อนที่ต้นทางจะถูกเขียนใหม่
สำหรับแพ็กเก็ตที่ถูกส่งต่อจากไคลเอนต์ VPN เคอร์เนลทำงานตามลำดับที่แน่นอน แพ็กเก็ตมาถึงอินเทอร์เฟซของอุโมงค์ ผ่าน prerouting ที่มี conntrack กับ DNAT จากนั้นจึงตัดสินใจเรื่องเส้นทาง ตามด้วยการส่งต่อ และปิดท้ายด้วย postrouting ที่ SNAT ถูกใช้เป็นขั้นสุดท้าย กฎรูปแบบ from ถูกตรวจสอบระหว่างการตัดสินใจเรื่องเส้นทางนั้น จึงเห็นที่อยู่เดิมของไคลเอนต์ ไม่ใช่ที่อยู่ที่แปลงแล้ว
ดังนั้นการเพิ่มกฎ masquerade ไม่ได้เปลี่ยนว่ากฎนโยบายใดจับคู่กับทราฟฟิกขาออก สิ่งที่เปลี่ยนคือฝั่งปลายทางเห็นอะไร และส่งผลให้มีเส้นทางกลับแบบใด สองอย่างนี้เป็นผลลัพธ์คนละเรื่อง และการรีวิวการเปลี่ยนแปลงมักทำให้สับสนอยู่เสมอ แยกสองเรื่องนี้ออกจากกัน แล้วการออกแบบมักชัดเจนภายในหนึ่งนาที
ที่อยู่ที่แปลงแล้วจะปรากฏในกฎในทิศทางของคำตอบ แพ็กเก็ตที่ย้อนกลับมาที่เกตเวย์ถูกส่งไปยังที่อยู่ที่แปลงแล้ว และถ้าคุณมีกฎนโยบายที่อิงปลายทางหรืออิงอินเทอร์เฟซที่แพ็กเก็ตเข้ามา นั่นคือค่าที่คุณจะจับคู่ การเชื่อมต่อเดียวกัน แต่มีแหล่งความจริงต่างกันในแต่ละทิศทาง
| Stage | Source the kernel sees | What it means for your rule |
|---|---|---|
| Prerouting | Client address, 172.31.7.42 | Where marks and DNAT are applied |
| Routing decision | Still 172.31.7.42 | This is where from rules match |
| Postrouting | Becomes 198.51.100.9 | What the far end and its return route see |
สองพูลที่มีต้นทางต่างกันจึงต้องการตารางต่างกันจริง และการออกแบบก็ถูกต้อง สิ่งที่ตารางข้างต้นตัดออกคือทางลัดในการดีบักด้วยการดูว่าปลายทางไกลได้รับอะไรแล้วอนุมานกฎจากตรงนั้น
การทดสอบจากเกตเวย์ไม่ใช่การทดสอบของพูล
ทราฟฟิกที่เกตเวย์สร้างขึ้นเองไม่เคยผ่าน prerouting เพราะไม่ได้เข้ามาทางอินเทอร์เฟซใดเลย มันถูกเลือกเส้นทางในเส้นทางขาออก โดยมีที่อยู่ของเกตเวย์เองเป็นต้นทาง และกฎ from ที่อิงช่วงไคลเอนต์จะไม่ตรงกัน ทุกตั๋วในเรื่องนี้ที่บอกว่าใช้ได้จากเครื่องแต่ไม่ได้จากไคลเอนต์ คือการพูดถึงข้อเท็จจริงเดียวกันซ้ำ
จำลองไคลเอนต์แทนการประมาณ การค้นหาเส้นทางถามได้โดยตรง ด้วยการระบุต้นทางและอินเทอร์เฟซขาเข้า
ip route get 198.51.100.9 from 172.31.7.42 iif tun0
ip route get 198.51.100.9 from 172.31.8.42 iif tun0
ip route show table 201
รันหนึ่งครั้งต่อพูล ถ้าสองคำสั่งคืนอินเทอร์เฟซเดียวกัน แสดงว่ากฎไม่ได้แยกพูล และสาเหตุคือกฎที่หายไปหรือกฎที่มีลำดับความสำคัญสูงกว่าซึ่งตรงกับทั้งสอง ถ้าคืนอินเทอร์เฟซต่างกันแต่ไคลเอนต์ยังล้มเหลว ความผิดพลาดอยู่หลังการค้นหาและคุณเลิกดูกฎได้
ลำดับความสำคัญ ไม่ใช่ตำแหน่งในไฟล์
กฎถูกประเมินตามลำดับความสำคัญจากน้อยไปมาก และตัวเลขคือสิ่งที่สำคัญ ไม่ใช่ลำดับที่คุณพิมพ์ ตาราง local อยู่ที่ลำดับความสำคัญ 0 ตาราง main ที่ 32766 และกฎเริ่มต้นที่ 32767 เพราะฉะนั้นกฎที่เพิ่มด้วยลำดับความสำคัญเริ่มต้นจะไปอยู่ใกล้ปลายรายการและแพ้แทบทุกอย่าง
ip rule show
ip rule add from 172.31.8.0/24 lookup 201 priority 1000
ip -4 route show table 201
ลำดับความสำคัญที่ระบุชัดทำให้ลำดับที่ตั้งใจมองเห็นได้ทั้งในไฟล์และการรีวิว และยังกันไม่ให้การเพิ่มภายหลังแซงหน้ากฎเดิมอย่างเงียบ ซึ่งเป็นสาเหตุที่พบบ่อยที่สุดที่นโยบายที่เคยทำงานหยุดทำงานหลังการเปลี่ยนแปลงที่ไม่เกี่ยวข้อง
กฎที่ตรงกันและชี้ไปยังตารางที่ไม่สมบูรณ์คือกับดักอีกอย่าง ถ้าตาราง 201 มีเส้นทางเริ่มต้นแต่ไม่มีเส้นทางไปยังปลายทาง แพ็กเก็ตจะถูกทิ้งหรือถูกส่งไปผิดที่ และกฎก็ดูถูกต้องสมบูรณ์เมื่อมองแยก อ่านตาราง ไม่ใช่แค่อ่านกฎ กฎคือตัวชี้ และตารางว่างคือตัวชี้ไปที่ความว่างเปล่า
เส้นทางกลับยังต้องมีอยู่
นโยบายต้นทางเลือกทางออก แต่ไม่ได้สร้างเส้นทางกลับ ถ้าพูลที่สองออกผ่านอุโมงค์ของพาร์ตเนอร์ พาร์ตเนอร์ต้องรู้ว่าจะไปถึง 172.31.8.0/24 ได้อย่างไร ไม่ว่าจะด้วยเส้นทางกลับมาที่เกตเวย์หรือด้วยการได้รับที่อยู่ที่แปลงแล้วซึ่งมันรู้จักอยู่แล้ว
การเลือกระหว่างสองอย่างนี้เป็นการตัดสินใจออกแบบที่มีผลลัพธ์ที่มองเห็นได้ การเลือกเส้นทางกลับของช่วงไคลเอนต์รักษาเอกลักษณ์ของไคลเอนต์แต่ละรายที่พาร์ตเนอร์และต้องให้พาร์ตเนอร์ยอมรับคำนำหน้าของคุณ ส่วนการแปลงซ่อนพูลไว้หลังที่อยู่เดียวและต้องให้พาร์ตเนอร์ยอมรับเฉพาะที่อยู่นั้น แลกกับบันทึกของคุณกับของเขาจะไม่ตรงกันอีกว่าคือใครเชื่อมต่อ
เลือกอะไรก็ตาม ให้เขียนไว้ข้างนิยามของพูล เส้นทางกลับที่มีอยู่เพียงในความจำของใครคนหนึ่ง คือสิ่งที่ survives จนกว่าพาร์ตเนอร์จะเปลี่ยนไฟร์วอลล์ แล้วใช้เวลาหนึ่งวันในการสร้างใหม่
อย่าจับอุโมงค์ของเกตเวย์เองในนโยบาย
กฎที่คุณเขียนสำหรับไคลเอนต์ใช้กับทราฟฟิกที่เกตเวย์สร้างด้วย เว้นแต่คุณจะยกเว้นไว้ กฎกว้างที่อิงเครื่องหมายหรืออิงอินเทอร์เฟซขาออกอาจจับการเชื่อมต่อของเกตเวย์เองกับพาร์ตเนอร์ แล้ว อุโมงค์ที่พานโยบายไปก็ถูกเลือกเส้นทางโดยนโยบายนั้น ซึ่งทำให้เกิดลูปหรือการขาดหายที่ดูเหมือนความผิดพลาดของผู้ให้บริการ
จำกัดแต่ละกฎให้แคบเท่าที่การออกแบบอนุญาต: คำนำหน้าต้นทาง อินเทอร์เฟซขาเข้า และหากรองรับ เครื่องหมายที่แพ็กเก็ตของไคลเอนต์เท่านั้นพาไป จากนั้นทดสอบการเชื่อมต่อของเกตเวย์เองหลังทุกการเปลี่ยนกฎ เพราะความผิดพลาดอ้างถึงตัวเองและไม่ปรากฏในการทดสอบจากไคลเอนต์
หน้าคู่มือ ip-rule อธิบายความหมายของตัวเลือกและลำดับความสำคัญ ผสานกับการทดสอบค้นหาต่อพูล แล้วการออกแบบจะตรวจสอบได้ ซึ่งเป็นความต่างระหว่างการเลือกเส้นทางตามนโยบายที่อยู่ได้หนึ่งปีกับแบบที่ทุกคนกลัวจะแตะต้อง