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

ห่วงโซ่ที่ทำงานจนกว่าคุณจะคุยกับกล่องกลาง

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

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

ทำไมคำตอบจึงออกไปทางอุโมงค์

บน B อินเทอร์เฟซที่หันไปทาง C มี AllowedIPs = 0.0.0.0/0 พร้อมกับเส้นทางเริ่มต้นที่ตรงกัน ดังนั้นทุกแพ็กเก็ตที่ B สร้างจะเข้าสู่อุโมงค์นั้น เว้นแต่จะมีสิ่งที่เฉพาะเจาะจงกว่ามีลำดับความสำคัญ

แพ็กเก็ตจาก A ที่ส่งถึง B มาถึงและได้รับการยอมรับ เพราะ B เป็นปลายทางและการส่งมอบภายในเกิดขึ้นก่อน คำตอบคือแพ็กเก็ตใหม่เอี่ยมที่สร้างขึ้นภายในและมุ่งไปยังที่อยู่สาธารณะของ A และปลายทางนั้นตรงกับเส้นทางเริ่มต้นเข้าไปในอุโมงค์ C ได้รับมัน ไม่ได้เป็นเจ้าของที่อยู่ดังกล่าว และทิ้งมันไป

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

การซ่อมแซมแบบแคบ: กฎนโยบายที่ตรงกับพอร์ตต้นทาง

คำตอบจากซ็อกเก็ตที่ฟังอยู่ของ B ออกไปด้วยพอร์ตต้นทาง 500 กฎนโยบายสามารถจับคู่กับสิ่งนั้นและส่งแพ็กเก็ตเหล่านั้นกลับไปยังตารางปกติ:

ip rule add sport 500 table main priority 100
ip rule add sport 8080 table main priority 101

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

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

ให้กฎมีเจ้าของ

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

PostUp = ip rule add sport 500 table main priority 100
PostDown = ip rule del sport 500 table main priority 100

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

เปรียบเทียบทางเลือกอย่างซื่อสัตย์

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

ApproachWhat it costsWhere it breaks
Source-port policy ruleOne rule per exposed portAnything B forwards rather than originates
Destination exception routeA route pinned to specific client addressesClients whose address changes
Stop full-tunnelling on BLoses the catch-all path toward CDesigns that depend on it
Split into two tunnelsMore interfaces and more policyNothing, at the cost of complexity

ตรวจสอบจากทั้งสองด้านเมื่อคุณเลือกแล้ว จาก A เริ่มการเชื่อมต่อไปยังพอร์ตของ B และทำให้ไม่ว่างสักระยะ บน B ให้เคอร์เนลพิสูจน์เส้นทางคำตอบด้วยสิ่งที่คล้ายกับ ip route get <address-of-A> sport 500 และยืนยันว่ามันระบุอินเทอร์เฟซ WAN ไม่ใช่อุโมงค์ หลังจากนั้นตรวจสอบว่ามีบางสิ่งหลัง C ยังตอบผ่านห่วงโซ่ ซึ่งพิสูจน์ว่าข้อยกเว้นยังคงแคบแทนที่จะกลายเป็นการข้าม สุดท้ายบันทึกพอร์ตลงในบันทึกการออกแบบ มิฉะนั้นผู้ดูแลคนถัดไปจะค้นพบสิ่งนี้อีกครั้งในบริการอื่น

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