แฮนด์เชกของ WireGuard ทำงานแต่ไม่มีอินเทอร์เน็ต: ตามรอยแพ็กเก็ต
แฮนด์เชกพิสูจน์เพียงคีย์และการเข้าถึง ตามรอยแพ็กเก็ตหนึ่งแพ็กเก็ตจาก AllowedIPs ผ่านการส่งต่อ NAT และเส้นทางขากลับเพื่อดูว่ามันหยุดที่ใด
อุโมงค์ทำงานอยู่ wg show รายงานแฮนด์เชกล่าสุด คุณสามารถ ping ที่อยู่ tunnel ของเซิร์ฟเวอร์ได้ และไม่มีอะไรเลยถัดจากนั้นตอบกลับ สัญชาตญาณแรกคือการสร้างคีย์ใหม่หรือแชร์คอนฟิกอีกครั้ง ซึ่งไปเปลี่ยนส่วนของเส้นทางที่พิสูจน์แล้วว่าทำงานอยู่
แฮนด์เชกที่เสร็จสมบูรณ์บอกว่าทั้งสองฝ่ายตกลงเรื่องคีย์ได้ UDP ไปถึงปลายทาง และการกำหนดเส้นทางแบบเข้ารหัสยอมรับแพ็กเก็ต แต่ไม่ได้บอกอะไรเลยว่าแพ็กเก็ตจะออกจากเซิร์ฟเวอร์ได้หรือไม่
ดังนั้นจงตามรอยแพ็กเก็ตหนึ่งแพ็กเก็ตแทนการเดา มีสี่จุดที่มันตายได้ และแต่ละจุดทิ้งร่องรอยต่างกัน
แฮนด์เชกพิสูจน์อะไรจริง ๆ
WireGuard เป็นโปรโตคอล UDP ที่สร้างเซสชันด้วยแฮนด์เชก Noise แล้วเข้ารหัสแพ็กเก็ตให้เพียร์ เมื่อ wg show แสดงแฮนด์เชกอายุไม่กี่วินาทีและตัวนับการรับส่งที่เพิ่มขึ้น ปลายทาง คีย์ และกุญแจสาธารณะของเพียร์ล้วนถูกต้อง
สิ่งที่ไม่พิสูจน์คือไคลเอนต์ของคุณส่งทราฟฟิกที่มุ่งสู่อินเทอร์เน็ตเข้าไปในอินเทอร์เฟซหรือไม่ เซิร์ฟเวอร์ยินดีส่งต่อหรือไม่ หรือคำตอบจะหาเส้นทางกลับได้หรือไม่ สิ่งเหล่านี้เป็นการตัดสินใจของเราเตอร์เคอร์เนลและไฟร์วอลล์ และเกิดขึ้นนอกอุโมงค์
นี่คือเหตุผลที่การ ping ไปยังที่อยู่ tunnel ของเซิร์ฟเวอร์เป็นการทดสอบที่หลอกลวงขนาดนั้น แพ็กเก็ตนั้น ถูกส่งถึงเซิร์ฟเวอร์เอง จึงสิ้นสุดในเครื่อง ไม่เคยต้องส่งต่อ ไม่เคยต้องแปล และไม่เคยต้องมีเส้นทางขากลับจากอินเทอร์เน็ต
AllowedIPs คือการตัดสินใจเรื่องเส้นทาง
บนไคลเอนต์ AllowedIPs ทำสองหน้าที่ คือตารางเส้นทางด้วยคีย์เข้ารหัสที่ตัดสินว่าเซลล์ปลายทางใดถูกส่งเข้าไปในอุโมงค์ของเพียร์นี้ และเป็นรายการที่อยู่ต้นทางที่เพียร์จะยอมรับจากคุณ ถ้าคอนฟิกของไคลเอนต์ระบุเพียง 10.8.0.0/24 ปลายทางสาธารณะจะไม่เข้าสู่อินเทอร์เฟซเลย และเส้นทางเริ่มต้นปกติของคุณจะพาพวกมันออกนอกอุโมงค์ ตอนนั้นอุโมงค์ทำงานสมบูรณ์และไม่ได้ทำอะไรที่คุณต้องการเลย
ดูว่าไคลเอนต์ติดตั้งอะไรจริง ๆ ไม่ใช่สิ่งที่ไฟล์คอนฟิกบอก:
wg show wg0 allowed-ipsip route get 1.1.1.1
คำสั่งที่สองคือตัวตัดสิน ถ้าคำตอบระบุอินเทอร์เฟซกายภาพและเกตเวย์ปกติ แพ็กเก็ตไม่ได้ถูกส่งผ่านอุโมงค์ และการเปลี่ยนแปลงฝั่งเซิร์ฟเวอร์จะไม่แก้ให้ เพิ่ม 0.0.0.0/0 สำหรับ IPv4 และ ::/0 สำหรับ IPv6 แยกกัน กฎที่จับทุกอย่างสำหรับตระกูลหนึ่งจะปล่อยอีกตระกูลไว้บนเส้นทางเดิม และนี่คือสาเหตุทั่วไปของอุโมงค์ IPv4 ที่ใช้งานได้กับการค้นหา IPv6 ที่ค้าง
แพ็กเก็ตตายที่เกตเวย์ตรงไหน
ถ้าเส้นทางถูกต้องแต่แพ็กเก็ตยังไปไม่ถึงไหน มันมาถึงเซิร์ฟเวอร์และหยุดอยู่ที่นั่น การตรวจสี่อย่างครอบคลุมเกตเวย์ส่วนใหญ่
การส่งต่อ sysctl net.ipv4.ip_forward ที่คืนค่า 0 คือคำตอบคลาสสิก และหลายดิสทริบิวชันยังคงเป็น 0 โดยค่าเริ่มต้น ต้องเป็น 1 และตั้งค่าถาวรในไฟล์ sysctl ไม่ใช่คำสั่งที่หายไปเมื่อรีบูต การส่งต่อ IPv6 เป็นสวิตช์แยก
นโยบายการกรอง เชน FORWARD ที่มีนโยบายทิ้งโดยค่าเริ่มต้นจะทิ้งทราฟฟิกในอุโมงค์แต่ยอมให้ทราฟฟิกไปยังโฮสต์เอง ซึ่งตรงกับอาการพอดี อ่านชุดกฎที่ใช้งานจริง ไม่ใช่ไฟล์ที่บันทึกไว้: nft list ruleset หรือ iptables -S
การแปลหรือการกำหนดเส้นทาง ไคลเอนต์ที่ใช้ที่อยู่ tunnel แบบส่วนตัวต้องมี NAT ต้นทางบนอินเทอร์เฟซขาออกของเซิร์ฟเวอร์ หรือมีคำนำหน้าที่กำหนดเส้นทางแล้วซึ่งเครือข่ายชั้นบนรู้วิธีส่งกลับ การเลือกระหว่างสองอย่างเป็นไปตามแผนที่อยู่ การเพิ่ม MASQUERADE ให้เครือข่ายที่กำหนดเส้นทางคำนำหน้ากลับอยู่แล้วนั้นไม่เป็นอันตรายแต่ไร้ความหมาย และการละไว้ในที่ที่ไม่มีเส้นทางจะทำให้คำตอบถูกส่งไปยังช่วงส่วนตัวที่ไม่สามารถกำหนดเส้นทางได้
เส้นทางขากลับ ในการออกแบบที่กำหนดเส้นทาง เราเตอร์ชั้นบนต้องมีเส้นทางชี้มาที่เซิร์ฟเวอร์ของคุณ เครือข่ายของผู้ให้บริการก็บล็อกได้เช่นกัน: คลาวด์หลายแห่งเปิดการตรวจต้นทางและปลายทางบนอินสแตนซ์ ซึ่งจะทิ้งแพ็กเก็ตที่ต้นทางไม่ใช่ที่อยู่ของอินสแตนซ์เองอย่างเงียบ ๆ จนกว่าจะปิดการตรวจนั้น
DNS ล้มเหลวต่างจากการกำหนดเส้นทาง
แพ็กเก็ตไปยังที่อยู่ที่รู้จักและการค้นหาชื่อเป็นความล้มเหลวสองอย่างที่แยกกัน และข้อความข้อผิดพลาดชักนำผิดในทิศทางตรงข้าม ถ้า ping 1.1.1.1 ทำงานแต่เบราว์เซอร์โหลดอะไรไม่ได้ เส้นทางถูกต้องและการแปลงชื่อไม่ถูก ถ้า ping เองล้มเหลว DNS ก็ไม่เกี่ยวข้องและคุณกลับไปที่หัวข้อก่อนหน้า
wg-quick ตั้งตัวแก้ไขชื่อจากบรรทัด DNS = ในคอนฟิกได้ และ systemd-resolved มีพฤติกรรมของตัวเองต่อลิงก์ VPN ที่เขียนทับตัวแก้ไขชื่อด้วยที่อยู่ที่เข้าถึงได้เฉพาะในอุโมงค์จะทำให้ทุกการค้นหาล้มเหลวในวินาทีที่อุโมงค์ล่ม ซึ่งดูเหมือนอุโมงค์ทำให้อินเทอร์เน็ตพัง
| Symptom | Layer to inspect |
|---|---|
| Tunnel address pings, nothing else does | Client route, then gateway forwarding |
| Public IP pings, hostnames fail | Resolver selection and reachability |
| Handshake completes, no reply ever | FORWARD policy or missing NAT on the server |
| Small requests work, large transfers stall | MTU and TCP MSS clamping |
ลำดับที่ให้หลักฐาน
เริ่มจากการตรวจฝั่งไคลเอนต์ก่อน เพราะเป็นคำสั่งเดียวและตัดความเป็นไปได้ไปครึ่งหนึ่ง จากนั้นยืนยันว่าเซิร์ฟเวอร์ถูกออกแบบให้เป็นทางออกสู่อินเทอร์เน็ตหรือไม่ เกตเวย์ที่สร้างสำหรับการเข้าถึงแบบส่วนตัวไม่ได้พังเมื่อปลายทางสาธารณะล้มเหลว
บนเซิร์ฟเวอร์ ให้เฝ้าดูอินเทอร์เฟซขณะที่คุณส่ง ping จากไคลเอนต์: tcpdump -ni wg0 icmp ควรแสดงคำขอ และ tcpdump -ni eth0 icmp ควรแสดงว่ามันออกไป ไม่ว่าจะแปลแล้วหรือไม่ ถ้ามันปรากฏในอันแรกและไม่เคยปรากฏในอันที่สอง การหยุดอยู่ที่เซิร์ฟเวอร์เอง ถ้ามันออกไปและไม่มีคำตอบกลับมา ปัญหาอยู่ที่ต้นน้ำ และนั่นเป็นอีกเรื่องหนึ่ง
สุดท้าย ทำให้การแก้ไขอยู่รอดหลังรีบูต การส่งต่ออยู่ในไฟล์ sysctl กฎไฟร์วอลล์อยู่ในบริการที่โหลดมัน และเส้นทางของไคลเอนต์อยู่ในคอนฟิกที่ยกอินเทอร์เฟซขึ้น ไม่ใช่ในเชลล์ที่คุณจะลืม เชื่อมต่อใหม่ ทำการทดสอบสองอย่างเดิมซ้ำ และยืนยันว่าตัวนับขยับ