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

อาการที่ทำให้เห็นชัด

ปัญหาการแบ่งส่วนประกาศตัวเองด้วยขนาด ไม่เคยด้วยที่อยู่ peer ของคุณตอบ ping ไบต์ 56 เป็นเวลาหนึ่งชั่วโมงแล้วเงียบไปที่ 1400 ไบต์ในขณะที่อุโมงค์ยังขึ้นอยู่และไม่มีเส้นทางใดเปลี่ยนแปลง การจับมือผ่านได้ หน้าต่าง TCP เต็มหน้าแรกไม่ผ่าน และการถ่ายโอนหยุดชะงักไม่กี่วินาทีหลังจากดูเหมือนแข็งแรง

วัดเพดานก่อนที่คุณจะแก้ไขอะไร เพราะเพดานที่ไม่ได้วัดคือเพดานที่คุณจะไล่ตามสองครั้ง ส่ง probe หนึ่งตัวที่ต่ำกว่าขนาดที่สงสัยโดยตั้งบิต do-not-fragment ไว้ ping -M do -s 1000 10.9.0.2 แล้วทำซ้ำที่ขนาดที่คุณรู้อยู่แล้วว่าใหญ่เกินไป เมื่อการพลิกผันตามขนาดเพย์โหลดในขณะที่ปลายทางไม่เปลี่ยน แสดงว่าเราเตอร์กำลังทำหน้าที่ของมันและมีเฮดเดอร์หนึ่งตัวหายไปจากงบประมาณ

นับทุกเฮดเดอร์หนึ่งครั้ง ในชั้นที่ถูกต้อง

เริ่มจาก MTU ที่เล็กที่สุดบนเส้นทาง ไม่ใช่จากอินเทอร์เฟซของอุโมงค์ เพราะกำแพงอยู่เหนือกว่าปลายทั้งสอง WireGuard ใช้ 60 ไบต์กับทรานสปอร์ตภายนอก IPv4 โดยแบ่งเป็น 20 สำหรับ IP, 8 สำหรับ UDP และ 32 สำหรับเฮดเดอร์ของตัวเอง และ 80 ไบต์เมื่อทรานสปอร์ตนั้นเป็น IPv6 wg0 ขนาด 1420 ไบต์เก็บไบต์ว่าง 20 ไบต์ไว้ใต้ 1440 ที่เส้นทางขนาด 1500 ไบต์ส่งได้จริง และนั่นคือเหตุผลที่ตัวเลขที่คัดลอกมาจากวิกิยังใช้ได้ที่นี่ วาดสแต็กทั้งหมดลงในไดอะแกรม เพราะคนต่อไปที่เปลี่ยน MTU จะเลือกตัวเลขกลมใหม่และรับบั๊กของคุณไป

LayerBytesRemaining
Path MTU on the wired linknone yet1500
WireGuard outer: IP, UDP, WG header601440
Slack kept for safety201420 (wg0)
IPIP header inside the tunnel201400 (ipip0)
Original IPv4 and TCP headers401360 payload

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

ตั้งค่า MTU สองตัวแยกกัน

พาหะและอุปกรณ์ซ้อนเป็นวัตถุแยกกัน แต่ละตัวจึงต้องมีค่าของตัวเอง ใช้ตามลำดับนี้ เพราะอุปกรณ์ซ้อนไม่ได้รับอะไรจากพาหะเลย:

ip link set wg0 mtu 1420
ip tunnel add ipip0 mode ipip remote 203.0.113.9 local 198.51.100.4
ip link set ipip0 mtu 1400

