Linux IPsec 게이트웨이의 외부 인터페이스에서 tcpdump를 실행하면 두 가지가 동시에 보입니다. 들어오는 ESP 프레임과 그 직후에 이어지는 복호화된 내부 패킷입니다. 나가는 쪽에서는 ESP만 나타납니다. 그러면 응답이 전송되지 않거나 IPsec이 한 방향만 암호화하고 다른 쪽을 잊었다고 결론 내리기 쉽지만 둘 다 사실이 아닙니다.

보고 있는 것은 캡처 지점입니다. 커널은 장치의 전송 경로가 패킷을 패킷 소켓에 넘기기 전에 나가는 패킷을 변환하므로, 소켓은 나가는 내부 형태를 결코 보지 못합니다. 들어올 때는 패킷이 먼저 ESP로 캡처되고, 다시 스택으로 들어올 때 역캡슐화된 사본이 보입니다. 같은 트래픽을 두 개의 다른 관찰 창에서 보는 것입니다.

무엇이 보이는지는 캡처 지점이 결정한다

일반 인터페이스에서 AF_PACKET 소켓은 장치 계층 가까이에 있습니다. 호스트를 떠나는 패킷은 먼저 IPsec 출력 처리를 거치며, 여기서 내부 TCP 세그먼트가 ESP 또는 UDP-4500 데이터그램으로 바뀌고, 그다음에야 이 계층에 도달합니다. 도착하는 패킷은 케이블에서 나올 때 아직 암호화된 상태로 소켓에 복사되며, 복호화된 결과는 스택이 이를 로컬로 전달하거나 포워딩할 때 나중에 보입니다.

이 순서가 비대칭성을 완전히 설명합니다. 방향이나 정책, 애플리케이션 동작에 대한 증거가 아니며, 그렇게 취급하면 계속 올바르게 전송되던 응답을 쫓아가게 됩니다. 이것은 이상을 네트워크가 아니라 도구가 만드는 몇 안 되는 네트워크 수수께끼 중 하나입니다.

필터를 의도한 계층에 맞춘다

tcp port 443 같은 표현은 내부 TCP 연결을 고릅니다. 나가는 방향에서는 소켓에 질의할 시점에 그 연결이 이미 ESP가 되어 있어 필터가 아무것도 일치시키지 못합니다. 보호된 트래픽을 세려면 대신 바깥 형태로, 즉 원시 ESP에는 프로토콜 50, NAT 통과가 관여하면 UDP 포트 4500으로 필터링하십시오. 두 필터 모두 두 피어 사이에서 비교할 수 있는 패킷 수를 내놓으며, 보통 세는 이유가 바로 그것입니다. 둘 다 내부 요청에 응답이 있었는지는 말해 주지 않습니다.

UDP 4500 수를 ESP 패킷 수로 취급하지 마십시오. IKE도 그 포트를 NAT-T 킵얼라이브와 캡슐화된 교환에 사용하므로, 이 숫자에는 측정하려던 데이터가 아닌 트래픽도 포함됩니다. UDP 500의 초기 IKE 교환은 그것이 질문이라면 자체 필터가 필요합니다. 제어 트래픽과 데이터를 섞은 숫자는 대역폭 추정도 알 수 없는 폭만큼 틀리게 만듭니다. 별도의 집계는 별도의 질문에 답합니다.

필터는 그것이 답하는 질문 옆에 적어 두십시오. «상자에서 ESP가 얼마나 나갔나»와 «웹 요청이 상자에서 나갔나»는 서로 다른 필터를 쓰는 다른 측정이며, 한 번의 캡처로 둘 다 결정할 수 없습니다. 그 메모가 없으면 두 사람은 결코 같은 것을 세지 않은 숫자를 비교하게 됩니다.

변환 전에 관찰하라, 후가 아니라

나가는 평문을 봐야 한다면 관찰 지점을 더 앞으로, IPsec 출력 처리 이전으로 옮기십시오. NFLOG는 규칙이 선택한 패킷을 사용자 공간 소켓으로 복사할 수 있는 Netfilter 훅을 제공하며, tcpdump가 이를 읽을 수 있습니다. strongSwan의 트래픽 덤프 안내서가 바로 이 이유로 이 접근 방식을 문서화합니다.

