본문으로 건너뛰기
AZ Tools

SVCB / HTTPS 레코드 생성·해독기

SVCB·HTTPS 레코드를 정규화·인코딩·검사합니다. SvcParams 해독, 와이어 바이트 분해, 그리고 위반한 RFC 9460 조항을 이름으로 지적합니다.

예시:

모드: ServiceMode (우선순위 1) — 숫자가 작은 쪽을 먼저 시도하고, 같은 숫자끼리는 부하 분산될 수 있습니다.

위반 사항 없음.

정규화된 표현 형식

1 . alpn="h3,h2" ipv4hint="192.0.2.1" ech="AEX+DQBBzQAgACD4"

존 파일 한 줄

example.com. 3600 IN HTTPS 1 . alpn="h3,h2" ipv4hint="192.0.2.1" ech="AEX+DQBBzQAgACD4"

와이어 형식 (hex)

0001000001000602683302683200040004c00002010005000c0045fe0d0041cd00200020f8

와이어 형식은 SvcParamKey를 오름차순으로 정렬하지만 표현 형식은 그렇지 않아서 두 순서가 다를 때가 많습니다. 이는 명세이고, 임의로 바꿔 쓴 것이 아닙니다.

바이트 분해
0001  SvcPriority (2바이트)
00  TargetName, 압축 없음
00010006026833026832  alpn (key 1)
00040004c0000201  ipv4hint (key 4)
0005000c0045fe0d0041cd00200020f8  ech (key 5)
해독된 SvcParams
키이름값
1alpnh3,h2
4ipv4hint192.0.2.1
5echAEX+DQBBzQAgACD4

사용법

  1. RDATA를 붙여 넣으세요. 우선순위, 대상 이름, 그다음 SvcParams입니다. 와이어 바이트를 hex로 붙여 넣으면 대신 디코딩합니다. 예시 버튼 네 개는 ECH가 붙은 전형적 HTTPS 레코드, AliasMode 레코드, DoH용 SVCB 레코드, 그리고 의도적 오류 두 개가 들어간 레코드입니다.
  2. 존 파일에 그대로 붙일 한 줄이 필요하면 소유자 이름, TTL, 레코드 종류를 설정하세요. SVCB와 HTTPS는 와이어 형식을 공유하므로 종류를 바꿔도 바이트는 변하지 않고 그 줄만 바뀝니다.
  3. 위반 항목을 먼저 읽으세요. 각 항목이 근거가 되는 RFC 9460 절을 함께 알려 주는데, "잘못된 레코드"라고만 말하는 검증기와의 논쟁을 끝내는 가장 빠른 방법입니다.
  4. 바이트 분해를 보면 각 파라미터가 어디서 시작하고 값이 몇 바이트인지 보입니다. 등록기관 양식은 거부한 레코드를 리졸버는 받아들이거나 그 반대인 상황에서 필요한 화면입니다.

자세한 설명

펼치기

SVCB(타입 64)와 웹 전용 쌍둥이인 HTTPS(타입 65)는 예전에 CNAME 하나에 문서 밖 지식을 더해야 했던 것을 한 레코드에 담습니다. 서비스가 말하는 ALPN 프로토콜, 포트, 주소 힌트, 그리고 ECH를 가능하게 하는 암호화된 client hello 설정입니다. 둘은 와이어 형식을 공유하며, 이 레코드에서 잘못되는 것은 거의 전부 다른 쪽이 파싱할 때까지는 멀쩡해 보이는 형식 세부 사항입니다. 이 페이지는 레코드를 정규화하고, 인코딩하고, 바이트를 분해하고, 위반한 조항을 해당 절과 함께 지적합니다.

첫째로 맞춰야 하는 것은 모드입니다. 우선순위 0은 AliasMode로, 대상이 별칭이며 SvcParam은 하나도 허용되지 않습니다. 1 이상은 ServiceMode이고, 숫자가 작은 쪽을 먼저 시도하며 같은 숫자끼리는 부하 분산될 수 있습니다. 우선순위가 0인데 alpn이 붙은 레코드는 필드가 하나 더 있는 레코드가 아니라 무효한 레코드이고, 이 페이지는 그것을 조용히 인코딩하지 않고 지적합니다.

둘째는 순서입니다. 와이어에서는 SvcParamKey가 번호 오름차순으로 나와야 하고 중복될 수 없지만, 표현 형식에서는 순서가 자유입니다. 그래서 1 . port=443 alpn="h2"와 1 . mandatory=port,alpn alpn="h2" port=443은 모두 키 0, 1, 3 순서의 바이트로 인코딩되고, 이 페이지가 출력하는 정규화 텍스트도 정렬된 상태로 돌아옵니다. 존 파일과 dig 응답의 순서가 다르다면 어느 쪽도 틀린 것이 아닙니다.

