คุณจินตนาการว่าเซิร์ฟเวอร์ VPN อ่านที่อยู่แล็ปท็อปของคุณจากแพ็กเก็ตแล้วเขียนลงบันทึก สิ่งที่มันอ่านคือสิ่งที่ฮอป NAT สุดท้ายใส่ไว้ในส่วนหัวภายนอก และบนโทรศัพท์ที่ใช้เป็นฮอตสปอต ค่านี้มักเป็นที่อยู่ที่แชร์กับผู้ใช้อื่นอีกหลายร้อยราย ที่อยู่ของเครื่องคุณเอง 192.168.x.x ไม่เคยข้ามอินเทอร์เน็ตในส่วนหัวนั้น และเซิร์ฟเวอร์ให้ที่อยู่ของอุโมงค์หลังการเชื่อมต่อถูกตั้งขึ้นแล้ว ดังนั้นเมื่อบันทึกของเซิร์ฟเวอร์กับ ip addr บนแล็ปท็อปไม่ตรงกัน ทั้งสองฝ่ายไม่ได้ผิด แต่พวกมันอธิบายชั้นต่าง ๆ ของเซสชันเดียวกัน

ที่อยู่สามแบบ และมีเพียงแบบเดียวในบันทึก

ความสับสนเกิดจากการรวมที่อยู่สามแบบเป็นหนึ่งเดียว แต่ละแบบมีเจ้าของต่างกัน อยู่ในส่วนหัวต่างกัน และไปถึงเซิร์ฟเวอร์ด้วยเส้นทางต่างกัน

AddressWho assigns itWhere it sitsVisible to the VPN server
Device address, e.g. 192.168.1.24Your router via DHCPOuter header, before translationNo, rewritten in place
Translated address and portRouter, ISP CGNAT, or bothOuter header, after translationYes, this is the tuple it logs
Tunnel address, e.g. 10.8.0.6The VPN server itselfInner header, after decapsulationYes, 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 แต่อุโมงค์ยังล้มเหลว การแปลงไม่ใช่ปัญหาของคุณ ให้ไปที่แฮนด์เชกและตารางเส้นทางภายในอุโมงค์

บทความที่เกี่ยวข้อง