관리 메뉴

피터의 개발이야기

[Network] 20. 가장 좁은 길의 크기를 출발지에서 어떻게 알 수 있을까? 본문

DevOps/Network

[Network] 20. 가장 좁은 길의 크기를 출발지에서 어떻게 알 수 있을까?

기록하는 백엔드개발자 2026. 7. 22. 22:20
반응형

목차: [Network] TCP/IP를 우편 시스템으로 이해하기
TCP/IP를 우편 시스템으로 이해하기 — Part 6. 너무 큰 소포와 좁은 길의 문제

ㅁ 들어가며

Source는 자신이 연결된 첫 Link의 MTU를 알 수 있다.

하지만 Destination까지 이어지는 모든 Link의 MTU를 처음부터 알고 있지는 않다.

Source ── 1500 ── R1 ── 1400 ── R2 ── 1280 ── Destination

이 경로에서 단편화 없이 보낼 수 있는 최대 IP Packet은 1280바이트다.

그렇다고 Source가 통신을 시작할 때 모든 Router에 전화를 걸어 MTU를 조사하는 것은 아니다.

Route가 바뀌면 가장 좁은 Link도 달라질 수 있다.

Source는 Packet을 보내고, 전달할 수 없는 Router가 돌려주는 제어 메시지를 단서로 크기를 조절한다.

이 과정이 Path MTU Discovery(PMTUD)다.

문제는 “너무 크다”는 안내가 돌아오지 않을 때 생긴다.

TCP Handshake 성공
작은 요청 성공
큰 Data Packet은 Drop
ICMP 안내도 Drop

→ 연결은 살아 있는 것처럼 보이지만 Data가 멈춤

 

이번 글에서는

Path MTU, ICMP Fragmentation Needed, ICMPv6 Packet Too Big,

PMTU Cache, MTU Black Hole, MSS Clamping, Packetization Layer PMTUD(PLPMTUD)를

하나의 전달 과정으로 연결한다.


ㅁ Link MTU와 Path MTU는 무엇이 다를까?

Link MTU는 하나의 Link에서 단편화 없이 운반할 수 있는 IP Packet 크기다.

Path MTU는 Source에서 Destination으로 가는 한 방향 경로에 있는 Link MTU 중 가장 작은 값이다.

Link MTU
→ 한 구간의 한계

Path MTU
→ 경로 전체의 최소 한계

 

다음 경로를 보자.

Source
  │ MTU 1500
  ▼
R1
  │ MTU 1450
  ▼
R2
  │ MTU 1280
  ▼
Destination

 

계산은 단순하다.

PMTU = min(1500, 1450, 1280)
     = 1280

 

하지만 실제 인터넷에서는 Source가 이 목록을 직접 가지고 있지 않다.

Forward Path와 Return Path가 다를 수도 있으므로 반대 방향 PMTU도 같다고 보장할 수 없다.

A → B PMTU = 1280
B → A PMTU = 1500

PMTU는 두 Host 사이의 영구적인 고정 속성이 아니라 특정 방향과 현재 경로에 대한 상태다.


ㅁ IPv4 PMTUD는 왜 DF Flag를 사용할까?

IPv4 Router가 큰 Packet을 자동으로 Fragmentation하면 Source는 경로가 좁다는 사실을 모른 채 계속 큰 Packet을 보낼 수 있다.

중간 Fragmentation을 피하려면 Source가 IPv4 Packet에 Don't Fragment(DF) Flag를 설정한다.

Source가 DF=1 Packet 전송
        ↓
Router의 Outgoing MTU 안에 들어감
        ↓
계속 전달

 

어느 Router에서 Packet이 Outgoing MTU보다 커지면 조건이 달라진다.

Packet Length: 1500
Outgoing MTU : 1400
DF           : 1

→ Router가 Fragmentation할 수 없음
→ Packet Drop
→ Source에 ICMP 오류 전송 가능

 

DF는 단순히 “조각내지 마라”는 금지 표시에 그치지 않는다.

큰 Packet을 그대로 보내 보고, 지나갈 수 없는 지점에서 명시적인 오류를 받게 만들어 Source가 경로의 한계를 학습하도록 돕는다.


