누군가 VPN이 „UDP를 막는다“고 보고하는데, 이 한 문장에는 전혀 다른 두 주장이 숨어 있다. 하나는 접속망이 볼 수 있는 전송에 관한 것이고, 다른 하나는 터널 안에서 복호화된 뒤의 애플리케이션 패킷에 관한 것이다. 암호화된 터널은 키 없이도 외부에서 필터링할 수 있고, 내부 UDP 애플리케이션은 필터링과 무관한 이유로 실패할 수 있다. 증거를 모으기 전에 어느 주장을 검증하는지 정하라.

두 개의 헤더, 하나의 단어

NAT-traversal을 쓰는 IPsec 배포에서 바깥 패킷은 두 VPN 엔드포인트 사이에서 주소 지정된 UDP이며, 보통 포트 4500을 쓴다. 그 안에서 암호화된 페이로드는 터널이 전달하는 모든 것을 실어 나르며, 그것 자체가 TCP나 UDP일 수 있다. 따라서 UDP라는 단어는 서로 다른 의미와 서로 다른 가시성으로 두 번 등장한다.

중간 네트워크는 바깥 헤더만 보고 내부는 아무것도 보지 못한다. 바깥 흐름을 허용하거나 조형하거나 버릴 수 있으며, 그러기 위해 무엇인가를 복호화할 필요가 없다. 이 비대칭성이 두 주장이 뒤섞이는 이유 전부다. 같은 단어가 네트워크가 필터링하는 것과 애플리케이션이 보내는 것을 함께 가리킨다. 발견을 기록할 때마다 단어 옆에 계층을 적으면 혼동은 대부분 사라진다.

내부 헤더는 복호화 후 수신 엔드포인트에서만 보인다. 그 시점부터 패킷은 다른 패킷과 마찬가지로 전달되며, 경로와 정책, 엔드포인트 자체의 필터링을 따른다. 이는 서로 다른 장비가 내리는 별개의 결정이다.

네트워크가 여전히 볼 수 있는 것

암호화가 숨기는 것은 페이로드와 내부 전송 헤더이지, 흐름이 존재한다는 사실이 아니다. 엔드포인트 주소, 포트, 패킷 크기, 타이밍은 그대로 보이며, 그것만으로 트래픽을 휴리스틱하게 분류하거나 특정 목적지를 차단할 수 있다.

sudo tcpdump -ni eth0 'udp port 4500'
sudo tcpdump -ni tun0 'udp port 5201'

첫 번째 캡처는 물리 인터페이스의 바깥 흐름을, 두 번째는 터널 인터페이스의 내부 흐름을 보여 준다. 둘을 동시에 돌리면 질문에 곧바로 답이 나온다. 바깥 흐름은 있고 내부가 없다면 애플리케이션은 터널로 아무것도 보내지 않은 것이다. 둘 다 있고 아무것도 돌아오지 않는다면 문제는 터널 너머, 목적지나 되돌아오는 경로에 있다.

RFC 3948 은 바깥 UDP 캡슐화를 정의하고, ESP 명세는 그 안의 보호된 배치를 정의한다. 두 문서 중 어느 것도 접속망이 바깥 흐름을 통과시킨다고 약속하지 않는다. 그래서 내부에 관한 어떤 이론보다 먼저 바깥 튜플에서 도달성 시험을 돌릴 가치가 있다. 바깥 튜플이 차단되면 터널이 아예 형성되지 않으며, 형성된 터널이 애플리케이션 하나를 잃는 경우와는 다르다.

동작하는 터널 안에서 UDP 앱 하나가 실패하는 이유

웹 애플리케이션은 실어 나르지만 UDP 애플리케이션은 나르지 않는 터널에는 그럴듯한 설명이 여럿 있고, ISP의 내부 프로토콜 필터링은 그 첫 번째가 아니다. 가장 흔한 것은 커버리지다. UDP 목적지로 가는 경로가 없거나 클라이언트의 분할 터널 규칙이 그것을 제외하기 때문에 두 애플리케이션이 같은 터널에 함께 들어가지 않는다.

두 번째는 엔드포인트다. 프로토콜 목록을 허용하는 VPN 서버, 목적지 쪽 방화벽, 기대한 포트에서 결코 수신하지 않는 서비스는 모두 네트워크 차단과 똑같아 보이는 타임아웃을 만든다.

세 번째는 패킷 크기다. UDP 애플리케이션은 웹 요청보다 큰 데이터그램을 보내는 일이 많고, 캡슐화가 사용 가능한 MTU를 줄이므로 핸드셰이크가 성공한 뒤 첫 전체 크기 페이로드에서 침묵이 올 수 있다. 작은 패킷은 통과하고 큰 패킷만 사라지므로 이 패턴을 차단으로 잘못 읽기 쉽다. 빠른 MTU 점검은 몇십 초 만에 결론을 내며, 답은 보통 네트워크 필터가 아니라 더 작은 페이로드나 수정된 MSS다.

ping -M do -s 1400 -c 2 10.60.0.20
iperf3 -u -c 10.60.0.20 -p 5201 -b 1M -t 5

첫 명령은 단편화를 끈 상태에서 큰 패킷이 경로를 통과하는지 시험하며, MTU 문제를 빠르게 드러낸다. 두 번째는 작고 제한된 UDP 스트림을 보내 손실과 지터를 보고한다. 시작했다가 멈추는 스트림은 차단이 아니라 크기를 가리킨다.

프로토콜이 아니라 계층을 보고하라

발견을 세 가지 형태 중 하나로 적어라. 바깥 전달 실패, 내부 포워딩 실패, 또는 애플리케이션 실패다. 각각 담당이 다르고, 이것을 섞으면 티켓이 엉뚱한 팀으로 간다.

로컬 포트를 바꾼다고 먼 쪽에 대응하는 리스너가 생기지 않으므로, 도움이 되는 것처럼 보이는 클라이언트 측 우회는 대개 원래 목적지가 틀렸다는 증거다. 마찬가지로 제공된 대체 프로필은 도달성에 대해 무엇인가를 증명하지만, 애플리케이션이 올바르게 설정되었는지에 대해서는 아무것도 증명하지 않는다.

추론과 관측도 분리해 두라. 트래픽 분석은 복호화하지 않고도 흐름이 무엇인지 시사할 수 있고 그것은 유용한 발견이지만, 내부 헤더를 읽는 것과 같은 주장은 아니다. 실제로 어느 쪽을 가졌는지 밝혀라.

관련 글