응답 없는 아웃바운드 ESP는 VPN이 죽었다는 뜻이 아니다
ESP는 연결마다 한 방향만 보호하고 아무것도 확인 응답하지 않는다. 서버를 무응답이라고 부르기 전에 내부 대화와 인바운드 SA를 맞춰 보라.
IPsec 호스트에서 트래픽을 캡처했고 ESP 패킷이 나가는 것을 보았으며 아무것도 돌아오지 않는 것을 보고 원격 쪽이 고장 났다고 결론지었다. 그 캡처는 이 결론을 뒷받침하지 않는다. ESP는 대화의 한 방향만 보호하고 IP 계층에서 아무것도 확인 응답하지 않으므로, 돌아오는 ESP가 없다는 것은 애플리케이션이 할 말이 없었다는 뜻일 수도 있고 터널이 죽었다는 뜻일 수도 있다. 어느 쪽 끝을 탓하기 전에 내부 교환과 수신 측 상태를 읽어라.
오해: 보호된 모든 패킷은 응답을 받을 자격이 있다
ESP는 요청-응답 프로토콜이 아니다. 정책이 선택하는 모든 것을 암호화하고 인증하며, 수신자는 자신의 패킷을 생성하지 않고 그 내부 패킷을 검증하고 복호화하여 전달한다. 목적지가 무시하는 UDP 질의나 인바운드 정책이 버리는 ICMP 에코는 올바른 결과로서 양방향 모두 침묵을 만든다. 그 침묵을 전송 장애로 취급하면 존재한 적 없는 네트워크 결함을 찾아 나서게 된다.
단방향 캡처가 실제로 증명하는 것은 송신자 스택이 그 관측 지점에서 무언가를 암호화했다는 것뿐이다. 도착에 대해서도, 응답할 의도에 대해서도 아무것도 아니다. 유용한 질문은 "왜 응답이 없는가"가 아니라 "내부 대화가 무엇을 만들어야 했는가"이다.
두 개의 SA, 두 개의 SPI, 하나의 대화
IPsec 보안 연관은 단방향이므로 정상적인 보호 교환은 별도의 식별자와 독립적인 상태를 가진 인바운드 연관과 아웃바운드 연관을 포함한다. 아웃바운드 패킷의 SPI로 반환 트래픽을 찾는 것은 범주 오류다. 어떤 응답이든 상대방 자신의 아웃바운드 SA 아래에서 자신의 SPI로 이동하기 때문이다. 대신 트래픽 선택자와 상대방 주소로 쌍을 맞춰라.
키 재생성은 이전 상태와 교체 상태가 겹칠 수 있어 몇 초 동안 그림을 복잡하게 만든다. 증상이 키 재생성 무렵 시작되었다면 연결 이름만이 아니라 연관 식별자와 타임스탬프를 함께 수집하라.
무언가 응답하기 전에 수신자가 해야 할 일
| Stage | What to look at | Wrong conclusion if skipped |
|---|---|---|
| Sender encrypts | outbound SA packet counter | "the tunnel is up" |
| Peer receives | inbound SA counter and replay window | "the peer is down" |
| Inner delivery | target host or service logs | "routing is broken" |
| Application replies | the app's own trace | "the reply was dropped" |
| Protected return | the peer's outbound SA | "ESP only works one way" |
각 행은 독립적으로 실패하고 실패마다 담당이 다르므로 하나의 캡처로는 구분할 수 없다. 인바운드 카운터는 도착의 유일한 직접 증거다. 인증이나 재전송 검사에 실패한 패킷은 아무 응답 없이 폐기되기 때문이다. 인바운드 카운터가 움직이지 않은 상대는 따라서 자신의 정책에 대해 아무 정보도 보내지 않고 있다.
전달은 복호화와 별개의 단계다. 상태가 유효해도 내부 목적지를 포함하지 않는 인바운드 정책이나 경로에 의해 패킷이 나중에 폐기될 수 있으므로, 깨끗한 카운터가 패킷이 원하는 곳으로 갔다는 뜻이라고 가정하지 말고 대상 호스트가 평문을 보았는지 확인하라.
네이티브 ESP는 UDP가 아니다
네이티브 ESP는 IP 프로토콜 50이며 TCP도 UDP도 아니고 포트가 전혀 없다. 따라서 UDP 500에서 IKE를 허용하는 방화벽 규칙은 데이터 경로에 대해 아무것도 말하지 않으며, 포트를 중심으로 작성된 필터는 터널이 협상하게 한 뒤 그 안에서 운반되는 모든 것을 버릴 수 있다. 데이터 경로는 실제로 관측한 모드에서 따로 시험하라.
NAT 뒤에서는 형태가 달라진다. 보호된 페이로드는 UDP 내부를, 보통 포트 4500으로 이동하며 이는 RFC 3948이 정의하는 바이다. 규칙을 쓰기 전에 활성 모드를 기록하되, 경로상의 장치가 네이티브 ESP와 UDP 캡슐화 ESP를 전혀 다르게 취급할 수 있고 일부 중간 상자는 하나를 허용하고 다른 하나를 버린다는 점을 염두에 두라.
이 사건에 속한 카운터를 읽어라
strongSwan 호스트에서 swanctl --list-sas는 연관마다 양방향 패킷 및 바이트 카운터를 보고하며, 이는 "한 번도 도착하지 않음"과 "도착했지만 응답되지 않음"을 구분하기에 충분하다. Linux에서는 /proc/net/xfrm_stat가 상태 누락, 정책 누락, 프로토콜 오류 같은 집계 실패를 센다. 그 합계는 부팅 이후 누적되며 하나의 네트워크 네임스페이스에 속하므로 큰 숫자가 곧 귀속은 아니다.
올바른 네임스페이스에서 사건 창 전후로 두 번 읽고 차이를 비교하라. 그렇지 않으면 지난주 오류를 오늘 오후의 티켓에 붙이게 된다. 네임스페이스와 두 타임스탬프를 티켓에 적어 다음 독자가 합계를 믿는 대신 비교를 재현할 수 있게 하라.
용의자가 아니라 단계를 지목하라
유용한 결론은 패킷이 어디서 멈췄는지 말한다. 한 번도 수신되지 않음, 수신 후 폐기됨, 전달되었으나 응답 없음, 또는 응답되었으나 돌아오는 길에 유실됨 중 하나다. 각각은 다른 담당과 다른 다음 명령을 가리킨다. "VPN 서버에서 응답 없음"은 네 가지 서로 다른 결함을 캡처가 결코 정당화하지 않은 한 문장으로 눌러 담는다.
캡처는 좁게 유지하고 원시 커널 상태는 티켓 밖에 두라. 호스트 밖으로 나가면 안 되는 키 자료를 담을 수 있기 때문이다. 카운터 차이와 타임스탬프가 다음 사람에게 넘길 가치가 있는 부분이다.