ㅁ Router는 너무 크다는 사실을 어떻게 알릴까?

IPv4 Router는 DF가 설정된 큰 Packet을 전달할 수 없을 때 일반적으로 다음 ICMP 메시지를 만든다.

ICMP Destination Unreachable
Type 3
Code 4
Fragmentation Needed and DF Set

 

현대적인 형식의 메시지에는 다음 Hop이 받아들일 수 있는 MTU, 즉 Next-Hop MTU가 포함될 수 있다.

Router → Source

이 Packet은 1500바이트다.
다음 Link는 1400바이트까지만 전달할 수 있다.
더 작게 만들어 다시 보내라.

 

ICMP 오류에는 문제가 된 원래 IP Header와 상위 계층을 식별할 수 있는 원래 Packet의 일부가 인용된다.

Source는 인용된 주소와 Protocol, Port 등의 정보를 이용해 어느 통신에 대한 오류인지 연결할 수 있다.

ICMP 메시지도 새로운 IP Packet이므로 Source로 돌아오는 Route와 정책이 필요하다.


ㅁ Source는 ICMP를 받으면 무엇을 바꿀까?

Source가 Next-Hop MTU 1400이라는 ICMP를 받았다고 하자.

운영체제는 해당 Destination 또는 Route와 관련된 PMTU 상태를 갱신할 수 있다.

기존 추정 PMTU: 1500
ICMP가 알린 MTU: 1400
새 추정 PMTU  : 1400

TCP라면 IP Packet 전체가 새 PMTU 안에 들어가도록 Segment의 Data 크기를 줄인다.

IPv4 Header 20바이트, TCP Header 20바이트만 있다고 가정하면 다음과 같다.

PMTU 1400
- IPv4 Header 20
- TCP Header 20
= TCP Data 최대 1360바이트

 

Header Option이 있으면 한 Packet에 넣을 Data는 더 작아질 수 있다.

큰 TCP Segment 재전송
→ PMTU에 맞는 더 작은 IP Packet
→ 중간 Fragmentation 없이 전달

 

PMTUD는 Application의 File 크기를 줄이는 과정이 아니다.

같은 Byte Stream을 더 작은 Packet 단위로 나누어 보내는 과정이다.


ㅁ ICMP 하나를 받으면 경로의 모든 MTU를 알게 될까?

한 번의 오류는 현재 막힌 Link의 한계를 알려 줄 뿐이다.

경로 뒤에 더 좁은 Link가 있을 수 있다.

처음 Packet 1500
→ MTU 1400 Link에서 Drop
→ PMTU를 1400으로 낮춤

다시 Packet 1400
→ MTU 1280 Link에서 Drop
→ PMTU를 1280으로 낮춤

 

Source는 오류를 받을 때마다 추정치를 더 낮출 수 있다.

따라서 PMTUD는 모든 Link를 먼저 열람해 정답을 한 번에 얻는 절차가 아니다.

보냄
→ 너무 크다는 응답
→ 크기를 줄임
→ 다시 보냄
→ 전달 가능한 크기에 도달

 

경로가 바뀌거나 PMTU 상태의 유효 시간이 지나면 운영체제가 다시 더 큰 크기를 탐색할 수 있다.


ㅁ PMTU Cache는 왜 영원히 믿을 수 없을까?

매 Packet마다 처음부터 크기를 다시 찾으면 비효율적이다.

운영체제는 발견한 PMTU를 Destination이나 Route 상태와 연관해 일정 시간 기억할 수 있다.

이를 PMTU Cache라고 부른다.

Destination A → PMTU 1500
Destination B → PMTU 1280
Destination C → PMTU 1420

 

하지만 인터넷 Route는 변한다.

이전 경로: 최소 MTU 1280
새 경로  : 최소 MTU 1500

오래된 작은 값만 영원히 사용하면 전달은 되더라도 필요 이상으로 작은 Packet을 계속 보내 효율이 떨어진다.

반대로 새 경로가 더 좁아졌는데 오래된 큰 값을 믿으면 다시 ICMP 오류나 손실을 만난다.

그래서 PMTU 정보는 구현별 유효 시간과 재검증 과정을 가진 동적인 추정값이다.

