Thông thường, phát hiện đơn vị truyền tối đa đường dẫn (PMTUD) xảy ra bất cứ khi nào máy chủ nghĩ rằng gói bị bỏ do quá lớn.
Điều này có thể là để đáp ứng với phân mảnh ICMP cần thiết (loại 3, mã 4) phản hồi rõ ràng cho thấy gói bị bỏ. Trong thực tế điển hình, tất cả các gói IPv4 được đặt với cờ "không phân đoạn" (DF), do đó, bất kỳ gói nào vượt quá MTU sẽ gợi ra phản hồi như vậy. IPv6 hoàn toàn không hỗ trợ phân mảnh.
Một số bộ định tuyến hoặc tường lửa máy chủ bỏ tất cả ICMP thường xuyên vì một quản trị viên ngây thơ tin rằng ICMP là một rủi ro bảo mật . Hoặc, một số sơ đồ tổng hợp liên kết có thể phá vỡ phân phối ICMP . Một cơ chế thay thế để khám phá MTU đã bị vượt quá, không phụ thuộc vào ICMP được đề xuất trong RFC4821 .
tracepath
là công cụ Linux yêu thích của tôi để thăm dò MTU. Dưới đây là ví dụ từ máy chủ có MTU 9001 trên mạng LAN, nhưng phải đi qua VPN IPsec để đạt 10.33.32.157:
$ tracepath -n 10.33.32.157
1?: [LOCALHOST] pmtu 9001
1: 10.1.22.1 0.122ms pmtu 1500
1: 169.254.3.1 1.343ms pmtu 1422
1: 10.255.254.61 23.790ms
2: no reply
^C [this host won't return an ICMP port unreachable, so tracepath won't terminate]
Các lỗi ICMP có thể được quan sát với tcpdump
:
$ sudo tcpdump -p -ni eth0 'icmp and icmp[0] == 3 and icmp[1] == 4'
14:46:57.313690 IP 10.1.22.1 > 10.1.22.194: ICMP 10.33.32.157 unreachable - need to frag (mtu 1500), length 36
14:46:57.315080 IP 169.254.3.1 > 10.1.22.194: ICMP 10.33.32.157 unreachable - need to frag (mtu 1422), length 556
Khám phá MTU được lưu trữ. Trong Linux, điều này có thể được quan sát và xóa sạch ip
(hãy cẩn thận với những thay đổi kể từ Linux 3.6 ):
$ ip route get 10.33.32.157
10.33.32.157 via 10.1.22.1 dev eth0 src 10.1.22.194
cache expires 591sec mtu 1422
$ sudo ip route flush cache
$ ip route get 10.33.32.157
10.33.32.157 via 10.1.22.1 dev eth0 src 10.1.22.194
cache
Đối với TCP, vượt quá MTU có thể tránh được như là một phần của thiết lập kết nối. Bao gồm trong SYN được gửi bởi mỗi đầu là kích thước phân đoạn tối đa (MSS). Tiêu đề TCP (20 byte không bao gồm tùy chọn ) và tiêu đề IP (20 byte) có nghĩa là MSS và MTU có liên quan bởi sự khác biệt 40 byte.
Dưới đây là ví dụ về thiết lập kết nối giữa hai máy chủ này khi truyền tệp lớn với scp
:
$ sudo tcpdump -p -ni eth0 'host 10.33.32.157 and tcp[13]&2 == 2'
IP 10.1.22.194.45853 > 10.33.32.157.22: Flags [S], seq 634040018, win 26883, options [mss 8961,sackOK,TS val 10952240 ecr 0,nop,wscale 7], length 0
IP 10.33.32.157.22 > 10.1.22.194.45853: Flags [S.], seq 1371736848, ack 634040019, win 26847, options [mss 1379,sackOK,TS val 10824267 ecr 10952240,nop,wscale 7], length 0
Trong gói đầu tiên, máy chủ lưu trữ cục bộ đề xuất MSS là 8961. Đây là MTU 9001 được cấu hình, ít hơn 40 byte. SYN / ACK được trả về có MSS là 1379, ngụ ý MTU là 1419. Tôi tình cờ biết trong mạng này máy chủ từ xa cũng đã gửi 8961, nhưng giá trị đã được sửa đổi bởi bộ định tuyến vì nó biết đường dẫn bao gồm đường dẫn internet ( MTU 1500) một chi phí từ một đường hầm IPsec. Bộ định tuyến này cũng đã sửa đổi MSS gửi 8961 của chúng tôi để xuất hiện là 1419 tại máy chủ khác. Điều này được gọi là kẹp MSS .
Vì vậy, theo một nghĩa nào đó, PMTUD đang diễn ra mọi lúc. Trong thực tế, điều đó thực sự có thể xảy ra, nếu kẹp MSS được đặt đúng chỗ và tất cả lưu lượng truy cập xảy ra trên TCP hoặc nếu không có bộ định tuyến nào có MTU nhỏ hơn cấu hình trên các điểm cuối. Ngay cả khi không có MSS kẹp, nó chỉ có thể xảy ra hiếm khi, khi bộ đệm hết hạn.