요약

  • ALPN은 애플리케이션 프로토콜 선택을 TLS 핸드셰이크 안에 넣어, 여러 프로토콜이 하나의 엔드포인트와 포트를 공유할 때 별도의 협상 왕복을 피하게 했다.
  • 클라이언트는 순서가 정해진 불투명 식별자 목록을 광고하지만, 서버는 자신의 정책에 따라 교집합에서 프로토콜 하나를 선택한다; 공통 선택이 없으면 무음한 임기응변이 아니라 치명적 실패가 요구된다.
  • 선택된 프로토콜은 재개 가능한 TLS 세션이 아니라 하나의 연결에 속한다. 이전 연결의 티켓은 옛 문법을 앞으로 끌고 갈 수 없으며, 성공적인 선택 자체가 오리진을 인증하거나 애플리케이션 작업을 승인하지 않는다.

오래된 티켓이 새 회선으로 돌아왔을 때

클라이언트가 익숙한 서비스에 다시 접속하는 장면을 상상해 보자. 클라이언트는 이전 TLS 연결에서 발급된 유효한 세션 티켓을 제시한다. 그 옛 연결은 HTTP/2를 사용했다. 서버는 여전히 티켓을 인식하므로 일부 암호적 수립 작업은 단축될 수 있다.

티켓을 대화 전체의 기억으로 취급하고 싶어진다. 클라이언트와 서버는 지난번에 HTTP/2로 대화했다; 왜 다시 물어야 하는가?

티켓이 새 연결의 애플리케이션 문법을 소유하지 않기 때문이다. 엔드포인트는 이제 다른 프로토콜을 선호할 수 있다. 클라이언트의 허용 집합이 바뀌었을 수도 있다. 로드 밸런서는 재개를 서로 다른 배포 상태를 가진 노드로 라우팅할 수 있다. 암호적 재개가 유효하더라도, 첫 애플리케이션 바이트의 의미는 그 바이트가 실려 갈 회선에 맞춘 결정이 여전히 필요하다.

2014년 ALPN 명세인RFC 7301은 이 점을 보기 드물게 분명하게 말한다. 이 확장은 세션이 아니라 연결의 속성을 수립한다. 재개나 세션 티켓을 사용할 때 이전 ALPN 내용은 무관하다. 새 핸드셰이크의 값만이 유효하다.

이 경계가 이 메커니즘의 가장 깊은 기여다. 재사용은 안전하게 재사용할 수 있는 것만 보존하며, 파서, 서비스 역할, 미래 정책 결정을 몰래 상속하지 않는다.

포트 번호는 더 이상 충분한 답이 아니었다

인터넷 역사의 대부분 동안 포트 번호는 전송 계층 위의 애플리케이션에 대한 실용적 단서였다. 한 포트로의 연결은 하나의 익숙한 문법을 실을 것으로 기대됐다. TLS는 이 편리한 추론을 유용한 방식으로 약화시켰다. 많은 애플리케이션 프로토콜이 보호받을 수 있고, 특히 443 포트에서 인프라를 공유할 수 있었다.

공유는 모호성을 만들었다. TLS가 완료된 후, 보호된 스트림을 어떤 애플리케이션 프로토콜이 소비해야 하는가? 애플리케이션 계층에서 두 번째 협상으로 답할 수 있지만, 네트워크 왕복이 하나 더 든다. 포트에서 추측하면 공유의 이유가 무색해진다. 애플리케이션 바이트를 먼저 보내고 어느 파서가 수용하는지 기다리는 방식은 실패를 비싸게 만들고, 일부 조합에서는 위험하게 만든다.

ALPN은 선택을 이미 존재하는 핸드셰이크 안으로 옮겼다. 보편적 애플리케이션 중개자를 요구하지 않았다. 연결을 수립 중인 두 엔드포인트 사이에 작은 교환을 추가했을 뿐이다.

RFC 8170의 역사적 기술은 당장의 압력을 기록한다: HTTP/2는 다른 왕복 없이 보호된 형태를 협상할 방법이 필요했다. HTTP Upgrade는 보안 없는 변형을 다뤘고; ALPN은 TLS 위에서 미래 HTTP 버전을 협상하는 주된 메커니즘이 되었다. 중요한 변화는 단순히 속도가 아니었다. 프로토콜 신원이 수립 후의 추론이 아니라 명시적 핸드셰이크 결과가 된 것이다.

