SVCB, HTTPS RR에 대해

SVCB, HTTPS RR에 대해

SVCB(Service Binding, 서비스 바인딩), HTTPS RR(Resource Record, 리소스 레코드)에 대해 간략히 알아보자.

Prerequisite: Service(SRV) record

SVCB가 왜 나왔는지 알려면 SRV(Service, 서비스) 레코드를 먼저 알아야 한다.

DNS SRV 레코드는 특정 서비스의 호스트 및 포트를 반환한다.

아래는 tcp 프로토콜을 쓰는 xmpp 서비스를 위한 SRV 레코드 예시다.

_xmpp._tcp.example.com. 86400 IN SRV 10 5 5223 server.example.com.

mongodb, mysql 등 failover가 필요한 시스템은 srv 레코드를 보통 쓴다.


아쉽게도 브라우저를 포함한, 대부분의 HTTP 클라이언트에서는 SRV 레코드가 무시된다.

Applicability Statement

In general, it is expected that SRV records will be used by clients for applications where the relevant protocol specification indicates that clients should use the SRV record. Such specification MUST define the symbolic name to be used in the Service field of the SRV record as described below.
It also MUST include security considerations. Service SRV records SHOULD NOT be used in the absence of such specification.
- RFC2782

_http._tcp SRV 레코드를 지원하면 되는데.. 문제는 SRV record의 RFC에서는 서비스명을 지정하는 RFC(즉 여기선 HTTP RFC)에 꼭 서비스 심볼과 보안 고려사항 등을 명시하라고 나와 있는데, HTTP RFC에는 딱히 명시가 되어 있지 않다.

그래서 http srv draft가 여러번 나왔지만 적용되지는 않았다.

왜 브라우저엔 적용이 거의 되지 않았는가, 추가적인 내용이 궁금하면 아래 링크를 참고해본다.

RFC 9460: Service Binding and Parameter Specification via the DNS (SVCB and HTTPS Resource Records)

이 RFC에서는 SVCB(Service Binding), HTTPS RRs(Resource Records)에 대해 정의하고 있다.

SVCB 리소스 레코드는 SRV 레코드와 비슷한 역할을 하는데 포트 외 여러가지 속성도 넣을 수 있는 등 좀 더 다양한 용도로 활용할 수 있다. 또한 특정 용도에 국한된 게 아니고, 규칙만 맞다면 SVCB-compatible한 여러 리소스 레코드를 만들어 확장할 수 있다.

HTTPS RR은 SVCB-Compatible한 resource record로, RFC section 9에서 구체적 사용 예를 다루고 있다. HTTPS RR 표현 형태는 아래와 같다.

Name TTL IN HTTPS SvcPriority TargetName SvcParams

dig로 확인해보기

dig로 SVCB 리소스 레코드를 확인할 수 있는데, bind 9.16.21 버전부터 지원이 추가되었다.

$ dig -v
DiG 9.20.1

$ dig example.com. SVCB
...
;; ANSWER SECTION
example.com.   300   IN   SVCB   0   example.org.

h3 지원하는 사이트에 HTTPS 레코드를 확인해보면 아래처럼 alpn(Application Layer Protocol Negotiation) 정보가 들어 있을 것이다.

$ dig cloudflare.com HTTPS
...
;; ANSWER SECTION:
cloudflare.com.		128	IN	HTTPS	1 . alpn="h3,h2" ipv4hint=104.16.132.229,104.16.133.229 ipv6hint=2606:4700::6810:84e5,2606:4700::6810:85e5

domain apex + HTTPS RR?

사실 이번 주말에 SVCB를 좀 조사해본 근본적인 이유는 domain apex 때문이었다.

domain apex에는 CNAME 레코드를 추가할 수 없는데, 만약 domain apex를 GitHub Pages, Netlify 등 다른 서비스에 붙이고 싶은 경우 A, AAAA 레코드로 추가해줘야 하는데 하드코딩이라 좀 번거로운 면이 있었다.

그리고 사실 대안도 없다. 어떤 네임서버에서는 ALIAS, ANAME 이라는 비표준 레코드 타입을 지원하기도 하지만, 권장되지는 않는다. ANAME은 Internet Draft에서 만료된 상태이기도 하다 (참고: https://datatracker.ietf.org/doc/draft-ietf-dnsop-aname/)

GitHub Pages 커스텀 도메인 문서에서는 비표준 DNS 레코드를 쓰라고 써있다. HTTPS 리소스 레코드가 모든 브라우저에서 100% 지원되지 않는 한 이게 최선일지도.

그런데 이제 RFC 9460이 Proposed Standard 상태가 되기도 했고, 여러 오픈소스 및 Cloudflare 등 네임서버에서 SVCB, HTTPS RR를 지원하기 시작했다.

참고로 HTTPS RR AliasMode(CNAME과 비슷)는 아래처럼 설정하면 된다.

HTTPS RR 예시. 기쁜 마음을 품고 테스트 해봤으나 크롬에서는 리졸빙에 실패한다.

하지만 HTTPS RR이 모든 브라우저에서 지원되는 것은 아니었다..

💡
글 작성일(2024-09-02) 기준 macOS에서 브라우저 별 HTTPS RR 지원 현황은 아래와 같다

- Safari: 지원됨
- Firefox: DoH(DNS-over-HTTP) 사용할 때만 지원
- Chrome: 일부만 지원 (포트가 다르거나, 도메인이 다르거나 등등 여러 부분 미구현)

내가 필요했던 부분은 단순히 CNAME 처럼 AliasMode가 필요했는데, Chromium에서 현재는 도메인이 다르면 HTTPS 레코드를 무시하게 된다. 따라서 HTTPS 레코드만 달랑 있으면 리졸빙에 실패한다.. 🥲

chromium dns_response_result_extractor.cc

크로미움에 관련 이슈도 열린 상태다. RFC Proposed Standard도 되었으니.. 빨리 지원됐으면 하는 바람이다.

참고로 크롬은 chrome://net-internals/#dns 페이지에서 DNS lookup만 따로 테스트해볼 수도 있다.

크롬은 HTTPS RR만 있을 때 DNS lookup에 실패한다