Cache의 범위와 갱신 방식은 운영체제마다 다를 수 있다.


ㅁ TCP MSS와 PMTU는 같은 값일까?

둘은 관련 있지만 같은 계층의 값은 아니다.

PMTU
→ 경로가 허용하는 IP Packet 전체 크기

MSS
→ TCP Segment에 담을 Data의 최대 크기

TCP Endpoint는 Handshake의 MSS Option으로 자신이 받을 수 있는 TCP Data 크기를 상대에게 알린다.

Server SYN-ACK: MSS=1460

이는 Server 쪽 Interface 조건을 반영할 수 있지만, 경로 중간의 Tunnel이나 더 작은 Link를 모두 알고 광고한 값이라고 보장할 수 없다.

상대가 광고한 MSS: 1460
중간 경로 PMTU   : 1280
IPv4/TCP 기본 Header 기준 안전한 Data: 1240

Sender는 상대 MSS와 자신이 발견한 PMTU, Header 크기 등을 함께 고려해야 한다.

Handshake가 끝난 뒤 PMTU가 더 작다는 사실을 발견해도 기존 TCP 연결은 더 작은 Segment로 조정할 수 있다. MSS Option을 다시 협상하는 새 Handshake가 필요한 것은 아니다.


ㅁ 왜 TCP Handshake는 되는데 큰 Data만 멈출까?

TCP SYN과 순수 ACK는 Payload가 거의 없어서 IP Packet도 작다.

SYN        : 작은 Packet → 통과
SYN-ACK    : 작은 Packet → 통과
ACK        : 작은 Packet → 통과

큰 Data Segment: PMTU 초과 → Drop

 

따라서 3-Way Handshake 성공은 큰 Packet도 전달된다는 증거가 아니다.

예를 들어 다음 현상이 나타날 수 있다.

  • SSH Login과 짧은 명령은 되지만 큰 출력에서 멈춤
  • 작은 HTTP 응답은 되지만 큰 응답이나 Upload가 정체됨
  • TLS 연결 중 작은 ClientHello는 가지만 큰 인증서 메시지 부근에서 멈춤
  • VPN 연결 후 일부 Site만 열리지 않음
  • ping 기본 크기는 성공하지만 큰 DF Probe는 실패

Application 문제처럼 보이지만 Packet 크기 경계가 원인일 수 있다.


ㅁ MTU Black Hole은 어떻게 만들어질까?

다음 경로를 생각해 보자.

Source ── MTU 1500 ── Router ── MTU 1200 ── Destination

Source가 1500바이트 DF Packet을 보낸다.

Router는 1200바이트 Link로 내보낼 수 없어 Packet을 버리고 ICMP Fragmentation Needed를 만든다.

 

그런데 Firewall이 ICMP Type 3 Code 4를 차단한다.

Source → Router : 큰 DF Packet
Router          : Packet Drop
Router → Source : ICMP Fragmentation Needed
Firewall        : ICMP Drop

 

Source가 보는 장면은 단순하다.

Packet을 보냈다.
ACK가 오지 않는다.
왜 사라졌는지는 모른다.
같은 크기로 재전송한다.
다시 사라진다.

명시적인 오류도 없고 Data도 앞으로 가지 않는 경로를 PMTU Black Hole 또는 MTU Black Hole이라고 한다.

“ICMP는 ping에만 쓰이니 모두 막아도 된다”는 정책이 정상 TCP 전달을 깨뜨릴 수 있는 대표적인 이유다.


ㅁ 모든 ICMP를 무조건 허용해야 할까?

ICMP가 PMTUD에 필요하다는 사실과 모든 ICMP Packet을 아무 검증 없이 신뢰해야 한다는 말은 다르다.

가짜 ICMP 오류로 PMTU를 불필요하게 낮추려는 입력도 생각할 수 있다.

Host와 Firewall은 다음 정보를 이용해 ICMP 오류가 실제 Flow와 관련되는지 검증할 수 있다.

  • ICMP에 인용된 원래 Source와 Destination
  • 원래 IP Protocol
  • 인용된 TCP 또는 UDP Port와 Sequence 관련 정보
  • 현재 연결과 Route 상태