กฎที่ควรจำ: MTU ชั้นใน = MTU ชั้นนอก - 20 เมื่อแพ็กเก็ตที่อุโมงค์ IPIP พาไปเป็น IPv4 และ - 40 ทันทีที่ด้านใดด้านหนึ่งของแพ็กเก็ตชั้นในเป็น IPv6 เพราะเฮดเดอร์ซ้อนโตจาก 20 ไบต์เป็น 40 ไม่มีอะไรอื่นอยู่ในผลลบนั้น ค่าใช้จ่ายของ WireGuard ถูกใช้ไปแล้วเมื่อคุณเลือก 1420 และการเรียกเก็บซ้ำจะสร้างอุโมงค์ที่ทำงานสมบูรณ์และยังช้าตราบใดที่ไม่มีใครวัดมัน การติดตั้งที่อุปกรณ์ทั้งสองพา 1400 กลม ๆ คือลายนิ้วมือของความผิดพลาดนั้น

IPv6 ที่ด้านใดด้านหนึ่งของแพ็กเก็ตซ้อนทำให้ตัวเลขทั้งหมดข้างต้นใช้ไม่ได้ ดังนั้นให้คำนวณใหม่แทนการคัดลอกตัวเลขจากไซต์ที่คล้ายกัน เฮดเดอร์ที่หักออกมีขนาด 40 ไบต์ต่ออันทันทีที่ IPv6 ปรากฏบนเส้นทางภายนอกหรือในดาต้าแกรมต้นฉบับ และตัวเลขเพย์โหลดลดลงเท่านั้นพอดี

กฎไฟร์วอลล์ที่คุณอาจไม่จำเป็นต้องใช้

ระหว่าง peer สองตัวของ WireGuard สิ่งเดียวที่อยู่บนสายคือ UDP กฎขาเข้าสำหรับโปรโตคอล 4 ซึ่งเป็นหมายเลขที่ RFC 2003 กำหนดให้กับการห่อหุ้ม IPv4-ใน-IPv4 จึงไม่สร้างเส้นทางซ้อนและไม่ทำให้มันคงอยู่ IPIP เฮดเดอร์อาศัยอยู่ในเพย์โหลดที่เข้ารหัส ซึ่งไม่มีไฟร์วอลล์ขอบใดเห็น การเปิดโปรโตคอล 4 ก็ไม่ได้ซื้ออะไรนอกจากทางที่ได้รับอนุญาตเพิ่มอีกหนึ่งทางเข้าสู่โฮสต์

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

สิ่งที่ WireGuard ตรวจสอบจริง ๆ

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

ตัวห่อให้โครงสร้างเส้นทาง ไม่ใช่ชั้นการเข้ารหัสชั้นที่สอง การเรียก IPIP ว่าการป้องกันเพิ่มเติมภายใน WireGuard คือการอธิบายการออกแบบที่แตกต่างออกไป

ตรวจสอบด้วยบันได ไม่ใช่ ping ครั้งเดียว

ทดสอบขนาดที่คร่อมขอบเขตที่คุณคำนวณไว้ แล้วยืนยันว่าเคอร์เนลคิดอย่างไรกับอุปกรณ์ทั้งสอง เมื่อ 1360 ไบต์เพย์โหลดบวก 40 ไบต์เฮดเดอร์รวมเป็น 1400 เสียงสะท้อนแรกด้านล่างผ่านได้ และตัวที่สองนั่งเลยเพดานไปหนึ่งไบต์:

ping -M do -s 1372 10.9.0.2
ping -M do -s 1373 10.9.0.2
wg show wg0
ip -d link show ipip0

การผ่านสะอาดใต้เพดานและการล้มเหลวที่ขนาดแรกเหนือเพดานหมายความว่าเลขคณิตคงอยู่ตั้งแต่ต้นจนจบ จากนั้นรันการถ่ายโอนที่เคยค้างอีกครั้ง เพราะ probe สังเคราะห์พิสูจน์งบประมาณและไม่ได้บอกอะไรเกี่ยวกับขนาดการเขียนของผู้ส่งเอง หากเส้นทางซ้อนยังแตกที่ขนาดที่คุณพิสูจน์แล้วว่าผ่าน ให้ตรวจสอบการถอดห่อหุ้มและเส้นทางของปลายทางไกลก่อนตัด MTU ออกอีกสิบไบต์

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