굽히지 않는 요구 사항이 있다. 송신 측이 내보내는 것과 동일한 1,500바이트 IP 패킷을 헤더까지 포함해 반대편이 받아야 한다. 터널은 그 패킷과 자신의 프레이밍을 두 번째 1,500바이트 IP 패킷 안에 넣을 수 없으므로 설계 어딘가가 양보해야 한다. 아래 순서는 내가 변경 창에서 쓰는 순서다. 바이트 예산을 쓰고, 언더레이가 실제로 무엇을 실을 수 있는지 증명하고, 정확히 하나의 전달 방식을 골라 반대편에서 내부 패킷을 확인한다.

프로파일을 편집하기 전에 바이트 예산을 쓰라

캡슐화는 여러 계층에서 바이트를 더하며, 그 합계는 찾아볼 수 있는 상수가 아니라 당신 프로파일의 속성이다. 주소 체계, 암호 선택, 전송 프로토콜, 그리고 어떤 압축이나 프레이밍 옵션이든 숫자를 움직이므로 다른 구축에서 복사한 뺄셈은 예산으로 쓸모가 없다. 내부 요구에서 시작해 자기 구성의 측정된 패킷당 오버헤드를 더하고, 누군가 파일을 편집하기 전에 결과 외부 크기를 변경 티켓에 적는다.

두 숫자가 설계를 결정한다. 경로가 단편화 없이 나르는 가장 큰 외부 패킷과, 캡슐화가 필요로 하는 추가 바이트다. 앞의 것이 뒤의 것에 1,500을 더한 값보다 작으면 둘 중 하나는 바뀌어야 한다. 그러면 선택은 창의적이 아니라 좁아지므로, 나는 옵션을 논의하기 전에 두 숫자를 모두 적는다. 터널 계층에서 그 바이트를 압축해 없애 주는 것은 없고, 어떤 단일 MTU 정수도 당신이 받은 요구를 없애지 못한다.

do-not-fragment ping으로 언더레이를 조사하라

인터페이스 MTU를 믿지 말고 경로를 측정하라. 외부 경로에서 가장 작은 링크가 중요하기 때문이다. Linux에서는, -M do 가 do-not-fragment 비트를 설정하고 -s 가 ICMP 페이로드를 지정하므로, 20바이트 IP 헤더와 8바이트 ICMP 헤더를 빼면 1,500바이트 프레임이 1,472바이트 페이로드로 응답한다. 조사가 실패할 때까지 페이로드를 올리고, 다음에 점보 크기로 뛰어 경로가 그것을 아예 나르는지 보라.

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를 올려라

점보 프레임은 end-to-end 속성이다, 당신이 우연히 통제하는 두 엔드포인트에서 켜는 설정이 아니다. 외부 경로의 모든 스위치, 라우터, 제공자 인계 지점이 더 큰 크기에 동의해야 하며, 1,500바이트 홉 하나만 있어도 방금 키운 패킷을 조용히 버린다. 로컬 인터페이스만 올리는 것은 터널이 고장 난 것처럼 보이게 하면서 언더레이가 조용히 떨어뜨리는 전형적인 반쪽 변경이다.

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 그리고 당신 소유가 아닌 링크를 두고 제공자와 다투는 대신 단편화로 넘어가라.

언더레이가 커질 수 없을 때 터널 단편화를 사용하라

내부 패킷 아래에서 지원되는 단편화 메커니즘은 여러 외부 패킷이 하나의 내부 패킷을 나르게 하고, 반대편 터널 엔드포인트는 원본을 스택에 넘기기 전에 그것들을 재조립한다. Community OpenVPN의 UDP fragment 옵션 은 그 아이디어의 한 구현이며, 외부 패킷의 보통 IP 단편화와 같은 것이 아니다. 양쪽 피어가 그 형식을 지원하는 버전을 실행해야 하고, 데이터 경로도 당신이 생각하는 그 경로여야 한다. 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이라고 보고하는데 아무것도 보이지 않으면 외부 패킷이 엔드포인트 사이 어딘가에서 버려지고 있는 것이므로, 암호 설정이 아니라 조사로 돌아가야 한다.

티켓을 닫기 전에 세 가지를 기록하라. 측정된 외부 예산, 선택한 메커니즘, 내부 패킷이 살아남았음을 증명한 명령이다. 다음에 이 터널을 만지는 사람은 세 가지 모두 필요하며, 그중 어느 것도 구성 파일만으로는 재구성할 수 없다.

관련 글