NAT เป็นตัวกำหนดว่าเซิร์ฟเวอร์ VPN ของคุณเห็นที่อยู่ต้นทางใดจริง ๆ
ที่อยู่แล็ปท็อปของคุณไม่เคยไปถึงเซิร์ฟเวอร์ VPN NAT เขียนที่อยู่ใหม่ที่ฮอปสุดท้าย และ IP ของอุโมงค์จะถูกกำหนดในภายหลัง วิธีเปรียบเทียบทั้งสองฝั่ง
คุณจินตนาการว่าเซิร์ฟเวอร์ VPN อ่านที่อยู่แล็ปท็อปของคุณจากแพ็กเก็ตแล้วเขียนลงบันทึก สิ่งที่มันอ่านคือสิ่งที่ฮอป NAT สุดท้ายใส่ไว้ในส่วนหัวภายนอก และบนโทรศัพท์ที่ใช้เป็นฮอตสปอต ค่านี้มักเป็นที่อยู่ที่แชร์กับผู้ใช้อื่นอีกหลายร้อยราย ที่อยู่ของเครื่องคุณเอง 192.168.x.x ไม่เคยข้ามอินเทอร์เน็ตในส่วนหัวนั้น และเซิร์ฟเวอร์ให้ที่อยู่ของอุโมงค์หลังการเชื่อมต่อถูกตั้งขึ้นแล้ว ดังนั้นเมื่อบันทึกของเซิร์ฟเวอร์กับ ip addr บนแล็ปท็อปไม่ตรงกัน ทั้งสองฝ่ายไม่ได้ผิด แต่พวกมันอธิบายชั้นต่าง ๆ ของเซสชันเดียวกัน
ที่อยู่สามแบบ และมีเพียงแบบเดียวในบันทึก
ความสับสนเกิดจากการรวมที่อยู่สามแบบเป็นหนึ่งเดียว แต่ละแบบมีเจ้าของต่างกัน อยู่ในส่วนหัวต่างกัน และไปถึงเซิร์ฟเวอร์ด้วยเส้นทางต่างกัน
| Address | Who assigns it | Where it sits | Visible to the VPN server |
|---|---|---|---|
Device address, e.g. 192.168.1.24 | Your router via DHCP | Outer header, before translation | No, rewritten in place |
| Translated address and port | Router, ISP CGNAT, or both | Outer header, after translation | Yes, this is the tuple it logs |
Tunnel address, e.g. 10.8.0.6 | The VPN server itself | Inner header, after decapsulation | Yes, but it chose it |
เฉพาะแถวกลางเท่านั้นที่ยังไม่ทราบตอนเชื่อมต่อ เซิร์ฟเวอร์เขียนลงตารางเพียร์ ไฟล์สถานะ หรือบันทึกโฟลว์ ขึ้นอยู่กับเดมอน WireGuard เรียกมันว่าจุดปลายทาง ไฟล์สถานะของ OpenVPN ระบุว่าเป็น Real Address และ strongSwan รายงานว่าเป็นโฮสต์ระยะไกลของ IKE_SA ค่านั้นจะรีเฟรชทุกครั้งที่มีแพ็กเก็ตมาจากแหล่งอื่น จึงเปลี่ยนได้โดยไม่มีใครรีสตาร์ตอะไร
แถวล่างคือสิ่งที่ผู้คนอ่านผิดว่าเป็นการอ้างตัวตน มันระบุช่องในคอนฟิกของเซิร์ฟเวอร์ ไม่ใช่บุคคล เพราะเซิร์ฟเวอร์เลือกจากพูลของตัวเอง ผู้ใช้สองคนอาจได้ที่อยู่ของอุโมงค์เดียวกันในวันต่างกัน และคนหนึ่งอาจถือสองที่อยู่จากสองอุปกรณ์
ทำไม tuple ที่บันทึกไว้เปลี่ยนขณะที่อุโมงค์ยังทำงาน
การแปลงที่อยู่คือตารางที่มีตัวจับเวลา ไม่ใช่การผูกถาวร เราเตอร์บ้านเก็บแมปปิ้ง UDP ไว้ระยะหนึ่งหลังแพ็กเก็ตสุดท้าย เกตเวย์ของผู้ให้บริการเวียนพอร์ตตามตารางของตัวเอง และโทรศัพท์ที่ย้ายจาก Wi-Fi ไป LTE กลับมาด้วยแหล่งที่ต่างออกไปโดยสิ้นเชิง ค่าเริ่มต้นของ conntrack ใน Linux เป็นเกณฑ์ที่มีประโยชน์ตรงนี้ nf_conntrack_udp_timeout คือ 30 วินาที และแบบสตรีมมิ่งคือ 120 ดังนั้นอุโมงค์ที่เงียบอาจสูญเสียแมปปิ้งไปนานก่อนผู้ใช้จะสังเกตเห็น
อุโมงค์ยังอยู่ได้เพราะโปรโตคอลตรวจสอบสิทธิ์เพียร์ ไม่ใช่ที่อยู่ WireGuard ไม่มีสถานะหลังแฮนด์เชก แพ็กเก็ตที่ผ่านการตรวจสอบจึงอัปเดตจุดปลายทางที่เก็บไว้ และการผูกใหม่จะหายเองในแพ็กเก็ตถัดไป นี่คือเหตุผลที่มี persistent-keepalive = 25 เพื่อให้แมปปิ้งยังอุ่นระหว่างไม่มีการใช้งาน --float ของ OpenVPN ทำหน้าที่เดียวกันและยอมให้ไคลเอนต์ที่ผ่านการตรวจสอบดำเนินต่อจากที่อยู่และพอร์ตใหม่ ในบิลด์ 2.4 และ 2.5 ที่ปิด float เป็นค่าเริ่มต้น การผูกใหม่จะรีเซ็ตเซสชันและไคลเอนต์เชื่อมต่อใหม่
IPsec ไปถึงจุดนั้นด้วยชิ้นส่วนที่เคลื่อนไหวมากกว่า IKEv2 สังเกตการแปลงโดยเปรียบเทียบแฮชต้นทางและปลายทางในเพย์โหลดตรวจจับ NAT เปลี่ยนไปใช้การห่อหุ้ม UDP 4500 และติดตาม keepalive ไปยัง tuple ใหม่ เมื่อ keepalive ถูกบล็อก SA จะยังขึ้นอยู่บนกระดาษ ขณะที่ทราฟฟิกในทิศทางหนึ่งหยุดลงอย่างเงียบ ๆ
เซิร์ฟเวอร์ระบุอะไรได้บ้าง และระบุอะไรไม่ได้
ตำนานที่ควรกำจัดคือการแปลงที่อยู่ซ่อนคุณจากผู้ให้บริการ มันเปลี่ยนป้ายชื่อ ไม่ใช่การสังเกต เกตเวย์หลัง NAT ของผู้ให้บริการเห็นพื้นที่ 100.64.0.0/10 หรือที่อยู่สาธารณะหนึ่งรายการที่ผู้ใช้หลายรายแชร์ และยังสามารถผูกโฟลว์กับหัวข้อของใบรับรอง คีย์สาธารณะของ WireGuard ที่อยู่ของอุโมงค์ที่จัดสรร ตัวนับไบต์ และหน้าต่างเวลาได้ ไม่มีสิ่งใดในนี้ที่ต้องใช้ที่อยู่ LAN ของคุณ
ขีดจำกัดก็ทำงานในอีกทางเช่นกัน ที่อยู่ที่แชร์ในบันทึกชี้ไปที่เกตเวย์ ไม่ใช่ครัวเรือน สองเซสชันจากที่อยู่ที่แปลงแล้วเดียวกันบนพอร์ตต่างกันคืออุปกรณ์คนละเครื่อง ที่อยู่เดียวกันในสองวันต่างกันอาจเป็นผู้ใช้สองรายที่ไม่เกี่ยวข้องกันหากพอร์ตถูกนำกลับมาใช้ เซิร์ฟเวอร์ที่บันทึกเฉพาะคีย์เพียร์ไม่สามารถจับคู่กับลูกค้าได้หากไม่มีฐานข้อมูลบัญชี และเซิร์ฟเวอร์ที่บันทึกเฉพาะที่อยู่ไม่สามารถแยกแล็ปท็อปออกจากโทรศัพท์หลังเราเตอร์เดียวกันได้
เปรียบเทียบทั้งสองฝั่งแทนการเดา
เพื่อตัดสินว่าเกิดอะไรขึ้น ให้จับการเชื่อมต่อเดียวกันที่ทั้งสองฝั่งในเวลาเดียวกันและเปรียบเทียบ tuple ไม่ใช่ที่อยู่ ฝั่งไคลเอนต์ ก่อนการแปลงใด ๆ
ss -uapn 'dport = :51820'
ip -4 route get 203.0.113.10
wg show wg0 endpoints
จากนั้นอ่านรายการแปลงบนเราเตอร์หรือเกตเวย์ CGNAT และสิ่งที่มาถึงเซิร์ฟเวอร์ในที่สุด
conntrack -L -p udp --dport 51820
tcpdump -ni eth0 udp port 51820
สามรูปแบบอธิบายความไม่ตรงกันส่วนใหญ่ พอร์ตต้นทางบนเซิร์ฟเวอร์ต่างจากพอร์ตภายในขณะที่ปลายทางตรงกัน นี่คือการแปลงพอร์ตปกติ ที่อยู่ต้นทางบนเซิร์ฟเวอร์เป็นของบล็อก ISP ที่ไม่ใช่ของคุณ แสดงว่ามีชั้น NAT เพิ่มอย่างน้อยหนึ่งชั้น แพ็กเก็ตหยุดหลังช่วงไม่มีการใช้งานแล้วกลับมาด้วยพอร์ตใหม่ แมปปิ้งหมดอายุ ไม่ใช่ความผิดพลาดของการกำหนดเส้นทาง หากเวลาห่างกันเกินหนึ่งหรือสองวินาที คุณกำลังเปรียบเทียบความพยายามคนละครั้ง
จุดที่ความต่างทำให้เกิดปัญหา
การหยุดชะงักที่ดูเหมือนเซิร์ฟเวอร์มีปัญหามักเริ่มที่นี่ กฎการเข้าถึงที่ผูกกับที่อยู่บ้านของคุณ ล้มเหลวหลังสัญญาเช่า ISP เปลี่ยน กฎ fail2ban ที่ตรงกับที่อยู่ที่แปลงแล้วจะบล็อกผู้ใช้ทั้งหมดหลังเกตเวย์นั้นพร้อมกัน เพียร์ระหว่างไซต์ที่มีที่อยู่ระยะไกลคงที่จะหยุดต่ออายุคีย์หลังลิงก์มือถือเปลี่ยน โปรโตคอลของอุโมงค์ปกติดี แต่สมมติฐานเกี่ยวกับ tuple ภายนอกไม่ปกติ
ความสับสนเดียวกันปรากฏที่ฝั่งเซิร์ฟเวอร์ด้วย หากกล่อง VPN เองอยู่หลัง NAT คุณต้องมีการส่งต่อพอร์ตและเส้นทางการส่งต่อที่ใช้งานได้ คู่มือการส่งต่อของ strongSwan ครอบคลุมกรณีนั้นสำหรับ IPsec เซิร์ฟเวอร์ที่เข้าถึงได้เฉพาะที่อยู่ส่วนตัวจะไม่เห็น tuple ที่แปลงแล้วซึ่งไคลเอนต์นำเสนอ และนี่เป็นปัญหาคนละอย่างกับการที่ไคลเอนต์ถูกแปลง
ทำการตรวจสอบทั้งสี่ข้อตามลำดับและหยุดที่ข้อแรกที่ล้มเหลว
- จับที่ทั้งสองฝั่งในเวลาเดียวกัน ยืนยันว่าพอร์ตต้นทาง พอร์ตปลายทาง และเวลาตรงกัน
- อ่านรายการเพียร์ของเซิร์ฟเวอร์สำหรับที่อยู่ที่มันถืออยู่ตอนนี้ ไม่ใช่ที่อยู่ที่คุณคาดไว้
- ตรวจตาราง conntrack หรือ NAT สำหรับรายการและอายุที่เหลือ
- ยืนยันว่าที่อยู่ของอินเทอร์เฟซอุโมงค์บนไคลเอนต์ตรงกับที่เซิร์ฟเวอร์จัดสรร ไม่ใช่ที่อยู่ LAN
หากการจับทั้งสองฝั่งตรงกันใน tuple แต่อุโมงค์ยังล้มเหลว การแปลงไม่ใช่ปัญหาของคุณ ให้ไปที่แฮนด์เชกและตารางเส้นทางภายในอุโมงค์