클라이언트는 집합을 제시했지, 명령을 내리지 않았다

클라이언트의 ALPN 확장은 비어 있지 않은 불투명 프로토콜 이름의 목록을 담는다. 목록은 클라이언트 선호 순서로 정렬된다. 그 순서는 클라이언트가 무엇을 말하기 바라는지에 대한 유용한 증거이지만, 서버에 대한 명령은 아니다.

서버는 자신의 지원 집합과 자신의 선호 순서를 갖는다. 클라이언트가 제시한 프로토콜 중에서 자신이 가장 선호하는 것을 선택하는 것이 기대된다. 따라서 허용되는 답은 교집합이다: 서버는 클라이언트 목록에 없는 프로토콜을 선택할 수 없고, 클라이언트의 첫 항목이 서버의 로컬 정책을 반드시 이겨야 하는 것도 아니다.

이 배치는 통제를 깔끔하게 나눈다. 클라이언트는 자신이 파싱할 준비가 된 문법의 경계를 통제한다. 서버는 이 연결에서 어떤 상호 지원 서비스를 운영할 의사가 있는지를 통제한다. 어느 쪽도 상대의 동의를 만들어 낼 수 없다.

응답에는 메뉴가 아니라 프로토콜 하나가 담긴다. 일단 선택되면 그 식별자는 해당 연결에서 확정적이다. 서버는 한 문법을 광고해 놓고 다른 문법으로 애플리케이션 데이터를 보내서는 안 된다. 선택이 가치 있는 이유는 어느 애플리케이션 파서가 스트림을 받기 전에 모호성을 제거하기 때문이다.

교집합이 없다는 것은 결과이지, 추측의 초대가 아니었다

두 지원 집합이 교차하지 않으면 RFC 7301은 서버에게 치명적no_application_protocol경보를 보내도록 요구한다. 호환성 폴백에 비하면 불친절하게 느껴질 수 있다. 실제로는 가능한 가장 진실한 결과다.

무음한 폴백은 클라이언트에게 부재의 의미가 구형 서버인지, 무시된 확장인지, 미들박스 상호작용인지, 아니면 의도적인 기본 문법 선택인지 불확실하게 남긴다. 이후 엔드포인트들이 같은 암호화된 바이트를 서로 다른 프로토콜로 해석하면, 연결은 암호적으로는 수립되었으나 의미적으로는 깨진 상태가 된다.

실패는 그 불일치를 애플리케이션 데이터 앞에서 끝내준다. 결함을 관찰 가능하게 만들기도 한다. 운영자는 "공통 프로토콜 없음"을 인증서 실패, 전송 손실, 애플리케이션 거부, 무효한 첫 프레임과 구별할 수 있다. 형식화된 중단은 원래 연결이 성공한 것처럼 꾸미지 않고도 설정을 바꾸거나 다르게 제약된 연결을 열 기회를 보존한다.

이후 보안 지침은 이 경계를 더 시급하게 만들었다.RFC 9325는 최신 TLS 구현이 ALPN을 지원할 것을 요구하고, 제시된 목록과 치명적 교집합 없음 규칙의 엄격한 집행을 권고한다. 그 관심사는 교차 프로토콜 혼동이다: 한 서비스를 위한 데이터가 다른 서비스에 의해 파싱되면 의도치 않은 효과를 낳을 수 있다. ALPN이 그런 공격 전부에 대한 완전한 방어는 아니지만, 제시되지 않은 프로토콜을 수용하는 것은 엔드포인트가 이미 갖고 있는 보호를 버리는 셈이다.

초기 설계는 그 답을 노출했다

RFC 7301은 서버가 선택한 프로토콜을 당시 사용되던 TLS ServerHello에 배치했다. 포트 번호가 더 이상 애플리케이션을 식별하지 못하는 상황에서 차등 처리를 하는 네트워크 요소들이 그 표식을 볼 수 있도록 만든 것이다. 문서는 또한 클라이언트 프로토콜 식별자가 민감한 정보를 누출할 수 있으며, 보이는 상태에서 함부로 사용해서는 안 된다고 경고했다.

