ขนส่งแพ็กเก็ตภายในขนาดคงที่ 1,500 ไบต์ผ่าน VPN
แพ็กเก็ตภายในคงที่ 1,500 ไบต์ไม่พอดีกับเส้นทางภายนอก 1,500 ไบต์ วัดโอเวอร์เฮดแล้วเลือก MTU ของ underlay ที่ใหญ่ขึ้นหรือแฟรกเมนเทชันที่รองรับ
คุณมีข้อกำหนดที่งอไม่ได้: ปลายทางต้องได้รับแพ็กเก็ต IP 1,500 ไบต์เดียวกับที่ผู้ส่งปล่อยออกมา รวมหัวข้อด้วย อุโมงค์ไม่สามารถห่อแพ็กเก็ตนั้นพร้อมเฟรมของตัวเองไว้ในแพ็กเก็ต IP 1,500 ไบต์ที่สองได้ ดังนั้นมีบางอย่างในดีไซน์ต้องยอม ลำดับด้านล่างคือลำดับที่ผมใช้ในหน้าต่างเปลี่ยนระบบ: เขียนงบไบต์ พิสูจน์ว่า underlay ขนอะไรได้จริง จากนั้นเลือกกลไกขนส่งเพียงหนึ่งเดียวและยืนยันแพ็กเก็ตภายในที่ปลายทาง
เขียนงบไบต์ก่อนแก้ไขโปรไฟล์
การห่อหุ้มเพิ่มไบต์ในหลายชั้น และผลรวมเป็นสมบัติของโปรไฟล์คุณ ไม่ใช่ค่าคงที่ที่ค้นหาได้ ตระกูลที่อยู่ การเลือกไซเฟอร์ โปรโตคอลขนส่ง และตัวเลือกการบีบอัดหรือเฟรมใด ๆ ล้วนเลื่อนตัวเลข ดังนั้นการลบที่คัดลอกจากระบบติดตั้งอื่นจึงไร้ค่าที่เป็นงบ เริ่มจากข้อกำหนดภายใน เพิ่มโอเวอร์เฮดต่อแพ็กเก็ตที่วัดได้ของการกำหนดค่าของคุณ แล้วเขียนขนาดภายนอกที่ได้ลงในตั๋วเปลี่ยนแปลงก่อนใครแก้ไฟล์
ตัวเลขสองตัวตัดสินดีไซน์: แพ็กเก็ตภายนอกที่ใหญ่ที่สุดที่เส้นทางขนได้โดยไม่แฟรกเมนต์ และไบต์เพิ่มเติมที่การห่อหุ้มของคุณต้องใช้ เมื่อตัวแรกน้อยกว่าตัวที่สองบวก 1,500 หนึ่งในสองต้องเปลี่ยน ทางเลือกจะแคบลงไม่ใช่สร้างสรรค์ ผมจึงเขียนตัวเลขทั้งสองก่อนคุยเรื่องทางเลือก ไม่มีอะไรในชั้นอุโมงค์บีบไบต์เหล่านั้นทิ้ง และไม่มีจำนวนเต็ม MTU ใดลบข้อกำหนดที่คุณได้รับ
ตรวจวัด underlay ด้วย ping do-not-fragment
วัดเส้นทางแทนที่จะเชื่อ MTU ของอินเทอร์เฟซ เพราะลิงก์ที่เล็กที่สุดในเส้นทางภายนอกคือสิ่งที่สำคัญ บน Linux, -M do ตั้งบิต do-not-fragment และ -s รับเพย์โหลด ICMP ดังนั้นเฟรม 1,500 ไบต์จะตอบด้วยเพย์โหลด 1,472 ไบต์เมื่อหักหัว IP 20 ไบต์และหัว ICMP 8 ไบต์ เพิ่มเพย์โหลดขึ้นจนกว่าการทดสอบจะล้มเหลว แล้วกระโดดไปที่ขนาด jumbo เพื่อดูว่าเส้นทางขนได้เลยหรือไม่
ping -M do -s 1472 -c 2 198.51.100.10 ping -M do -s 8972 -c 2 198.51.100.10 tracepath -n 198.51.100.10
เส้นทางที่ผ่าน 1,472 และล้มเหลวที่ 8,972 ไม่สามารถขนแพ็กเก็ตภายใน 1,500 ไบต์บวกโอเวอร์เฮดในแพ็กเก็ตภายนอกเดียวได้ นั่นคือคำตอบที่คุณต้องการก่อนเปิดการกำหนดค่า VPN มันยังตัดสินว่าสองหัวข้อถัดไปหัวข้อใดใช้กับคุณ จึงเก็บผลทดสอบทั้งสองไว้ข้างตั๋ว การเดาที่นี่มีต้นทุนเป็นหน้าต่างบำรุงรักษาหนึ่งครั้ง เพราะอุโมงค์ที่รายงานตัวเองว่า up ไม่ได้บอกอะไรเกี่ยวกับแพ็กเก็ตที่ใหญ่ที่สุดที่เส้นทางจะรับ
เพิ่ม MTU ของเส้นทางเฉพาะที่ทุกฮอปเห็นด้วย
เฟรม jumbo เป็นสมบัติแบบ end-to-endไม่ใช่การตั้งค่าที่คุณเปิดบนปลายทางสองจุดที่คุณบังเอิญควบคุม สวิตช์ เราเตอร์ และจุดส่งมอบของผู้ให้บริการทุกจุดบนเส้นทางภายนอกต้องเห็นด้วยกับขนาดที่ใหญ่ขึ้น และฮอป 1,500 ไบต์เพียงจุดเดียวจะทิ้งแพ็กเก็ตที่คุณเพิ่งขยายอย่างเงียบ ๆ การเพิ่มเฉพาะอินเทอร์เฟซท้องถิ่นคือการเปลี่ยนแปลงครึ่ง ๆ แบบคลาสสิกที่ทำให้อุโมงค์ดูพังขณะที่ underlay ทิ้งไปอย่างเงียบ ๆ
ip link set dev eth1 mtu 9000 ip link show dev eth1 ping -M do -s 8972 -c 2 198.51.100.10
เปลี่ยนอินเทอร์เฟซ แล้วทดสอบเส้นทางเดิมซ้ำก่อนเปลี่ยนอย่างอื่น หากการทดสอบยังล้มเหลว ให้ย้อนกลับด้วย ip link set dev eth1 mtu 1500 และไปที่แฟรกเมนเทชันแทนที่จะเถียงกับผู้ให้บริการเรื่องลิงก์ที่ไม่ใช่ของคุณ
ใช้แฟรกเมนเทชันของอุโมงค์เมื่อ underlay ขยายไม่ได้
กลไกแฟรกเมนเทชันที่รองรับใต้แพ็กเก็ตภายในทำให้แพ็กเก็ตภายนอกหลายแพ็กเก็ตขนแพ็กเก็ตภายในหนึ่งแพ็กเก็ต และปลายอุโมงค์ฝั่งตรงข้ามประกอบกลับก่อนส่งต้นฉบับให้สแตก ตัวเลือก UDP fragment ของ Community OpenVPN เป็นการนำแนวคิดนั้นไปใช้แบบหนึ่ง และไม่ใช่สิ่งเดียวกับการแฟรกเมนต์ IP ปกติของแพ็กเก็ตภายนอก peer ทั้งสองต้องรันเวอร์ชันที่รองรับรูปแบบนี้ และเส้นทางข้อมูลต้องเป็นเส้นทางที่คุณคิด: ไคลเอนต์ OpenVPN 3 และช่องข้อมูลที่เร่งด้วยเคอร์เนลมีขีดจำกัดต่างกัน โปรไฟล์ที่ทำงานบนไคลเอนต์หนึ่งจึงอาจล้มเหลวบนอีกตัว
openvpn --config client.ovpn --tun-mtu 1500 --fragment 1400 --verb 4
การแฟรกเมนต์ภายนอกแบบปกติเป็นอีกทางเลือก และเป็นทางที่อ่อนกว่า เราเตอร์ IPv6 ไม่แฟรกเมนต์แพ็กเก็ตที่ส่งต่อเลย แพ็กเก็ตภายนอกที่ใหญ่เกินจึงตายไปเฉย ๆ และผู้ส่งรู้ก็ต่อเมื่อข้อความ ICMPv6 ที่เกี่ยวข้องรอดผ่านเส้นทางมาได้ แฟรกเมนต์ยังเชิญการกรองและการขยายการสูญเสีย ผมจึงถือว่านี่เป็นทางสำรองไม่ใช่แผน
ตัวขนส่งภายนอกแบบสตรีมเลี่ยงคำถามเรื่องขนาดด้วยการแบ่งสตรีมไบต์ของตัวเอง และแพ็กเก็ตภายในที่ประกอบกลับยังเป็น 1,500 ไบต์ได้ นี่เป็นการตัดสินใจด้านการขนส่งที่มีต้นทุนของตัวเอง รวมถึงพฤติกรรม TCP ซ้อน TCP ที่รู้จักกันดี จึงควรเลือกอย่างตั้งใจไม่ใช่ผลข้างเคียงของการเถียงเรื่อง MTU
ยืนยันว่าแพ็กเก็ตภายในมาถึงโดยไม่เปลี่ยน
การตรวจสอบไม่ใช่แฮนด์เชกที่สำเร็จ ดักจับบนอินเทอร์เฟซอุโมงค์ที่ทั้งสองปลาย และเปรียบเทียบขนาดและเนื้อหาของแพ็กเก็ตที่แอปพลิเคชันส่งจริงกับสิ่งที่ปลายทางได้รับ
ip link show dev tun0 ping -M do -s 1472 -c 2 10.8.0.1 tcpdump -ni tun0 -c 5 'icmp and greater 1000'
หากการดักจับแสดงแพ็กเก็ตภายในขนาดเต็มที่ปลายอีกด้าน ทางเลือกการขนส่งใช้ได้ และงานที่เหลือคือบันทึกไว้ หากไม่แสดงอะไรเลยขณะที่อุโมงค์รายงานว่า up แพ็กเก็ตภายนอกกำลังถูกทิ้งที่ใดที่หนึ่งระหว่างปลายทาง ซึ่งส่งคุณกลับไปที่การทดสอบไม่ใช่การตั้งค่าไซเฟอร์
บันทึกสามอย่างลงในตั๋วเปลี่ยนแปลงก่อนปิด: งบภายนอกที่วัดได้ กลไกที่เลือก และคำสั่งที่พิสูจน์ว่าแพ็กเก็ตภายในรอด คนถัดไปที่แตะอุโมงค์นี้จะต้องใช้ทั้งสามอย่าง และไม่มีสิ่งใดสร้างกลับได้จากไฟล์กำหนดค่าเพียงอย่างเดียว