네트워크 정책은 필요한 ICMP 오류 종류를 허용하면서 Rate Limiting과 Stateful Validation을 적용할 수 있다.

핵심은 다음 두 극단을 피하는 것이다.

ICMP는 위험하니 전부 Drop       (X)
ICMP라고 표시되면 전부 무조건 신뢰 (X)

정상 전달에 필요한 Control Plane 메시지의 역할과 검증 범위를 함께 설계해야 한다.


ㅁ IPv6 PMTUD는 무엇이 다를까?

IPv6 Router는 지나치게 큰 Packet을 중간에서 Fragmentation하지 않는다.

Outgoing Link로 전달할 수 없으면 Packet을 버리고 Source에 다음 메시지를 보낸다.

ICMPv6 Packet Too Big
Type 2, Code 0
MTU 값 포함

Source는 알려진 MTU에 맞춰 Packet을 더 작게 만들어야 한다.

필요하다면 IPv6 Source가 Fragment Extension Header를 사용해 Fragment할 수 있지만 Router가 대신 나누지는 않는다.

IPv6가 모든 Link에서 기대하는 최소 MTU는 1280바이트다. 1280보다 작은 Link 기술은 IPv6 계층 아래에서 Fragmentation과 Reassembly 같은 적응을 제공해야 한다.

IPv4 PMTUD
→ DF Packet + ICMP Type 3 Code 4

IPv6 PMTUD
→ Router Fragmentation 없음
→ ICMPv6 Type 2 Packet Too Big

ICMPv6 Packet Too Big을 차단하면 IPv6의 정상적인 크기 조절도 깨질 수 있다.


ㅁ ICMP가 오지 않아도 크기를 알아낼 수 있을까?

전통적인 PMTUD는 Router가 보내는 ICMP 오류에 크게 의존한다.

그러나 ICMP가 차단되거나 장비가 올바른 MTU를 알리지 않는 경로도 있다.

Packetization Layer Path MTU Discovery(PLPMTUD)는

  TCP 같은 Packetization Layer가 여러 크기의 Probe를 보내고 End-to-End 전달 결과로 사용할 크기를 탐색하는 접근이다.

작은 크기: 전달 성공
조금 큰 Probe: 전달 성공
더 큰 Probe: 응답 없음

→ 확인된 크기와 실패한 크기 사이에서 안전한 값 탐색

PLPMTUD의 핵심은 ICMP만을 유일한 진실로 기다리지 않는 데 있다.

  • ACK가 돌아온 Probe 크기는 End-to-End로 전달됐음을 확인한다.
  • 큰 Probe가 실패해도 작은 Packet으로 연결 상태를 계속 확인할 수 있다.
  • ICMP 정보가 도착하면 추가 단서로 활용할 수 있다.

단순한 Data Loss와 크기 때문에 발생한 Loss를 구분하는 일은 쉽지 않다.

그래서 Probe 식별, 재시도, 확인된 Base 크기 같은 상태가 필요하다.

TCP 구현은 반복 재전송에서 Black Hole을 의심해 Segment 크기를 낮추는 완화 동작을 제공할 수도 있다.

구체적인 탐색과 Fallback 방식은 Protocol과 운영체제 구현에 따라 달라진다.


ㅁ PMTUD와 PLPMTUD는 무엇을 관찰할까?

구분 전통적인 PMTUD PLPMTUD
주요 단서 Router의 ICMP Too Big 오류 End-to-End Probe의 성공과 실패
IPv4 출발점 DF가 설정된 Packet Packetization Layer가 크기별 Probe 관리
장점 Router가 정확한 Next-Hop MTU를 알려 줄 수 있음 ICMP가 사라져도 탐색 가능
어려움 ICMP 차단 시 Black Hole Loss 원인이 MTU인지 혼잡인지 구분 필요
상태 위치 IP/Route PMTU 상태 TCP·QUIC 같은 Packetization Layer 상태
공통 목표 중간 Fragmentation 없이 경로가 운반할 수 있는 Packet 크기 사용 같은 목표

두 방식을 서로 완전히 배타적인 선택으로 볼 필요는 없다.