이는 본래 비밀인 메커니즘의 우연한 누설이 아니었다. 설계는 암호화된 애플리케이션 스트림이 처음부터 프로토콜 선택을 숨긴다고 주장하는 대신 자신의 가시성을 인정했다.

TLS 1.3은 그 증거 표면의 일부를 바꿨다.RFC 8446에서 클라이언트는 여전히 ClientHello에서 ALPN을 제시하지만, 서버의 응답은 핸드셰이크 트래픽 키로 보호되는 첫 서버 메시지인 EncryptedExtensions에 나타난다. 관찰자의 시야는 따라서 TLS 버전과 핸드셰이크 경로에 따라 달라진다.

안전한 결론은 정밀하다. TLS 1.3은 그 단계에서 서버가 선택한 ALPN 값을 통상적으로 보호한다. 그러나 기준 ClientHello 제시가 사라지지 않으며, ALPN이 전적으로 공개이거나 전적으로 사적이라는 무시대적 주장을 정당화하지도 않는다.

HTTP/2는 문법을 선택한 뒤 그것을 확인했다

HTTP/2는 이 메커니즘에 구체적 형태를 준다.RFC 9113은 TLS 위의 HTTP/2에h2를 할당하고, 보호된 HTTP/2 연결이 ALPN을 사용할 것을 요구한다. 이전h2c토큰은 평문 형태를 기술하며 TLS ALPN에서 전송하거나 선택해서는 안 된다.

그러나 ALPN 결과가 일반 요청 전에 마지막으로 교환되는 것은 아니다. TLS 협상이 완료되면 양쪽 HTTP/2 엔드포인트는 연결 프리페이스를 보낸다. 클라이언트 프리페이스는 의도적으로 식별 가능한 옥텟 시퀀스와 SETTINGS 프레임으로 시작하고; 서버는 자신의 SETTINGS 프레임으로 시작한다.

선택과 확인은 서로 다른 역할을 한다. ALPN은 어떤 문법이 시작될 수 있는지에 합의한다. 프리페이스는 뒤따르는 바이트가 실제로 그 문법을 따르고 초기 매개변수를 수립한다는 것을 증명한다. 하나만 기록하는 운영자는 중요한 증거를 잃는다: 선택된h2값은 무효한 프리페이스를 설명할 수 없고, 핸드셰이크 없이 캡처된 프리페이스는 양 엔드포인트가 TLS 아래 HTTP/2에 합의했음을 보여줄 수 없다.

조기 데이터는 바뀐 의미를 앞지르지 못했다

TLS 1.3은 적격 재개에서 클라이언트가 핸드셰이크가 끝나기 전에 조기 애플리케이션 데이터를 보낼 수 있게 한다. 이 성능 기능은 ALPN의 연결 범위를 철학적 문제가 아니라 운영적 문제로 만든다.

HTTP/2를 기대하며 준비된 조기 바이트가 있는데 새 연결이 다른 프로토콜을 선택했다고 하자. 그 바이트를 자동으로 재전송하면, 그 문법으로 작성된 적이 전혀 없는 애플리케이션 동작을 그 문법에 흘려 넣게 된다. 따라서 RFC 8446은 협상된 연결이 같은 ALPN 프로토콜을 선택하지 않는 한 TLS 구현이 조기 데이터를 자동으로 재전송해서는 안 된다고 규정한다.

"같은 ALPN"은 필요 조건의 경계일 뿐이다. 그것이 재전송이 무해함을, HTTP 메서드가 멱등함을, 자격 증명이 여전히 적절함을, 애플리케이션 작업이 이미 처리되지 않았음을 증명하지는 않는다. 그 질문들은 애플리케이션과 그 재전송 정책에 속한다. ALPN은 특히 심각한 한 범주의 오류—프로토콜 의미가 바뀌는 지점을 가로질러 바이트를 자동으로 옮기는 오류—를 방지한다.

세션 티켓은 재개를 지원할 수 있다. 어제의 애플리케이션 결정이 오늘도 유효하다는 것을 보증할 수는 없다.

QUIC은 선택을 전송 수립의 일부로 만들었다

