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

สามตัวเลขที่คนเรียกกันว่า MTU

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

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

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

ทดสอบเส้นทางด้วยเพย์โหลดที่คุณควบคุม

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

ping -M do -s 1372 -c 2 203.0.113.20
ping -4 -f -l 1372 vpn.example

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

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

IPv4 และ IPv6 แบ่งแพ็กเก็ตต่างกัน ผลทดสอบของตระกูลหนึ่งจึงไม่บอกอะไรเกี่ยวกับอีกตระกูล ทดสอบตระกูลที่แอปใช้จริง

การหนีบ MSS ช่วยได้แค่ TCP

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

iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
ip link show tun0

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

กับ UDP มันไม่ทำอะไรเลย ไคลเอนต์เสียงหรือเกมที่ส่งดาต้าแกรมขนาดใหญ่จะเพิกเฉยต่อการตั้งค่า MSS ทั้งหมด เพราะไม่มีการจับมือให้เขียนใหม่ ถ้าแอปที่ล้มเหลวเป็น UDP ให้ดูตัวเลือกขนาดแพ็กเก็ตของไคลเอนต์เองแทน สองโปรโตคอลล้มเหลวต่างกันและแก้ด้วยเครื่องมือต่างกัน ชื่อโปรโตคอลจึงควรอยู่ในประโยคแรกของตั๋ว

OpenVPN มีตัวเลือกอย่าง tun-mtu, mssfix และการตั้งค่าที่เกี่ยวกับการแบ่งแพ็กเก็ต และพฤติกรรมขึ้นกับเวอร์ชันและช่องข้อมูลว่าเป็น AEAD หรือไม่ อ่านคู่มือของเวอร์ชันที่ใช้ และเปลี่ยนทีละตัวเลือก

เปลี่ยนการตั้งค่าที่รองรับเพียงหนึ่งอย่างแล้วทำซ้ำทั้งสองรอบ

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

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

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

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