구현은 ICMP 오류를 받아 빠르게 줄이면서 End-to-End Probe로 전달 여부를 검증할 수 있다.


ㅁ MSS Clamping은 무엇을 바꿀까?

Tunnel이나 Firewall 장비가 TCP SYN의 MSS Option을 더 작은 값으로 바꾸는 구성이 있다.

이를 TCP MSS Clamping이라고 한다.

Client SYN MSS=1460
        ↓ Tunnel Gateway가 조정
상대가 보는 MSS=1360

상대는 처음부터 더 작은 TCP Segment를 보내므로 Tunnel 내부에서 PMTU를 넘는 Packet이 생길 가능성을 줄일 수 있다.

MSS Clamping은 다음 상황에서 실용적인 완화책이 될 수 있다.

  • Tunnel Overhead 때문에 내부 PMTU가 줄어듦
  • 제어할 수 없는 경로에서 ICMP가 잘못 차단됨
  • TCP 연결이 큰 Segment에서 반복적으로 멈춤

하지만 한계도 분명하다.

  • TCP SYN의 MSS만 조정하므로 UDP와 다른 Protocol 문제는 해결하지 않는다.
  • 잘못된 값을 사용하면 필요 이상으로 작은 Segment를 만들어 효율이 떨어진다.
  • ICMP 차단이나 MTU 구성 오류라는 근본 원인을 숨길 수 있다.
  • 이미 성립한 연결의 SYN을 과거로 돌아가 바꾸지는 못한다.

MSS Clamping은 “모든 MTU 문제의 정답”이 아니라 관리 경계에서 신중하게 사용하는 보완책이다.


ㅁ 큰 ping 하나로 PMTU를 확정할 수 있을까?

DF가 설정된 ICMP Echo Request의 크기를 바꾸며 성공 경계를 찾는 방법은 유용한 진단 단서다.

IPv4 Header Option이 없고 ICMP Header가 8바이트라면 다음처럼 계산한다.

추정 PMTU = ping Data 크기 + IPv4 Header 20 + ICMP Header 8

 

예를 들어 Linux에서 다음 Probe를 사용할 수 있다.

ping -M do -c 1 -s 1472 192.0.2.10
1472 + 20 + 8 = 1500

Data 크기를 1473으로 늘리면 IPv4 Packet은 1501바이트가 된다.

 

하지만 이 결과 하나만으로 모든 Application의 PMTU를 확정하면 안 된다.

  • ping Option과 크기 의미는 운영체제마다 다르다.
  • ICMP Echo만 정책적으로 차단될 수 있다.
  • ECMP 때문에 Flow별 경로가 다를 수 있다.
  • 반대 방향 PMTU가 다를 수 있다.
  • Tunnel과 Header Option이 실제 Application Packet 크기를 바꿀 수 있다.

ping은 경계 가설을 시험하는 도구이지 모든 Protocol과 경로의 절대적인 증명서는 아니다.


ㅁ tracepath는 무엇을 보여줄까?

Linux의 tracepath는 Hop을 관찰하면서 PMTU 변화 단서를 표시할 수 있다.

tracepath 192.0.2.10

 

출력에는 환경에 따라 다음과 같은 정보가 보일 수 있다.

pmtu 1500
...
pmtu 1400

tracepath도 경로 장비의 ICMP 응답, Return Path, 정책의 영향을 받는다.

응답이 없거나 일부 Hop이 보이지 않는다고 해당 Link가 존재하지 않는 것은 아니다.

표시된 PMTU 역시 관찰한 Probe에 기반한 결과다.

권한과 설치 여부, Option은 운영체제와 배포판에 따라 다를 수 있다.


ㅁ Packet Capture에서는 무엇을 찾아야 할까?

IPv4 PMTUD 문제를 조사할 때 다음 흐름을 함께 본다.

큰 TCP Data Packet
→ 같은 Sequence Number의 Retransmission
→ ICMP Type 3 Code 4 존재 여부
→ 재전송 Packet 크기 변화 여부

 

Wireshark Display Filter 예시는 다음과 같다.

icmp.type == 3 && icmp.code == 4

 

IPv6 Packet Too Big은 다음처럼 찾을 수 있다.