ALPN은 즉각적인 HTTP/2 동기의 범위를 넘어 성장했다. QUIC은 TLS를, 그 위의 애플리케이션들이 인증된 프로토콜 선택도 필요로 하는 전송 계층에 통합한다.RFC 9001은 다른 메커니즘이 합의를 제공하지 않는 한 QUIC 엔드포인트가 ALPN을 사용할 것을 요구하고, 애플리케이션 프로토콜이 협상되지 않으면 즉시 종료할 것을 요구한다.

QUIC은 또 하나의 호환성 차원을 추가한다: 애플리케이션 프로토콜이 사용할 수 있는 QUIC 버전을 제한할 수 있다. 서버는 클라이언트가 선택한 QUIC 버전과 호환되는 프로토콜을 선택해야 하며, 어느 엔드포인트든 호환되지 않는 결과를 동일한 no-application-protocol 계열의 연결 오류로 다룬다.

이것이 선택을 트래픽 대시보드용 라벨로 환원할 수 없는 이유를 보여준다. 선택은 파싱 규칙을 그 규칙을 실을 전송 인스턴스에 연결한다. 등록된 식별자는 HTTP/3, DNS over QUIC 또는 다른 애플리케이션을 이름 지을 수 있지만, 선택된 이름이 힘을 갖는 것은 양 엔드포인트가 애플리케이션 교환 전에 그것을 호환되는 연결에 묶기 때문이다.

레지스트리는 바이트를 고정했지, 현실을 고정하지 않았다

ALPN 프로토콜 이름은 불투명한 바이트 문자열이다. 상호운용성은 두 독립 구현이 같은 명시된 프로토콜에 대해 같은 바이트를 사용할 것을 요구한다. 현재의IANA TLS 확장 및 ALPN 레지스트리는 전문가 검토(Expert Review) 아래 그 공유 네임스페이스를 제공한다.

표에는http/1.1,h2,h3같은 익숙한 값이 들어 있다. 또한h2c를 예약 식별자로 보존하면서 TLS ALPN에서는 허용되지 않는다고 명시한다. 이 조합은 시사적이다: 등록은 한 맥락에서 그 사용을 금지하더라도 이름과 그 경계를 보존할 수 있다.

레지스트리 행은 배포 카운터가 아니다. 브라우저가 식별자를 제시하는지, 서버가 선택하는지, 트래픽이 올바른 애플리케이션에 도달하는지, 그 애플리케이션이 안전한지를 보여주지 않는다. 그것은 더 좁은 사실을 증명한다: 한 바이트 시퀀스에 할당된 설명과 참조가 존재하여, 구현자가 비공개로 경쟁하는 표기를 발명할 필요가 없다는 것.

그 선택은 만료되었기 때문에 강했다

ALPN은 오래 지속되는 보안 세션의 기억된 속성으로 설계될 수도 있었다. 실제 범위는 더 규율적이다. 모든 새 연결은 새 제시와 새 선택을 얻는다. 서버는 선호를 바꿀 수 있다. 클라이언트는 낡은 프로토콜을 제거할 수 있다. 혼합 플릿은 자신의 불일치를 드러낸다. 실패한 교집합은 애플리케이션 상태를 오염시키지 않고 멈출 수 있다.

그 만료는 낭비되는 협상이 아니다. 어제의 호환성 결정이 내일의 엔드포인트에 권위를 얻는 것을 막는 장치다. 같은 세션 티켓, 주소, 인증서가 다른 연결에 참여하면서 애플리케이션 문법은 다시 결정될 수 있다.

인터넷은 시간을 절약하려고 상태를 재사용하는 경우가 흔하다. 안전한 재사용은 어떤 결정이 그 상태와 함께 이동할 수 있는지 아는 데 달려 있다. ALPN은 그 선을 특히 분명하게 그었다: 암호적 재개는 계속될 수 있지만, 새 연결에서 사용될 프로토콜은 그것을 사용할 엔드포인트들이 여전히 직접 선택해야 한다.

출처

이 출처들은 표준, 권고, 레지스트리 상태를 정의한다. 현재 배포 점유율, 트래픽 통계 또는 특정 제품 구성에 대한 증명을 제공하지는 않는다.