IPIP ภายใน WireGuard: 20 ไบต์ส่วนเกินที่ไม่มีใครใส่ไว้ในงบประมาณ
IPIP มีค่าใช้จ่ายเพิ่มอีก 20 ไบต์ภายใน WireGuard จัดทำงบประมาณในชั้นที่ถูกต้องก่อนตำหนิการแบ่งส่วนสำหรับการถ่ายโอนที่ค้างบนอุโมงค์ที่ใช้งานอยู่
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 จะเลือกตัวเลขกลมใหม่และรับบั๊กของคุณไป
| Layer | Bytes | Remaining |
|---|---|---|
| Path MTU on the wired link | none yet | 1500 |
| WireGuard outer: IP, UDP, WG header | 60 | 1440 |
| Slack kept for safety | 20 | 1420 (wg0) |
| IPIP header inside the tunnel | 20 | 1400 (ipip0) |
| Original IPv4 and TCP headers | 40 | 1360 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 ออกอีกสิบไบต์