대부분의 설명에서 SSTP 에 관한 두 가지 사실이 하나로 합쳐지고, 바로 그 합쳐짐이 캡처를 혼란스럽게 만든다. 애플리케이션 패킷은 보호된 채널 안에서 살아남고, 그 채널을 나르는 TCP 연결은 내내 자기 주소를 유지한다. 회선 위로 지나가는 것은 운반자와 그 화물이며, 둘 중 어느 것의 대체물도 아니다. 스택을 바깥에서 안쪽으로 걸어가며 지나는 모든 경계에 이름을 붙여라.

바깥 운반자에서 시작하라

회선 위의 첫 번째 것은 포트 443으로 가는 평범한 TCP 연결이며, 라우터가 전달하는 실제 주소를 가진다. 바로 그 연결이 네트워크 주소 변환을 견디고 접속 사업자가 셀 수 있는 대상이다. 페이로드를 보호한다고 해서 운반자가 사라지지 않으며, 그것은 크기나 시점을 숨기지도 않는다.

이 지점 이후의 모든 것은 라우팅되는 대신 운반된다. 내부 교환이 실패해도 운반자는 계속 동작한다.

캡슐화를 안쪽으로 따라가라

보호된 채널 안에는 SSTP 제어 교환이 있고, 그다음 PPP 세션, 그다음 클라이언트가 전달받기를 원하는 네트워크 패킷이 있다. 각 계층에는 고유한 협상, 고유한 오류 메시지, 고유한 상태 기계가 있다. 따라서 결함은 한 관점에서는 TLS 결함처럼 보이고 다른 관점에서는 PPP 결함처럼 보일 수 있다. 계층을 순서대로 읽으면 어느 상태 기계가 멈췄는지 알 수 있다.

캡처 하나가 전체 스택을 보여 주는 경우는 드물다. 바깥 헤더는 종단점 밖에서만 보이고, 안쪽 헤더는 캡슐 해제 후에만 보인다. 그 비대칭은 프로토콜이 아니라 당신이 서 있는 위치에서 온다.

아래 그림은 계층을 묶어서 논의라도 할 수 있게 한다. 바이트 배치도 아니고, 패킷마다 레코드 하나를 약속하지도 않으며, 구현이 암호 연산을 몇 번 수행하는지에 대해서도 말하지 않는다.

outer IP header
  TCP to port 443
    TLS record layer
      SSTP control and data packets
        PPP frames
          inner IP packet
            application transport and payload

캡처를 읽기 전에 관측자에 이름을 붙여라

같은 세션의 캡처 두 개는 서로 다른 질문에 답하며, 어느 질문인지는 어느 인터페이스에서 떴는지가 결정한다. 접속 경로에서는 운반자와 TLS 레코드가 보이고, 내부 주소를 보지 않고도 크기와 간격을 잴 수 있다. 종단점에서는 캡슐 해제 후 내부 패킷이 사설 전달 정책 아래의 평범한 트래픽이다.

해석하기 전에 모든 캡처에 인터페이스와 방향을 적어라. 물리 어댑터에서 뜬 추적은 내부 애플리케이션의 주소를 평범한 바깥 필드로 보여 주지 않으며, 그 부재를 암호화 실패로 읽는 것은 흔한 실수다. 터널 안쪽에서 뜬 추적은 운반자를 전혀 보여 주지 않으므로 사업자의 시야에 관한 질문에 답할 수 없다. 같은 규율이 종단점 로그에도 적용되며, 그 로그는 내용이 아니라 협상 순서를 기록한다.

그림이 증명할 수 없는 점검을 남겨라

계층 순서는 배포가 서버 인증서를 검증하는지, 지원되는 TLS 버전을 협상하는지, 계정을 승인하는지를 입증하지 않는다. 그 각각은 캡슐화와 무관하게 실패하는 구성 결정이다.

그림에서 추론하는 대신 무엇을 협상했는지 보고하는 클라이언트로 검증하라. TLS 핸드셰이크로 시작하고, 그다음 SSTP 교환, 그다음 PPP로 이어 가며 오류를 보고하는 첫 단계에서 멈춰라. 첫 명령은 체인과 협상된 버전을 출력하고, 두 번째는 캡처에 존재하는 핸드셰이크를 나열한다.

openssl s_client -connect vpn.corp.internal:443 -servername vpn.corp.internal
tshark -r sstp.pcap -Y "tls.handshake.type == 1"

관련 글