셋째는 이스케이프인데, 쉼표로 구분되는 값이 두 계층을 지나기 때문에 거의 모두가 여기서 걸립니다. 표현 값은 먼저 RFC 1035 문자열로 해제되어 역슬래시가 다음 문자를 이스케이프하고 세 자리 \DDD는 한 바이트가 됩니다. 그 결과를 쉼표로 나누는데, 이 계층에서는 역슬래시가 쉼표를 이스케이프합니다. 그래서 alpn="h2\,h3"는 프로토콜 두 개입니다. 첫 계층이 역슬래시를 먹어 버리고 둘째 계층은 평범한 구분자를 보기 때문입니다. 반면 alpn="h2\\,h3"는 h2,h3라는 이름의 프로토콜 하나입니다. \xNN 이스케이프도 없습니다. alpn="h2\x2ch3"는 h2x2ch3라는 프로토콜 하나입니다.

감추지 않고 처리하는 작은 경계들. SVCB rdata 안의 대상 이름은 DNS 압축을 쓰지 않으므로 항상 전체가 나옵니다. 알 수 없는 키는 값 없이 쓸 수도 있고 빈 값으로 쓸 수도 있으며, key65535와 key65535=""는 같은 4바이트입니다. mandatory는 자기 자신을 나열할 수 없고, 없는 키를 지목할 수 없으며, 정렬되어 돌아옵니다. alpn 없는 no-default-alpn은 무효입니다. 그리고 IPv6 힌트는 주소에 실제로 IPv4가 박혀 있을 때만 점 표기로 출력됩니다. 0 그룹이 정확히 여섯 개 연속이거나, 다섯 개 뒤에 ffff가 오는 경우입니다. 그래서 ::0.0.0.1은 ::1로 돌아오는데 ::192.0.2.1은 점을 유지합니다.

이 페이지가 알려 줄 수 없는 것은 그 레코드가 실제로 동작하는지입니다. 주소 힌트는 힌트입니다. RFC 9460은 A와 AAAA 레코드를 여전히 필요하게 두고, 리졸버는 힌트를 완전히 무시해도 됩니다. ech 값은 base64인지만 검사하며, 그 안의 키가 서버와 맞는지는 DNS가 아니라 TLS의 문제입니다. 그리고 문법적으로 완벽한 HTTPS 레코드라도 클라이언트가 조회하는 이름에 놓여 있지 않다면 아무 일도 하지 않습니다.

자주 묻는 질문

SVCB와 HTTPS 레코드의 차이는 무엇인가요?

타입 번호와 놓는 위치뿐입니다. SVCB는 타입 64이고 일반형이어서, 특정 프로토콜을 위해 _dns.example.com처럼 접두사가 붙은 이름에 놓습니다. HTTPS는 타입 65이고 HTTP에 한정되며, 이름 자체에 놓여서 브라우저가 접두사 없이 바로 조회할 수 있습니다. RDATA 형식은 바이트 단위로 동일하고, 그래서 이 페이지는 둘을 같은 방식으로 인코딩하며 존 파일 줄만 달라집니다.

왜 파라미터 순서가 바뀌어서 돌아오나요?

와이어 형식은 SvcParamKey 오름차순을 요구하고 표현 형식은 그렇지 않기 때문입니다. RFC 9460 2.2절이 정렬된 순서를 인코딩의 일부로 정해 두었으므로, 텍스트를 어떻게 썼든 바이트는 같고, 이 페이지는 바이트가 쓰는 순서대로 텍스트를 다시 출력합니다. 키가 아예 중복되는 것은 두 형식 모두에서 무효입니다.

ALPN 목록이 프로토콜 하나가 되거나 둘이 되는 이유는?

쉼표로 구분되는 값이 두 번 이스케이프 해제되기 때문입니다. 값 전체가 먼저 RFC 1035 문자열로 읽히면서 역슬래시 하나가 그 단계에서 소비되고, 그 결과를 쉼표로 나누는 단계에서 역슬래시가 쉼표를 이스케이프합니다. 따라서 값 안에 들어가야 하는 쉼표는 존 파일에서 역슬래시 두 개가 필요합니다. 그래서 alpn="h2\,h3"는 프로토콜 둘이고 alpn="h2\\,h3"는 h2,h3라는 이름의 프로토콜 하나입니다.

AliasMode 레코드에 SvcParams를 넣을 수 있나요?

없습니다. 우선순위 0은 AliasMode이고 RFC 9460 2.4.2절은 여기에 SvcParam을 전혀 허용하지 않습니다. 이 레코드는 CNAME이 하듯 다른 이름을 가리키기 위해 존재하며, CNAME이 허용되지 않는 존 apex에서도 쓸 수 있습니다. 일부 권한 서버는 여분의 파라미터를 받아들이고 조용히 버리는데 이는 오류보다 나쁘므로, 이 페이지는 위반으로 보고합니다.

ipv4hint와 ipv6hint가 A·AAAA 레코드를 대체하나요?

아니며, 대체로 취급하는 것이 가장 흔한 배포 실수입니다. RFC 9460 7.3절은 힌트가 왕복 한 번을 줄이는 최적화이고 클라이언트가 무시할 수 있으며 A와 AAAA 레코드가 여전히 존재하고 일치해야 한다고 명시합니다. 또한 힌트는 주소가 아니라 SVCB 레코드와 함께 캐시되므로, TTL이 긴 레코드는 A 레코드가 옮겨 간 뒤에도 오래된 주소를 품고 있을 수 있습니다.

관련 도구