ทำไมอุโมงค์ VPN ที่สองจึงทำให้อันแรกพัง?
ไคลเอนต์ VPN ตัวที่สองติดตั้งเส้นทางเริ่มต้นครึ่งเดียวสองเส้น และอุโมงค์แรกก็ดับลง อ่านว่าเส้นทางใดชนะ แล้วแยกตามโปรไฟล์ ตาราง หรือเนมสเปซ
การติดตั้งไคลเอนต์ VPN ตัวที่สองเพื่อเข้าถึงเครือข่ายของลูกค้าหนึ่งรายคือวิธีที่เรื่องนี้มักเริ่มต้น และอุโมงค์แรกก็ดับลงในขณะที่ไคลเอนต์ทั้งสองรายงานความสำเร็จ ไคลเอนต์แต่ละตัวติดตั้งเส้นทางเริ่มต้น เส้นที่สองเจาะจงกว่า และเคอร์เนลก็ตามเส้นนั้นสำหรับทุกอย่างยกเว้นการเชื่อมต่อภายนอกของอุโมงค์แรกเอง ไม่มีอะไรพังและไม่มีโปรไฟล์ใดผิด เส้นทางหนึ่งมาแทนอีกเส้น และทางแก้คือตัดสินว่าอุโมงค์ใดควรเป็นเจ้าของเส้นทางเริ่มต้น
อาการ: ไคลเอนต์ตัวที่สองชนะอย่างเงียบ ๆ
OpenVPN: ตัวเลือก redirect-gateway def1 ไม่เขียนทับ 0.0.0.0/0 แต่เพิ่ม 0.0.0.0/1 และ 128.0.0.0/1 สองเส้นนี้ครอบคลุมทุกที่อยู่ IPv4 และแต่ละพรีฟิกซ์ชนะเส้นทางเริ่มต้นธรรมดาในด้านความยาว เส้นทางเริ่มต้นเดิมยังอยู่ในตารางและไม่ถูกใช้กับทราฟฟิกปกติอีกต่อไป และเส้นทางโฮสต์ไปยังเซิร์ฟเวอร์ VPN ทำให้อุโมงค์ไม่จับแพ็กเก็ตภายนอกของตัวเอง ไคลเอนต์ทั้งสองทำแบบนี้ และตัวที่สองก็เพียงติดตั้งคู่ของมันทีหลัง
นี่คือเหตุที่อุโมงค์แรกดูเหมือนตายไปแล้วไม่ใช่ถูกตัดขาด อินเทอร์เฟซยังขึ้นอยู่ ช่องควบคุมยังมีชีวิต และไม่มีทราฟฟิกของแอปพลิเคชันมาถึงอีก ข้อร้องเรียนแบบตรงกันข้ามก็มาจาก push ที่หายไปเช่นกัน โทรศัพท์ที่เชื่อมต่อได้แต่ไม่ส่งอะไรเลยมักคุยกับเซิร์ฟเวอร์ที่ไม่เคยประกาศ redirect-gateway อุปกรณ์จึงเก็บเส้นทางเริ่มต้นของตัวเองไว้และเข้าถึงได้เพียงพูล
ถ่ายภาพเส้นทางก่อนและหลังไคลเอนต์ตัวที่สองเชื่อมต่อ สองเส้นทางครึ่งที่ปรากฏในตารางคือการเปลี่ยนแปลงทั้งหมด และอธิบายข้อร้องเรียนทั้งสอง ไม่มีอะไรอื่นในตารางต้องขยับเพื่อให้อาการเกิด นี่คือเหตุที่การถอดไคลเอนต์ตัวที่สองคืนค่าตัวแรกทันที
อ่านว่าอุโมงค์ใดชนะจริง
อย่าเดาผู้ชนะจากลำดับที่ไคลเอนต์เริ่มหรือจากไอคอนในถาดระบบ ถามเคอร์เนลว่าจะใช้เส้นทางใดสำหรับปลายทางนอกเครือข่ายส่วนตัวทั้งสอง และอ่านอินเทอร์เฟซที่ส่งกลับมา
ip route show
ip route get 198.51.100.24
route print -4
Find-NetRoute -RemoteIPAddress 198.51.100.24
สองคำสั่งแรกคือคำตอบของ Linux และสองคำสั่งหลังคือสิ่งที่เทียบเท่าใน Windows รันขณะที่อุโมงค์ทั้งสองขึ้นอยู่ จากนั้นตัดหนึ่งเส้นแล้วรันอีกครั้ง ความต่างระหว่างผลลัพธ์ทั้งสองคือข้อเท็จจริงที่คุณต้องมีก่อนเลือกทางแก้ และใช้เวลาน้อยกว่าการอ่านบันทึกของไคลเอนต์ตัวใดตัวหนึ่ง
บันทึกผลลัพธ์ รวมชื่ออินเทอร์เฟซและพรีฟิกซ์ที่ตรงกัน ตั๋วที่บอกว่า VPN ตัวที่สองทำให้ตัวแรกพังคือคำอธิบายอาการ ไม่ใช่ข้อความเกี่ยวกับเส้นทางที่ใครจะลงมือทำได้ การค้นหาทำให้มันกลายเป็นข้อเท็จจริงที่วิศวกรคนถัดไปทำซ้ำได้ด้วยคำสั่งเดียว
Windows: ห้ามไม่ให้โปรไฟล์หนึ่งเป็นเจ้าของเส้นทางเริ่มต้น
Windows เก็บโปรไฟล์ที่บันทึกไว้ และไคลเอนต์ในตัวยอมให้ตัวหนึ่งขึ้นกับอีกตัวเพื่อให้ตัวแรกขึ้นอัตโนมัติเมื่อตัวที่สองเชื่อมต่อ โปรไฟล์ที่เชื่อมต่อล่าสุดมักเก็บเส้นทางเริ่มต้นไว้ ผู้ถือครองจริงจึงเป็นการเชื่อมต่อครั้งสุดท้ายไม่ใช่ครั้งแรก ให้แต่ละโปรไฟล์มีเส้นทาง push ของตัวเอง และเปิด split tunneling สำหรับตัวที่ไม่ควรเป็นเจ้าของเส้นทางเริ่มต้น
Set-VpnConnection -Name "Contoso" -SplitTunneling $true
rasdial Contoso
Split tunneling เปลี่ยนสิ่งนี้ มีเพียงพรีฟิกซ์ที่เซิร์ฟเวอร์ push เข้ามาในตาราง ซึ่งทำให้เส้นทางเริ่มต้นอยู่กับอุโมงค์แรก การออกแบบยังล้มเหลวหากเซิร์ฟเวอร์ทั้งสอง push เส้นทางเริ่มต้น เพราะตอนนั้นการเชื่อมต่อสุดท้ายชนะและไม่มีอะไรฝั่งไคลเอนต์เปลี่ยนได้ แก้ push ฝั่งเซิร์ฟเวอร์หรือยอมรับเจ้าของเดียว
โปรไฟล์ที่ทริกเกอร์ด้วยแอปเป็นฟีเจอร์อีกอย่างที่ควรรู้ โปรไฟล์ Windows เริ่มได้เมื่อไฟล์ปฏิบัติการที่ระบุเริ่มทำงาน โดยตัวกรองทราฟฟิกตัดสินว่ามันบรรทุกอะไร นี่คือการตั้งค่าโปรไฟล์ไม่ใช่กฎไฟร์วอลล์ และแก้ปัญหาต่างจากความขัดแย้งของเส้นทางเริ่มต้น
Linux: เก็บอุโมงค์ที่สองไว้นอกตารางหลัก
การรันอินสแตนซ์ openvpn --config สองตัวบนเครื่องเดียวทำให้ไคลเอนต์ทั้งสองอยู่ในตารางเดียวกัน และสามทางเลือกแยกทั้งสองด้วยการแยกตัวที่เพิ่มขึ้น ทางที่เบาที่สุดคือห้ามไคลเอนต์ตัวที่สองแก้ตารางเลย ใช้ route-nopull พร้อมเส้นทางชัดเจน หรือสคริปต์ route-up ที่ติดตั้งเฉพาะสิ่งที่คุณตั้งใจ จากนั้นอุโมงค์ที่สองบรรทุกเฉพาะพรีฟิกซ์ที่คุณระบุและไม่มีอย่างอื่น จากนั้นคุณตัดสินใจว่าพรีฟิกซ์ใดไปที่ไหนแทนที่จะค้นพบทีหลัง
Policy routing คือทางเลือกกลาง กฎหนึ่งเลือกตารางแยกสำหรับที่อยู่ต้นทางหรือเครื่องหมายไฟร์วอลล์หนึ่งรายการ และตารางนั้นบรรทุกเส้นทางของอุโมงค์ที่สอง การกรองเส้นทางย้อนกลับคือกับดักตรงนี้ เพราะคำตอบที่มาบนอินเทอร์เฟซต่างจากที่ตารางจะเลือกจะถูกทิ้ง ดังนั้นตรวจสอบการตั้งค่า rp_filter ก่อนสรุปว่าอุโมงค์พัง
ip rule add from 10.44.7.0/24 table 100
ip route add default dev tun1 table 100
sysctl net.ipv4.conf.all.rp_filter
เนมสเปซของเครือข่ายเป็นทางเลือกที่หนักและสะอาดที่สุด เริ่มไคลเอนต์ตัวที่สองภายใน ip netns ให้คู่ veth และเข้าสู่เนมสเปซนั้นเพื่อใช้งาน อาการรบกวนหายไปเพราะแต่ละเนมสเปซมีตารางของตัวเองแทนที่จะแชร์ตารางเดียว ซึ่งคุ้มกับการตั้งค่าเพิ่มเมื่ออุโมงค์ทั้งสองต้องอยู่หลายสัปดาห์
ต่อแอปพลิเคชัน และการต่อโซ่เป็นปัญหาอีกเรื่อง
บางครั้งมีเพียงโปรแกรมเดียวที่ควรใช้อุโมงค์ที่สอง บน Linux policy routing ตามผู้ใช้ cgroup หรือพอร์ตให้ผลนั้น และปลายทางเดียวสามารถปักหมุดกับอินเทอร์เฟซได้โดยไม่แตะเส้นทางเริ่มต้นเลย แอปที่ปักหมุดซ็อกเก็ตไว้กับอินเทอร์เฟซเดียวจะไม่ปรึกษาตารางเส้นทางเลย ตัวเรียกใช้จึงใช้อะแดปเตอร์จริงต่อไปได้จนกว่าจะเลือกที่อยู่ในการตั้งค่าของตัวเอง
การต่อโซ่เป็นการกระทำที่ต่างจากการรันสองอุโมงค์เคียงกัน การต่อ A ผ่าน B หมายความว่าที่อยู่ของเซิร์ฟเวอร์ภายในต้องเข้าถึงได้จากภายในอุโมงค์ภายนอก ไคลเอนต์ภายนอกก็ต้องไม่เข้าใจผิดว่าแพ็กเก็ตที่เข้ารหัสของไคลเอนต์ภายในเป็นการรั่วไหล ไคลเอนต์เดียวในเครื่องเสมือนเป็นเวอร์ชันหยาบแต่เชื่อถือได้ ทั้งสองบนโฮสต์เดียวต้องทำงานเส้นทางข้างต้นบวกเส้นทางภายนอกไปยังเซิร์ฟเวอร์ภายในที่ไม่เคยเข้าอุโมงค์ใน
จดเจ้าของเส้นทางเริ่มต้น รายการพรีฟิกซ์ที่แต่ละอุโมงค์บรรทุก และเส้นทาง DNS ข้อเท็จจริงสามข้อนี้ทำให้เหตุการณ์ครั้งหน้าเป็นการค้นหาไม่ใช่การสอบสวน