ดูเหมือนอุโมงค์จะทำงานก็ต่อเมื่อเซิร์ฟเวอร์ส่งอะไรบางอย่างมาก่อน เริ่มจากไคลเอนต์แล้วไม่มีอะไรเกิดขึ้น รอสักสองสามวินาที ลองอีกครั้งแล้วสำเร็จ การวินิจฉัยตามปกติคือ NAT เสีย และการวินิจฉัยตามปกตินั้นผิด สิ่งที่เปลี่ยนไปคือฝั่งหนึ่งได้เรียนรู้ว่าอีกฝั่งอยู่ที่ไหน

ความรู้เรื่องปลายทาง ไม่ใช่การเข้าถึงได้

เพียร์ของ WireGuard จะไม่เริ่มแฮนด์เชกจนกว่าจะรู้ว่าจะส่งไปที่ไหน การกำหนดค่าจัดหาให้เป็นปลายทางที่ประกอบด้วยที่อยู่และพอร์ต และสถานะที่กำลังทำงานติดตามปลายทางที่เชื่ออยู่ในขณะนี้

wg show พิมพ์ทั้งสองด้านของภาพนั้น และเพียร์ที่ไม่มีปลายทางในผลลัพธ์ก็เริ่มอะไรไม่ได้เลย ไม่ว่ากุญแจสาธารณะและคำนำหน้าที่อนุญาตจะถูกต้องเพียงใด เปรียบเทียบมุมมองของไคลเอนต์กับของเซิร์ฟเวอร์ก่อนเปลี่ยนกฎใด ๆ เพราะทั้งสองมักไม่ตรงกันว่าใครรู้อะไร

เพียร์เรียนรู้ปลายทางได้อย่างไร

WireGuard เงียบโดยเจตนา เมื่อแพ็กเก็ตที่พิสูจน์ตัวตนถูกต้องมาถึงจากที่อยู่ที่เพียร์ไม่ได้คาดไว้ การนำไปใช้งานจะอัปเดตปลายทางของเพียร์นั้นเป็นต้นทางใหม่ และนั่นคือวิธีที่การโรมมิ่งทำงานบนแล็ปท็อปที่เปลี่ยนเครือข่าย พฤติกรรมนี้อธิบายการขึ้นกับทิศทาง ถ้าเซิร์ฟเวอร์ส่งก่อนและแพ็กเก็ตของมันไปถึงไคลเอนต์ ไคลเอนต์จะเรียนรู้ที่อยู่ปัจจุบันของเซิร์ฟเวอร์และตอบกลับได้ จนถึงตอนนั้นมันไม่มีที่ให้ส่ง กลไกนี้คือการโรมมิ่งที่พิสูจน์ตัวตนแล้ว ไม่ใช่ทางลัดแบบเชื่อถือในการใช้งานครั้งแรก เพราะแพ็กเก็ตต้องถูกต้องก่อนที่ปลายทางจะย้าย

เอกสารเครื่องมือสำหรับ wg อธิบายการอัปเดตนั้น และคุ้มค่าที่จะอ่านสักครั้งหากคุณจะออกแบบโดยอิงสิ่งนี้

การแปลแบบมีสถานะเพิ่มทิศทางของตัวเอง

เมื่อ UDP ผ่านเกตเวย์ที่แปลที่อยู่ เกตเวย์จะสร้างสถานะสำหรับแพ็กเก็ตแรกที่มันเห็น RFC 4787 อธิบายพฤติกรรมนั้นและเวลาหมดอายุที่ในที่สุดจะลบการแมปออก การแมปที่ไม่มีการใช้งานจะหมดอายุ และแพ็กเก็ตขาเข้าจากฝั่งไกลจะถูกเกตเวย์ทิ้งก่อนถึงโฮสต์ อุโมงค์ที่ทำงานทั้งเช้าจะหยุดตอบตอนบ่ายด้วยเหตุผลนี้เอง

นี่คือกลไกที่สองและเป็นอิสระซึ่งสร้างอาการตามทิศทางเดียวกัน ทั้งความรู้เรื่องปลายทางและสถานะการแปลต้องถูกต้อง และการแก้อย่างหนึ่งไม่อีกอย่างหนึ่ง

กำหนดทิศทางที่คุณต้องการจริง ๆ

สำหรับไคลเอนต์ที่ต้องเริ่มการเชื่อมต่อ ให้ใส่ปลายทางของเซิร์ฟเวอร์ในส่วนเพียร์ของไคลเอนต์และเก็บไว้ที่นั่น การพึ่งให้เซิร์ฟเวอร์ส่งก่อนคือการพึ่งความบังเอิญในลำดับทราฟฟิกที่จะเปลี่ยนในเครือข่ายที่เงียบ การกำหนดค่าควรระบุทิศทางที่ตั้งใจ ไม่ใช่ค้นพบมัน

สำหรับเพียร์ที่อยู่หลังการแปลซึ่งต้องเข้าถึงได้ต่อไป ให้เปิด keepalive แบบต่อเนื่องที่ฝั่งนั้น keepalive ทุก 25 วินาทีคือค่าเริ่มต้นปกติ และจุดประสงค์คือทำให้การแมปเปิดอยู่ ไม่ใช่ทดสอบอุโมงค์ เลือกฝั่งเดียวเพื่อรับภาระนี้ เพราะการเปิดทั้งสองฝั่งเพิ่มทราฟฟิกและเสียงรบกวนในบันทึกเป็นสองเท่าโดยไม่ปรับผลลัพธ์ให้ดีขึ้น

เปรียบเทียบสถานะก่อนและหลังตัวกระตุ้น

บันทึกมุมมองทั้งสองในขณะที่มันล้มเหลว แล้วบันทึกอีกครั้งหลังจากเซิร์ฟเวอร์ส่ง คำสั่งแรกแสดงปลายทางและอายุของแฮนด์เชก คำสั่งที่สองแสดงว่ามีรายการแปลสำหรับพอร์ตหรือไม่ การบันทึกแสดงว่าทิศทางใดข้ามสายไปจริง และการตรวจเส้นทางยืนยันว่าไคลเอนต์ไม่ได้ส่งทราฟฟิกนั้นไปที่อื่นทั้งหมด

wg show
conntrack -L -p udp 2>/dev/null | grep 51820
tcpdump -ni any -c 20 'udp port 51820'
ip route get 198.51.100.7

บันทึกคอลัมน์ปลายทางและรายการแปลไว้ด้วยกัน เพียร์ที่ไม่มีปลายทางและเกตเวย์ที่ไม่มีการแมปเป็นข้อบกพร่องสองอย่างที่ต่างกัน มีเพียงอย่างเดียวเท่านั้นที่ keepalive แก้ได้

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