정책 일치는 규칙을 터널로 들어가려는 트래픽으로 제한합니다. -m policy --pol ipsec --dir out이 상자가 보내는 모든 패킷을 기록하는 대신 규칙을 구체적으로 만듭니다. 그다음 로그 그룹을 제한된 캡처로 읽되, 작은 스냅샷 수와 크기 제한으로 진단이 트래픽 아카이브가 되지 않게 하십시오. 제한된 캡처는 무관한 페이로드를 끌고 다니지 않고 검토자에게 넘기기도 더 쉽습니다. 시작하기 전에 수를 정하고, 얼마나 도착했는지 본 뒤에 정하지 마십시오.

iptables -I OUTPUT 1 -d 10.83.0.44/32 -p tcp --dport 8443 -m policy --pol ipsec --dir out -j NFLOG --nflog-group 5
tcpdump -ni nflog:5 -s 128 -c 20 'host 10.83.0.44 and tcp port 8443'

흐름에 맞는 훅을 고르십시오. OUTPUT은 게이트웨이가 스스로 만드는 트래픽을 다루고, LAN 클라이언트에서 오는 통과 트래픽은 대신 FORWARD 체인을 지나며, OUTPUT의 규칙은 결코 그것을 보지 못합니다. 위의 주소와 포트는 승인된 시험 대상에 대한 자리 표시자입니다.

관찰이 증명하는 것

NFLOG는 로깅 대상이지 수용 결정이 아닙니다. 거기에 패킷이 나타난다는 것은 그 패킷이 훅에 도달해 규칙과 일치했다는 뜻입니다. 이후 필터가 허용했는지, 장치가 전송했는지, 피어가 무엇을 받았는지는 보여 주지 않습니다.

빈 로그도 마찬가지로 모호합니다. 규칙의 패킷 카운터를 확인하고, 방향을 확인하고, 흐름이 실제로 IPsec 정책과 일치했는지 확인하고, 목적지를 확인하십시오. 두 피어에서 일치하는 카운터만이 관찰을 결론으로 바꿉니다. 그다음 같은 통제된 시도에 대해 두 피어의 보안 연계 카운터를, 무엇이 보호되고 전송되었는지에 대한 권위 있는 기록이므로 비교하십시오.

또 하나의 함정이 있는데, 여기서 «평문»은 IPsec 암호화 계층 바깥을 뜻합니다. 내부 HTTPS 세션에도 여전히 자체 TLS가 있습니다. 역캡슐화된 패킷을 캡처해도 애플리케이션의 TLS가 복호화되지 않으며, 거기서 읽을 수 있는 HTTP가 보인다면 그 애플리케이션은 처음부터 HTTPS를 쓰지 않은 것입니다.

정리하고 양쪽 끝을 비교한다

관찰이 끝나면 삽입한 바로 그 규칙을 소유자별로 제거하십시오. 로깅 규칙을 남겨 두면 일치하는 모든 패킷에서 CPU를 소모하고 조용히 데이터 보존 문제를 만듭니다. 소유하지 않은 체인을 비우는 대신 -D로 규칙을 반복해 삭제하십시오.

iptables -D OUTPUT -d 10.83.0.44/32 -p tcp --dport 8443 -m policy --pol ipsec --dir out -j NFLOG --nflog-group 5

배포가 사용자 공간 IPsec, XFRM 인터페이스 또는 하드웨어 오프로드를 사용한다면 관찰 지점이 달라지고 이 방법이 전혀 적용되지 않을 수 있습니다. libipsec의 경우 내부 트래픽을 관찰하는 문서화된 위치는 TUN 장치입니다. 먼저 경로를 파악하고, 다음으로 질문에 답하는 지점을 고르고, 두 방향이 다르게 보이는 것은 변환의 반대편을 보고 있을 때뿐이라고 예상하십시오.

관련 글