Những lầm tưởng về MTU của VPN: vì sao gói tin của bạn nhỏ lại và chỗ trống đi đâu
Đóng gói và PPPoE ăn mất chỗ của gói tin, nhưng MTU thấp hơn không phải là chẩn đoán. Hãy tách kích thước trong và ngoài trước khi đổi một con số.
Ai đó nói với bạn rằng VPN "đang mất gói vì MTU", bạn đặt đường hầm thành 1400, và việc truyền lại hoạt động. Kết quả đó có cảm giác như một chẩn đoán. Thường thì đó là một sự trùng hợp số học: bạn chọn một con số đủ nhỏ để nằm dưới một giới hạn mà bạn chưa bao giờ xác định, và bạn sẽ gặp lại đúng giới hạn đó ở mạng tiếp theo với một ngân sách khác.
Hai lầm tưởng gây ra phần lớn điều này. Thứ nhất là MTU của giao diện đường hầm chính là MTU của đường đi. Thứ hai là đóng gói tốn "một tiêu đề" và PPPoE không tốn gì đáng để đếm. Cả hai đều sai theo cách khiến con số bạn chọn trông tùy tiện trong khi thực ra nó đã được xác định.
Lầm tưởng một: MTU của đường hầm là MTU của đường đi
Giá trị bạn đặt trên giao diện đường hầm là một lời hứa cục bộ về gói bên trong lớn nhất mà bản triển khai sẽ chuyển xuống dưới. Dung lượng thực của đường đi là thuộc tính của từng liên kết giữa bạn và đầu xa, và nó có thể thay đổi khi tuyến thay đổi, khi một kết nối di động chuyển giao hoặc khi lưu lượng đi qua một peering khác. Một 1500 được cấu hình cho bạn biết máy chủ của bạn sẽ dựng gì, không phải mạng sẽ chở gì.
Việc dò MTU đường đi tồn tại để dung hòa hai điều đó, và nó phụ thuộc vào phản hồi. Với IPv4, một bộ định tuyến không thể chuyển tiếp gói kích thước đầy đủ phải gửi thông điệp ICMP "fragmentation needed", và bên gửi hạ thấp ước lượng của mình. Với IPv6, tương đương là thông điệp Packet Too Big, và các bộ định tuyến hoàn toàn không phân mảnh trên đường truyền. Khi phản hồi đó bị lọc, bên gửi tiếp tục tạo ra các gói mà đường đi không thể chở, và không gì nói cho nó biết vì sao.
Lầm tưởng hai: đóng gói tốn một tiêu đề
Đếm các lớp bên ngoài một cách trung thực. Tiêu đề IP bên ngoài là 20 byte với IPv4 hoặc 40 với IPv6. Đóng gói UDP để xuyên NAT thêm 8. Giao thức đường hầm thêm tiêu đề riêng, một vectơ khởi tạo hoặc nonce, phần đệm đến ranh giới khối hoặc căn lề của mã hóa, một phần đuôi và một giá trị kiểm tra toàn vẹn. Tùy giao thức và mã hóa, tổng cộng nằm thoải mái trong hàng chục byte trước khi gói bên trong bắt đầu.
Sau đó trừ tiếp các tiêu đề của chính gói bên trong. Một phân đoạn TCP bên trong đường hầm mang tiêu đề IP 20 byte và tiêu đề TCP 20 byte của riêng nó, và MSS của TCP được suy ra từ MTU, không phải từ tải trọng danh nghĩa của đường hầm. Đó là lý do ping với tải trọng nhỏ hơn có thể thành công trong khi việc truyền tệp bị đình trệ: các công cụ kiểm tra những thứ khác nhau, và chỉ một trong số chúng thực sự dùng một phân đoạn TCP kích thước đầy đủ.
ip link show tun0
ping -M do -s 1472 192.0.2.10
ping -M do -s 1400 192.0.2.10
Lệnh đầu tiên báo cáo MTU đường hầm đã đặt. Hai phép thử gửi tải trọng 1472 byte, cùng với 28 byte tiêu đề IPv4 và ICMP là một gói 1500 byte, rồi một gói nhỏ hơn. Nếu phép thử lớn thất bại hoàn toàn và phép thử nhỏ thành công, bạn có một lỗi phụ thuộc kích thước chứ không phải vấn đề định tuyến chung.
Lầm tưởng ba: PPPoE vẫn cho bạn 1500 sạch
Một liên kết truy cập PPPoE thông thường không chở gói IP 1500 byte. Tiêu đề PPPoE cùng trường giao thức PPP chiếm 8 byte bên trong khung Ethernet, để lại 1492 cho gói IP. Đó là giới hạn truyền thống được mô tả trong RFC 2516. Nếu bạn chạy VPN trên một liên kết như vậy, chi phí phụ của đường hầm đến từ 1492 đó, không phải từ 1500.
RFC 4638 định nghĩa một cách thương lượng tải trọng PPP lớn hơn khi cả bộ tập trung truy cập và thiết bị của khách hàng đều hỗ trợ, vì thế "kết nối này dùng PPPoE" tự nó không chứng minh một con số cụ thể. Một thiết lập cục bộ không thể buộc một thiết bị trung gian chấp nhận một gói mà nó chưa bao giờ được cấu hình cho, nên câu hỏi hữu ích là liên kết thực sự đã thương lượng điều gì, không phải nhãn nói gì.
Vì sao sự cố trông có vẻ chọn lọc
Việc các yêu cầu nhỏ thành công và các lần truyền lớn bị đình trệ là dấu hiệu kinh điển của một hố đen MTU đường đi. Bắt tay, truy vấn DNS và lệnh gọi API đều vừa; việc truyền hàng loạt tạo ra các phân đoạn kích thước đầy đủ chết ở một liên kết, và thông điệp ICMP đáng lẽ phải báo cáo vấn đề thì không bao giờ đến. Kết nối trông ổn và bản tải treo, khiến người ta nhìn vào máy chủ thay vì đường đi.
Một sai lầm thứ hai, có liên quan, là lẫn lộn ba con số: MTU của giao diện, MSS của TCP và thiết lập phân mảnh hoặc đệm của chính giao thức. Việc kẹp MSS trên bộ định tuyến ghi lại MSS được quảng bá để bên gửi dựng các phân đoạn nhỏ hơn; nó không đổi MTU của đường hầm và không giúp lưu lượng UDP. Gán cùng một con số cho cả ba vì chúng có vẻ liên quan là cách một thay đổi thiện chí phá hỏng một cấu hình đang chạy tốt.
Đổi gì, và theo thứ tự nào
Hãy bắt đầu bằng bằng chứng. Xác nhận bằng các phép thử ở trên rằng sự cố phụ thuộc kích thước, rồi tìm kích thước nhỏ nhất đi qua và lớn nhất thất bại. Kiểm tra MTU thực của liên kết truy cập trước khi đổ lỗi cho đường hầm; một liên kết PPPoE giới hạn ngân sách trước khi VPN của bạn chạm vào nó. Ghi lại các giá trị ban đầu để có thể hoàn tác thay đổi.
Sau đó áp dụng điều chỉnh nhỏ nhất mà ứng dụng khách ghi nhận. Nhiều ứng dụng khách cung cấp MTU đường hầm cùng tùy chọn sửa MSS, và tùy chọn MSS thường là đòn bẩy tốt hơn cho TCP vì nó đến được bên gửi mà không thu nhỏ từng gói. Thử lại cùng đích và cùng kiểu truyền, và ghi lại các con số bạn chốt. Một giá trị đường hầm chạy được trên một mạng truy cập không phải hằng số phổ quát, và địa điểm tiếp theo sẽ có ngân sách riêng.