WSS 터널 암호화는 앱이 아니라 TLS 종단에서 끝난다
wss:// URL은 한 홉에서 TLS가 있음을 증명합니다. 페이로드에 자체 암호화가 있는지는 클라이언트가 안에 무엇을 넣는지와 그 TLS를 누가 종단하는지에 달려 있습니다.
보안 WebSocket 안에 실려 가는 터널은 클라이언트가 그 안에 넣은 만큼의 암호화만 가지고, 그보다 많지 않습니다. wss:// 스킴은 TLS가 한 홉에서 연결 하나를 보호한다고 말합니다. WebSocket 메시지 안의 바이트가 별도로 보호되는지에 대해서는 아무 말도 하지 않으며, 중간에서 무언가가 TLS를 종단할 때 누가 트래픽을 읽을 수 있는지를 결정하는 것은 바로 이 차이입니다.
하나처럼 보이는 두 계층
보안 WebSocket은 그 위에서 WebSocket 핸드셰이크가 수행되는 TLS이며, RFC 6455가 연결과 보안 절에서 설명하는 바와 같습니다. TLS 계층이 서버를 인증하고 스트림을 암호화한 다음, WebSocket 계층이 애플리케이션이 보내기로 결정한 것을 프레이밍합니다.
이는 두 개의 독립적인 결정이며, 전체 경로 위에 자물쇠 하나를 그리는 다이어그램은 두 번째를 감춥니다. TLS 연결을 누가 종단하는지 물으십시오. 그다음 클라이언트가 각 메시지 안에 무엇을 넣는지 물으십시오. 배포에 관한 나머지 모든 것은 이 두 답에서 나옵니다.
설계 A: 전송이 유일한 암호화
더 단순한 설계에서는 클라이언트가 원시 IP 패킷을 받아 WebSocket 메시지로 감쌉니다. 안에는 아무것도 암호화되지 않으므로 TLS 세션을 가진 구성 요소가 평문 페이로드를 읽습니다. 그 구성 요소가 자체 터널 서버라면 이것이 의도된 종단이며, 서버는 어차피 트래픽을 보게 되어 있었으므로 설계가 일관됩니다.
경로에 검사 프록시가 앉아 클라이언트가 신뢰하는 인증서로 TLS를 종단하면 상황은 다른 구성이 됩니다. 그 프록시는 이제 서버가 가졌을 것과 같은 평문을 가지고 있으며, WebSocket 프레이밍을 아무리 겹쳐도 그것은 바뀌지 않습니다. 클라이언트의 신뢰 저장소가 그 이름에 대해 그 인증서를 받아들이기로 선택했기 때문에, 이 결과는 터널이 열리기 훨씬 전에 이미 결정되어 있었습니다. 프록시는 요청된 호스트와 각 메시지의 크기도 보며, 그것만으로 더 이상 아무것도 복호화하지 않고 많은 활동의 지문을 뜰 수 있습니다.
설계 B: 페이로드가 자체 키를 지닌다
두 번째 설계에서는 클라이언트가 자체 피어 신원과 키 교환을 가진 VPN 프로토콜로 패킷을 암호화하고 인증한 다음, 그 결과를 WebSocket 메시지 안에 실어 보냅니다. 여기서 바깥 TLS를 종단하면 트래픽이 아니라 암호문이 드러납니다. 프록시는 메시지 크기와 타이밍을 볼 수 있고, 페이로드의 다른 것은 볼 수 없습니다. 이는 훨씬 작은 노출이며, 그럼에도 검토에서 이름을 붙일 가치가 있는 메타데이터이지 손을 저어 치울 일이 아닙니다.
안쪽 프로토콜 자체의 종단은 여전히 평문을 보는데, 그것이 이 구성의 요점이며 동시에 한계입니다. 종단의 구성 요소가 암호화 전이나 복호화 후에 데이터를 읽을 권한을 가진다면, 추가 계층은 그것을 제한하지 않습니다. 키와 그 키를 다루는 소프트웨어가 중요한 경계로 남습니다.
VPN 라벨, 익숙한 클라이언트 아이콘, 마케팅 페이지는 이 설계가 존재한다는 증거가 아닙니다. 페이로드 형식을 읽는 것이 증거입니다.
평문이 실제로 어디에 나타나는지 추적하라
URL 스킴은 사실 하나만 주므로 나머지는 인터페이스에서 얻으십시오. 아래 검사는 각각 다음 검사의 범위를 좁히므로 순서대로 실행하십시오:
ss -tnp | grep -E ':(443|8443)\b' ip -br link show type tun openssl s_client -connect vpn.example.net:443 -servername vpn.example.net -brief tcpdump -ni tun0 -c 5 -X
바깥 연결부터 시작하십시오. TLS 포트로 가는 장수명 TCP 세션 하나가 WebSocket 운반체의 모습이며, 무관한 호스트로 가는 두 번째 세션은 더 깊이 보기 전에 설명이 필요합니다. 다음으로, tun이나 tap 장치가 있으면 클라이언트가 단일 애플리케이션 스트림을 프록시하는 것이 아니라 IP 패킷을 다루고 있다는 것을 알려 주는 클라이언트의 터널 인터페이스를 찾으십시오.
터널 인터페이스에서의 캡처가 보통 페이로드 문제를 정리합니다. 거기서 읽히는 헤더는 안쪽 패킷이 별도로 암호화된 적이 없음을 뜻하고, 엔트로피가 높은 페이로드는 암호화되었음을 뜻합니다. 바깥 인터페이스에서도 캡처를 반복해 비교해 보면, 둘 다 무작위로 보일 경우 안쪽 계층이 바깥 계층이 되돌릴 수 없는 일을 하고 있다는 것을 알 수 있습니다.
실제로 부여한 신뢰를 검토하라
설치된 기업 루트 인증서는 클라이언트의 신뢰 저장소에 관한 사실이며, 어떤 프록시가 무엇을 기록하거나 검사하는지에 대한 선언이 아닙니다. CA의 존재로 행동을 추론하는 대신 배포된 정책과 실제 연결 경로를 확립하십시오.
관리되는 장비에서는 어떤 구성 요소가 TLS를 종단하는지, 클라이언트가 고정된 인증서를 검증하는지 공개 인증서를 검증하는지, 페이로드 형식은 무엇인지 관리자에게 물으십시오. 그 세 가지 답이 나중에 방어할 수 있는 발견이 됩니다.
결과를 판결이 아니라 경계로 쓰십시오. "TLS는 검사 프록시에서 종단되고, 안쪽 페이로드는 종단점만 가진 키로 별도 암호화되어 있다"는 공급업체가 바뀌어도 살아남는 검증 가능한 진술입니다. "WebSockets는 안전하다"는 그렇지 않습니다.