icmpv6.type == 2

 

함께 확인할 Field는 다음과 같다.

IPv4: ip.len, ip.flags.df, icmp.type, icmp.code, icmp.mtu
IPv6: ipv6.plen, icmpv6.type, icmpv6.mtu
TCP : tcp.seq, tcp.len, tcp.analysis.retransmission

 

Capture 지점이 중요하다.

Router 앞에서 큰 Packet 확인
Router 뒤에서 Packet 없음
Source 쪽에서 ICMP 없음

→ Router Drop과 ICMP Return Path를 나누어 조사

NIC Offload 때문에 Host Capture에서 MTU보다 큰 TCP 단위가 보일 수 있으므로 Wire Packet 크기와 혼동하지 않는다.


ㅁ MTU 문제를 진단하는 순서는 무엇일까?

“작은 것은 되고 큰 것은 안 된다”는 증상만으로 곧바로 MTU 문제라고 단정할 수는 없다.

 

다음 순서로 가설을 좁힐 수 있다.

  1. DNS와 Route, TCP Handshake가 실제로 성공하는지 확인한다.
  2. 실패가 전체 연결인지 특정 크기 이후인지 확인한다.
  3. 양 Endpoint에서 Packet 크기, DF, Retransmission을 Capture한다.
  4. ICMP Fragmentation Needed 또는 Packet Too Big이 생성되는지 확인한다.
  5. 생성된 ICMP가 Source까지 돌아오는지 각 정책 지점을 확인한다.
  6. Interface와 Tunnel MTU, Encapsulation Overhead를 계산한다.
  7. TCP라면 SYN의 MSS와 실제 Segment Payload 크기를 비교한다.
  8. DF Probe와 tracepath 결과를 보조 단서로 사용한다.
  9. 임시 MSS Clamping 전에 ICMP와 MTU 구성의 근본 원인을 확인한다.

관찰의 핵심은 실패한 Application만 보는 것이 아니라

  큰 Packet이 마지막으로 보인 지점과 ICMP가 마지막으로 보인 지점을 따로 찾는 것이다.


ㅁ 우편 비유를 네트워크 용어로 바꾸면

비유를 실제 Protocol과 상태로 다시 연결해 보자.

우편 이야기 실제 용어 정확한 의미
경로 전체에서 가장 작은 소포 규격 Path MTU 한 방향 경로의 Link MTU 중 최솟값
소포에 나누지 말라는 표시 IPv4 DF Flag 중간 Router의 Fragmentation을 금지
다음 길에는 너무 크다는 반송 안내 ICMP Type 3 Code 4 DF Packet이 Outgoing MTU를 넘었음을 알림
반송장에 적힌 허용 크기 Next-Hop MTU 다음 Link가 전달할 수 있는 Packet 크기
목적지별로 기억한 포장 규격 PMTU Cache 발견한 PMTU를 Route 상태와 연관해 임시 저장
반송 안내가 사라지는 구간 MTU Black Hole 큰 Packet과 ICMP 오류가 모두 전달되지 않아 정체
IPv6의 너무 큰 소포 안내 ICMPv6 Packet Too Big IPv6 Router가 Source에 MTU 한계를 통보
크기를 조금씩 바꿔 시험 배송 PLPMTUD End-to-End Probe 성공 여부로 안전한 크기를 탐색
접수 시 소포 본문 한도를 줄임 MSS Clamping TCP SYN의 MSS 값을 관리 장비가 조정
터널 포장 때문에 줄어든 내부 공간 Encapsulation Overhead Outer Header만큼 내부에서 쓸 크기가 감소

 

전체 흐름은 다음과 같다.

Source가 큰 DF Packet 전송
            ↓
     Router의 MTU 초과
            ↓
       Packet Drop
            ↓
ICMP Too Big이 Source에 도착하는가?
       ┌────┴────┐
      Yes        No
       │          │
 PMTU 갱신     같은 크기 재전송
 Packet 축소    ACK 진전 없음
       │          │
 전달 재개     MTU Black Hole

ㅁ 격리된 Linux 환경에서 Black Hole을 관찰해 보기

