Hairpin NAT: ทำไมปลายทาง VPN ถึงล้มเหลวจากภายใน
ไคลเอนต์ภายในที่ใช้ที่อยู่สาธารณะออกจาก LAN แล้วกลับเข้ามา เมื่อเราเตอร์ไม่ทำ hairpin ด้านนอกก็ใช้ได้ แต่ด้านในใช้ไม่ได้
เซิร์ฟเวอร์ VPN ที่ตอบจากเครือข่ายมือถือได้แต่ใช้จากโซฟาไม่ได้ มักไม่ใช่ปัญหาใบรับรอง ไคลเอนต์ภายใน LAN กำลังขอให้เราเตอร์แปลงแพ็กเก็ตที่มีปลายทางเป็นที่อยู่สาธารณะของเราเตอร์เอง ซึ่งหมายความว่าแพ็กเก็ตต้องออกไปแล้วกลับเข้ามาทันที กลอุบายนี้เรียกว่า hairpinning และเราเตอร์จำนวนมากไม่ติดตั้งไว้หรือทำเฉพาะเมื่อเปิดช่องทำเครื่องหมายไว้ การที่การทดสอบจากภายนอกผ่านคือสิ่งที่ทำให้สับสน เพราะมันพิสูจน์ว่าตัวรับฟังและกฎการส่งต่อนั้นถูกต้อง
แพ็กเก็ตออกไปแล้วกลับเข้ามา
ติดตามแพ็กเก็ต ไคลเอนต์แปลงชื่อสาธารณะ เชื่อมต่อกับที่อยู่สาธารณะ และ NAT ปลายทางของเราเตอร์เขียนปลายทางใหม่ไปยังเซิร์ฟเวอร์ภายใน คำตอบจากเซิร์ฟเวอร์ถูกส่งไปยังที่อยู่ LAN ของไคลเอนต์ จึงกลับผ่านอินเทอร์เฟซ LAN ของเราเตอร์โดยไม่เคยผ่านกฎ NAT ที่จะแปลงต้นทางกลับเลย
ตอนนี้ไคลเอนต์ได้รับแพ็กเก็ตจากที่อยู่ที่มันไม่เคยส่งอะไรไป และทิ้งมัน ความไม่สมมาตรนั้นคือความล้มเหลวทั้งหมด
RFC 4787 อธิบายพฤติกรรมที่คาดหวังจาก NAT ในกรณีนี้ และฉบับย่อคือในทางปฏิบัติมันเป็นทางเลือก แม้ในที่ที่ระบุไว้ในทฤษฎี เราเตอร์บางรุ่นเรียกการตั้งค่านี้ว่า NAT loopback บางรุ่นเรียกว่า hairpin NAT หรือ NAT reflection และบางรุ่นไม่แสดงอะไรเลย เราเตอร์ที่ไม่มีสิ่งนี้ไม่ได้กำหนดค่าผิด มันกำลังทำสิ่งปกติ และการแก้ไขอยู่ที่อื่น อย่าสรุปจากการทดสอบภายในที่ล้มเหลวว่ากฎการส่งต่อสาธารณะผิด
การตรวจสอบ 1: ทดสอบสองเส้นทางแยกกัน
จากภายนอก LAN เชื่อมต่อด้วยโปรไฟล์เดียวกับที่ผู้ใช้จริงจะใช้และยืนยันว่าเซสชันถูกสร้าง จากภายในเชื่อมต่อกับที่อยู่สาธารณะด้วยโปรไฟล์เดียวกันและบันทึกข้อผิดพลาดที่แน่นอนกับเวลา
การทดสอบภายในที่แม่นยำยังคงชื่อโฮสต์ไว้และแทนที่เฉพาะที่อยู่: curl -v --resolve vpn.example.com:443:203.0.113.10 https://vpn.example.com/ ส่งคำขอไปยังที่อยู่สาธารณะขณะที่ยังนำเสนอชื่อเซิร์ฟเวอร์ที่ถูกต้อง สิ่งนี้แยกปัญหาการแปลงชื่อออกจากปัญหาการแปลงที่อยู่ ซึ่งสับสนได้ง่ายเมื่อชื่อเดียวกันใช้ได้จากร้านกาแฟ สังเกตว่าไคลเอนต์ล้มเหลวที่การเชื่อมต่อ TCP หรือภายหลังที่ TLS เพราะอย่างแรกชี้ไปที่การแปลงและอย่างที่สองชี้ไปที่ตัวตน
การตรวจสอบ 2: อ่านสิ่งที่เซิร์ฟเวอร์เห็น
ข้อสังเกตที่มีประโยชน์ที่สุดคือมุมมองของเซิร์ฟเวอร์ เริ่มการดักจับบนโฮสต์ VPN ที่กรองตามที่อยู่ LAN ของไคลเอนต์และที่อยู่ LAN ของเราเตอร์ แล้วทำการพยายามภายในซ้ำ หากไม่มีอะไรมาถึง แพ็กเก็ตไม่ได้รอดจากการแปลง
หากการเชื่อมต่อมาจากที่อยู่ LAN ของเราเตอร์แทนที่จะเป็นของไคลเอนต์ hairpinning กำลังเกิดขึ้นและต้นทางถูกเขียนใหม่ นี่คือการกำหนดค่าที่ทำงานได้ ไม่ใช่ข้อบกพร่อง
การตรวจสอบ 3: แก้ไขโดยไม่แตะเส้นทางภายนอก
มีสามรูปแบบที่รองรับ โดยเรียงตามรัศมีผลกระทบที่เพิ่มขึ้น รูปที่แคบที่สุดคือ DNS แยก: เผยแพร่ระเบียนภายในเพื่อให้ชื่อเซิร์ฟเวอร์เดียวกันแปลงเป็นที่อยู่ภายในสำหรับไคลเอนต์ใน LAN ซึ่งหลีกเลี่ยงเส้นทางสาธารณะทั้งหมด วิธีถัดไปคือเปิดตัวเลือก loopback หรือ reflection ที่มีเอกสารของเราเตอร์ หากมี และใช้กับบริการนี้เท่านั้น รูปที่กว้างที่สุดคือกฎ source-NAT บนเราเตอร์ที่เขียนทราฟฟิกจาก LAN ไปยังเซิร์ฟเวอร์ใหม่เพื่อให้คำตอบกลับมาผ่านเราเตอร์ บนเราเตอร์ Linux นี่คือกฎ MASQUERADE ใน POSTROUTING ที่ตรงกับที่อยู่และพอร์ตของเซิร์ฟเวอร์ ทั้งสามวิธีทำให้เส้นทางภายนอกไม่ถูกแตะต้อง และนั่นคือคุณสมบัติที่ต้องรักษาไว้
อย่าขยายการส่งต่อพอร์ตที่ไม่เกี่ยวข้องเพื่อให้เส้นทางภายในดูเหมือนภายนอก และอย่าย้ายบริการไปยังพอร์ตอื่นเพื่อหลีกเลี่ยงปัญหา การเปลี่ยนแปลงทั้งสองอย่างเปลี่ยนสิ่งที่โลกภายนอกเข้าถึงได้เพื่อแก้ไขบางสิ่งที่มีเพียงโลกภายในเท่านั้นที่เห็น
DNS แยกมีกับดักหนึ่งข้อที่ควรกล่าวถึง การแทนที่ชื่อโฮสต์ด้วย IP โดยพลการเปลี่ยนสิ่งที่ไคลเอนต์ตรวจสอบ ดังนั้นระเบียนภายในยังคงต้องตรงกับชื่อในใบรับรอง
การตรวจสอบ 4: ตรวจสอบทั้งสองเส้นทางในภายหลัง
ทำการพยายามภายนอกจากภายนอก LAN ซ้ำ ทำการพยายามภายในด้วยโปรไฟล์เดียวกันซ้ำ และยืนยันว่าบันทึกของเซิร์ฟเวอร์แสดงสองเซสชันที่สำเร็จแยกจากกัน ไม่ใช่ความสำเร็จหนึ่งและความเงียบหนึ่ง จากนั้นตรวจสอบว่าไคลเอนต์อื่นยังเข้าถึงตัวรับฟังได้และเส้นทางไปยังทรัพยากรส่วนตัวไม่เปลี่ยนแปลง
เก็บบันทึกให้สั้น: ไคลเอนต์แต่ละรายใช้ที่อยู่ใด เซิร์ฟเวอร์เห็นอะไร และใช้การแก้ไขข้อใดจากสามข้อ ข้อกำหนด hairpinning ของ RFC 4787 เป็นเอกสารอ้างอิงสำหรับสิ่งที่คาดหวังจาก NAT ที่นี่ และอธิบายว่าเหตุใดเราเตอร์ที่ไม่มีคุณสมบัตินี้จึงทำงานตามปกติ ความล้มเหลวภายในที่โลกภายนอกไม่สามารถจำลองได้เป็นคำถามเรื่องการแปลงจนกว่าจะพิสูจน์เป็นอย่างอื่น ดังนั้นจงทดสอบเช่นนั้น