다음 실습은 ip, iptables, tcpdump, nc가 있는 개인 Linux VM에서만 수행한다.

모든 정책과 MTU 변경은 세 Network Namespace 안에 격리한다.

pmtu-client ── MTU 1500 ── pmtu-router ── MTU 1200 ── pmtu-server

Server Interface는 1500을 유지하고 Router의 Server 방향 Outgoing Interface만 1200으로 설정한다.

이 차이 때문에 Server가 광고한 TCP MSS만으로는 중간의 작은 MTU를 알 수 없다.

 

Namespace와 가상 Link를 만든다.

sudo ip netns add pmtu-client
sudo ip netns add pmtu-router
sudo ip netns add pmtu-server

sudo ip link add veth-pc type veth peer name veth-prc
sudo ip link add veth-prs type veth peer name veth-ps

sudo ip link set veth-pc netns pmtu-client
sudo ip link set veth-prc netns pmtu-router
sudo ip link set veth-prs netns pmtu-router
sudo ip link set veth-ps netns pmtu-server

 

Address와 Interface를 설정한다.

sudo ip -n pmtu-client addr add 10.20.1.2/24 dev veth-pc
sudo ip -n pmtu-router addr add 10.20.1.1/24 dev veth-prc
sudo ip -n pmtu-router addr add 10.20.2.1/24 dev veth-prs
sudo ip -n pmtu-server addr add 10.20.2.2/24 dev veth-ps

sudo ip -n pmtu-client link set lo up
sudo ip -n pmtu-router link set lo up
sudo ip -n pmtu-server link set lo up
sudo ip -n pmtu-client link set veth-pc up
sudo ip -n pmtu-router link set veth-prc up
sudo ip -n pmtu-router link set veth-prs up mtu 1200
sudo ip -n pmtu-server link set veth-ps up mtu 1500

 

Route와 Forwarding을 설정한다.

sudo ip -n pmtu-client route add default via 10.20.1.1
sudo ip -n pmtu-server route add default via 10.20.2.1
sudo ip netns exec pmtu-router \
  sysctl -w net.ipv4.ip_forward=1

 

Client Terminal에서 Packet을 Capture한다.

sudo ip netns exec pmtu-client \
  tcpdump -n -vv -i veth-pc -s 0 -w /tmp/pmtu-blackhole.pcap \
  'icmp or tcp port 8080'

 

먼저 Router가 생성한 ICMP Fragmentation Needed를 Router 안에서만 버린다.

sudo ip netns exec pmtu-router \
  iptables -I OUTPUT -p icmp \
  --icmp-type fragmentation-needed -j DROP

 

Server Terminal에서 TCP 수신을 시작한다. nc Option은 구현마다 다를 수 있다.

sudo ip netns exec pmtu-server nc -l 8080 > /dev/null

 

Client Terminal에서 충분히 큰 Data를 보낸다.

dd if=/dev/zero bs=1M count=4 | \
  sudo ip netns exec pmtu-client nc 10.20.2.2 8080

 

다음을 관찰한다.

  • 3-Way Handshake는 작은 Packet이라 성공하는가?
  • 큰 TCP Data Packet의 DF가 설정되어 있는가?
  • 같은 Sequence 범위가 재전송되는가?
  • Client Capture에 ICMP Type 3 Code 4가 보이지 않는가?

일부 TCP 구현은 반복 손실 후 Black Hole Fallback으로 Segment 크기를 낮춰 스스로 회복할 수 있다.

따라서 “영원히 멈춤” 대신 긴 정체 후 회복으로 보일 수도 있다.

전송이 정체된 동안 Router의 Drop Rule을 제거한다.

sudo ip netns exec pmtu-router \
  iptables -D OUTPUT -p icmp \
  --icmp-type fragmentation-needed -j DROP

다음 큰 재전송에서 Router의 ICMP가 Client에 도착하면 PMTU가 갱신되고 더 작은 TCP Segment로 전송이 재개되는지 확인한다.

별도의 DF Probe로 1200바이트 경계를 확인할 수도 있다.

 

Linux의 -M probe는 권한이 필요하며 Kernel의 기존 PMTU 확인을 우회해 Probe를 보낸다.

sudo ip netns exec pmtu-client \
  ping -M probe -c 1 -s 1172 10.20.2.2

sudo ip netns exec pmtu-client \
  ping -M probe -c 1 -s 1173 10.20.2.2
1172 + IPv4 20 + ICMP 8 = 1200 → 경계 안
1173 + IPv4 20 + ICMP 8 = 1201 → 경계 초과

 

iptables가 없거나 nftables Backend 정책이 다른 환경에서는 명령을 그대로 사용할 수 없을 수 있다.

실제 Host Firewall에 Drop Rule을 추가하지 말고 Namespace 내부에서만 실습한다.

실습을 마치면 Namespace를 삭제한다. 내부 Firewall Rule과 가상 Interface도 함께 제거된다.

sudo ip netns del pmtu-client
sudo ip netns del pmtu-router
sudo ip netns del pmtu-server

ㅁ 핵심 정리

  • Link MTU는 한 Link의 크기 한계이고 Path MTU는 한 방향 경로에 있는 Link MTU의 최솟값이다.
  • IPv4 PMTUD는 DF Packet이 너무 클 때 Router가 보내는 ICMP Type 3 Code 4를 이용해 PMTU를 낮춘다.
  • Source는 PMTU에서 IP와 Transport Header를 제외한 크기로 TCP Segment Data를 조절한다.
  • ICMP 한 번이 경로의 모든 Link를 알려 주는 것은 아니며 더 좁은 Link에서 다시 오류를 받을 수 있다.
  • PMTU Cache는 Route 변화 때문에 영구적인 정답이 아니며 유효 시간과 재탐색이 필요하다.
  • TCP MSS는 TCP Data 크기이고 PMTU는 IP Packet 전체 크기이므로 같은 값이 아니다.
  • TCP Handshake와 작은 Packet이 성공해도 큰 DF Data Packet은 중간 MTU에서 실패할 수 있다.
  • 필요한 ICMP Too Big 오류가 차단되면 Source가 Packet을 줄이지 못하는 MTU Black Hole이 생긴다.
  • IPv6 Router는 Fragmentation하지 않고 ICMPv6 Type 2 Packet Too Big으로 MTU를 알린다.
  • PLPMTUD는 End-to-End Probe의 성공과 실패를 이용해 ICMP에만 의존하지 않고 크기를 탐색한다.
  • MSS Clamping은 TCP의 실용적인 완화책일 수 있지만 UDP를 해결하지 못하고 근본 MTU 오류를 숨길 수 있다.
  • 진단할 때 큰 Packet의 마지막 관찰 지점과 ICMP 오류의 Return Path를 분리해서 확인해야 한다.

 

핵심 용어: Link MTU, Path MTU, PMTU, Path MTU Discovery, PMTUD, DF, ICMP Type 3 Code 4, Fragmentation Needed, Next-Hop MTU, PMTU Cache, Maximum Segment Size, MSS, MTU Black Hole, ICMPv6 Packet Too Big, Packetization Layer PMTUD, PLPMTUD, MSS Clamping, Encapsulation Overhead

 

PMTUD는 출발 전에 모든 길의 규격을 읽는 절차가 아니다.
큰 Packet을 보낸 뒤 돌아오는 “이 길에는 너무 크다”는 제어 메시지와 End-to-End 전달 결과로
현재 경로의 한계를 계속 학습하는 과정이다.


ㅁ 다음 이야기

이제 Source는 경로가 허용하는 크기에 맞춰 Packet을 보낼 수 있다.

그러나 IPv4에는 또 다른 한계가 있다. 인터넷에 연결하려는 기기는 계속 늘어났지만 전 세계에서 고유하게 사용할 수 있는 IPv4 주소의 수는 제한되어 있다.

집 안의 여러 Computer와 Phone이 하나의 공인 IPv4 주소로 동시에 인터넷을 사용하는 것은 어떻게 가능할까?

다음 글에서는 「여러 집이 하나의 공인 주소를 함께 쓸 수 있을까?」라는 질문을 통해 Private Address, NAT, NAPT/PAT, Translation Table과 End-to-End 연결의 변화를 살펴본다.

 

반응형
Comments