사전 리소스 레코드
포맷

리소스 레코드

gabury1

도메인 이름 하나에 딸린 데이터 한 벌입니다. 어떤 이름의 무엇이고 얼마나 오래 써도 되는 값인지를 함께 적습니다. 도메인 네임 시스템 응답이 실어 나르는 것이 바로 이 한 벌입니다.

쉽고 빠른 이해

도메인 이름 하나에 딸린 값 한 벌을 적는 단위입니다. 어떤 이름에 인터넷 주소 10.1.0.52 를 매다는 것이 레코드 한 개입니다. 인터넷 주소가 하나 더 있으면 레코드도 하나 더 있어야 합니다.

이름·종류·유효기간 같은 고정 자리를 값 앞에 붙여 둡니다. 그래야 값의 뜻을 몰라도 다음 레코드로 건너뛸 수 있고, 캐시에 얼마나 오래 남겨도 되는지도 알 수 있습니다. 이 고정 자리가 없으면 소프트웨어마다 나오는 모든 종류를 미리 알아야만 메시지를 처리할 수 있습니다.

놓이는 순서는 이렇습니다.

  1. 이름·종류·유효기간 같은 고정 자리 뒤에 값이 붙습니다. 값의 길이는 정해져 있지 않습니다
  2. 값 앞에 길이가 먼저 나옵니다. 뜻을 몰라도 그 길이만큼 건너뛰어 다음 레코드로 갈 수 있습니다
  3. 값을 캐시에 얼마나 오래 남겨도 되는지는 유효기간 자리가 정합니다

대가는 유효기간이 최대치일 뿐 지켜진다는 보장은 없다는 것입니다. 레코드 하나는 이름과 종류가 같고 값이 하나일 때 씁니다. 값이 여러 개면 레코드도 그 수만큼 나눠야 합니다.

상세

도메인 이름은 노드 하나를 가리킵니다. 많은 네임서버가 이름 공간을 내부에서 트리나 해시 구조로 만들어 두는데, 그 구조 안의 자리 하나하나가 노드입니다. 노드마다 자원 정보 한 벌이 딸립니다. 그 한 벌은 비어 있을 수도 있습니다. 한 이름에 딸린 자원 정보는 낱낱의 리소스 레코드로 이루어집니다.

특정 레코드 하나를 이야기할 때 RFC(Request For Comments, 인터넷 표준 문서) 1034 는 그 레코드가 다음을 가진다고 가정합니다.

  • owner — 이 레코드가 발견되는 도메인 이름입니다.
  • type — 16비트로 부호화한 값입니다. 이 레코드에 든 자원의 종류를 정합니다. 타입은 추상적인 자원을 가리킵니다 — 예컨대 타입 A 는 「인터넷 주소」라는 자원의 종류를 가리킬 뿐이고, 실제 32비트 주소값은 RDATA 가 담습니다(「형태」에서 다시 다룹니다).
  • class — 16비트로 부호화한 값입니다. 프로토콜 계열이나 그 계열 안의 한 사례를 식별합니다. IN(Internet, 인터넷) 클래스가 한 예이고, CH 처럼 다른 프로토콜 계열을 위한 클래스도 정의될 수 있습니다(「예시」에 클래스가 갈리는 예가 있습니다).
  • TTL(Time To Live, 생존 시간) — 초 단위의 32비트 정수입니다. 주로 리졸버가 레코드를 캐시할 때 씁니다.
  • RDATA(Resource Data, 자원 데이터) — 자원을 기술하는 데이터입니다. 타입에 따라, 때로는 클래스에 따라 달라집니다.

owner 이름은 레코드의 온전한 일부를 이루기보다 암묵적인 경우가 잦습니다. 앞서 본 노드에 직접 레코드를 매다는 식입니다. 그러고 남는 부분이 모든 레코드에 한결같은 고정 헤더와 가변부입니다. 고정 헤더는 종류(type)·소속(class)·유효기간(TTL)이고 가변부는 기술하려는 자원에 맞춘 RDATA 입니다.

TTL 이 뜻하는 것은 이 레코드를 캐시에 얼마나 오래 둘 수 있는가의 시간 제한입니다. 존 안의 권위 데이터에는 이 제한이 걸리지 않습니다. 그쪽도 시간이 지나면 만료되지만 만료를 정하는 것은 존의 갱신 정책입니다. TTL 값은 데이터가 유래한 존의 관리자가 정합니다.

RDATA 는 이진 문자열과 도메인 이름의 조합으로 실려 갑니다. 여기 실린 도메인 이름은 DNS(Domain Name System, 도메인 네임 시스템) 안의 다른 데이터를 가리키는 값으로 자주 쓰입니다.

같은 레코드가 자리마다 다른 꼴로 나타납니다.

자리 꼴
DNS 프로토콜 패킷 안 이진
네임서버·리졸버 내부 저장 대개 고도로 부호화된 꼴
마스터 파일 대부분 한 줄짜리 텍스트. 괄호를 쓰면 여러 줄로 이어 적는다

마스터 파일에서 레코드 한 줄은 [<TTL>] [<class>] <type> <RDATA> 또는 [<class>] [<TTL>] <type> <RDATA> 꼴을 취합니다. 앞의 TTL 과 class 는 순서를 바꿔 적어도 되고 둘 다 생략해도 되며, type 과 RDATA 는 항상 그 뒤에 이 순서로 옵니다.

flowchart TD
  L["레코드 한 줄"] --> O["앞자리 둘 · TTL 과 class 어느 쪽이 먼저와도 되고 둘 다 생략 가능"]
  O --> T["type · 필수"]
  T --> R["RDATA · 필수, 언제나 마지막"]

클래스와 타입은 표준 니모닉(예: IN, A, MX)을 쓰고 TTL 은 십진 정수입니다. 생략한 클래스와 TTL 은 마지막으로 명시한 값을 기본값으로 삼습니다. 타입 니모닉과 클래스 니모닉은 서로 겹치지 않으므로 파싱 결과가 하나로 정해집니다. 명세는 이 문법(TTL 과 class 를 앞세우는 순서)이 예시나 실제 레코드에서 쓰는 순서와 다르다고 곧바로 적습니다 — 이 문법 순서를 고른 이유는 파싱과 기본값 적용이 수월해지기 때문입니다. 실제 예시는 대신 TTL·클래스·타입 순서로 적고, 타입 니모닉이 언제나 맨 마지막에 옵니다.

표현 한계

담지 못하는 것과 레코드 밖에 남는 것부터 봅니다.

TTL 의 부호와 범위

RFC 1035 안에서 TTL 의 부호가 세 자리에서 어긋납니다. 3.2.1 은 32비트 부호 있는 정수라고 적습니다. 4.1.3 은 32비트 부호 없는 정수라고 적습니다. 2.3.4 는 부호 있는 32비트 수의 양수 값이라고 적습니다.

RFC 2181 8 이 이 어긋남을 정리합니다. TTL 값은 부호 없는 수이고 최솟값은 0, 최댓값은 2147483647 입니다. 2의 31제곱에서 1 을 뺀 값입니다. 전송할 때 이 값은 32비트 TTL 필드의 덜 중요한 31비트에 부호화되고 최상위 비트, 곧 부호 비트는 0 으로 둡니다. 최상위 비트가 켜진 채로 받은 TTL 은 받은 값 전체가 0 이었던 것처럼 다루어야 합니다.

적어 넣은 수명이 지켜진다는 보장은 레코드 밖에 있습니다. 구현은 받은 TTL 에 상한을 둘 자유가 언제나 있고, 그보다 큰 값은 그 상한이었던 것처럼 다루어도 됩니다. TTL 이 정하는 것은 최대 수명이지 의무 수명이 아닙니다.

1초보다 짧은 수명을 적을 자리는 없습니다. TTL 은 초 단위 정수입니다. 값 0 은 이 레코드를 진행 중인 트랜잭션에만 쓰고 캐시해서는 안 된다는 뜻으로 해석됩니다. 극히 변덕스러운 데이터에도 0 을 쓸 수 있습니다. SOA(Start Of Authority, 시작 권한) 레코드는 캐싱을 막으려고 언제나 TTL 0 으로 배포됩니다.

RDATA 의 뜻과 길이

RDATA 는 자원을 기술하는 가변 길이 옥텟(8비트, 1바이트) 문자열입니다. 이 정보의 형식은 레코드의 TYPE 과 CLASS 에 따라 달라집니다. 그 형식이 무엇인지를 레코드 안에 적는 자리는 없습니다. TYPE 코드가 무엇을 뜻하는지 모르는 쪽은 RDATA 를 옥텟 덩이로만 나를 수 있습니다.

길이는 RDLENGTH 가 적습니다. RDATA 필드의 옥텟 길이를 적는 부호 없는 16비트 정수입니다. 명세는 RDATA 의 최대 크기를 따로 적지 않습니다. 16비트가 셀 수 있는 범위를 넘는 RDATA 는 길이를 적을 자리가 없다는 것이 이 정의에서 따라 나옵니다.

이름의 길이

라벨은 63 옥텟 이하입니다. 이름 전체는 255 옥텟 이하입니다.

라벨 제한은 부호화 방식에서 나옵니다. 메시지 안의 도메인 이름은 라벨의 나열로 표현됩니다. 라벨 하나는 길이 필드 한 옥텟과 그 수만큼의 옥텟으로 표현됩니다. 모든 길이 옥텟의 상위 두 비트는 0 이어야 하고, 남은 여섯 비트가 라벨을 63 옥텟 이하로 제한합니다.

이름 전체의 255 옥텟 제한은 구현을 단순하게 하려고 둔 것이라고 명세가 적습니다. 여기서 세는 옥텟에는 라벨의 옥텟과 라벨 길이 옥텟이 함께 들어갑니다. 모든 도메인 이름은 루트의 빈 라벨로 끝나므로 길이 옥텟 0 이 이름의 끝을 표시합니다.

TXT 의 문자열 토막

TXT(Text, 텍스트) 레코드의 RDATA 는 TXT-DATA 이고, 그 내용은 하나 이상의 <character-string> 입니다.

<character-string> 은 길이 옥텟 하나와 그 수만큼의 문자로 이루어집니다. 이진 정보로 다루어지며, 라벨의 길이 옥텟과 달리 상위 비트에 제한이 없어 8비트를 모두 씁니다.

packet-beta
title 문자열 토막(character-string)의 길이 옥텟
0-7: "길이값 · 8비트 전체(0~255)"

길이 옥텟 하나가 나타낼 수 있는 최댓값이 255 이므로 데이터부는 최대 255 옥텟이고, 길이 옥텟까지 합친 전체는 최대 256 옥텟입니다. 그보다 긴 텍스트는 토막 여럿으로 쪼개 담게 됩니다.

담긴 텍스트의 뜻은 레코드가 정하지 않습니다. 명세는 TXT 레코드가 설명 텍스트를 담는 데 쓰이며 그 텍스트의 의미는 그것이 발견된 도메인에 달렸다고 적습니다.

한 응답에 실리는 양

UDP(User Datagram Protocol, 사용자 데이터그램 프로토콜)로 나르는 메시지는 512 옥텟으로 제한됩니다. IP(Internet Protocol, 인터넷 프로토콜) 헤더와 UDP 헤더는 세지 않습니다. 더 긴 메시지는 잘리고 헤더에 그 사실을 알리는 비트가 켜집니다.

레코드 하나에 걸린 제한은 아닙니다. 대신 한 응답에 몇 벌을 실을 수 있는지가 여기서 정해집니다. 특정 owner 이름과 class 와 type 에 대한 질의는 딸린 레코드를 언제나 전부 돌려줍니다. 그 전부가 응답에 들어가지 못하면 응답은 앞서와 같은 방식으로(잘렸다는 뜻의 truncated) 표시해야 합니다.

예시

ISI.EDU 마스터 파일

RFC 1035 5.3 이 ISI.EDU 존을 정의하는 데 쓸 법한 파일을 보입니다. origin(파일을 읽을 때 상대 이름의 기준으로 삼는 이름)은 ISI.EDU 로 두고 읽습니다.

@   IN  SOA     VENERA      Action\.domains (
                                 20     ; SERIAL
                                 7200   ; REFRESH
                                 600    ; RETRY
                                 3600000; EXPIRE
                                 60)    ; MINIMUM

        NS      A.ISI.EDU.
        NS      VENERA
        NS      VAXA
        MX      10      VENERA
        MX      20      VAXA

A       A       26.3.0.103

VENERA  A       10.1.0.52
        A       128.9.0.32

VAXA    A       10.2.0.27
        A       128.9.0.33

줄 맨 앞의 @ 는 origin 을 그대로 쓴다는 표시이므로 여기서는 ISI.EDU 를 가리킵니다. SOA 뒤 괄호 안의 다섯 값(SERIAL·REFRESH·RETRY·EXPIRE·MINIMUM)은 SOA 레코드 자신의 RDATA 필드값이고, 각각의 뜻은 SOA 레코드 편이 다룹니다. 이어지는 세 줄의 NS(Name Server, 네임서버) 레코드는 이 존을 맡은 네임서버 이름을 적습니다.

VENERA A 10.1.0.52 한 줄이 레코드 하나입니다. 줄 맨 앞의 VENERA 가 owner 이고, A 가 타입이고, 10.1.0.52 가 RDATA 입니다. 바로 아래 A 128.9.0.32 줄은 빈칸으로 시작합니다. 빈칸으로 시작한 레코드는 마지막으로 명시된 owner 가 소유한 것으로 봅니다. 그래서 VENERA 라는 이름에 A 레코드가 둘 딸립니다. 인터넷 주소를 여럿 가진 호스트는 A 레코드를 여럿 가집니다.

클래스와 TTL 이 대부분의 줄에서 보이지 않습니다. 첫 줄의 IN 이 명시한 클래스가 뒤로 이어지고, 생략한 값은 마지막으로 명시한 값을 따릅니다.

메시지에 실린 여섯 레코드

RFC 1034 3.6.1 은 같은 표기로 메시지에 실린 레코드들을 보입니다.

ISI.EDU.        MX      10 VENERA.ISI.EDU.
                MX      10 VAXA.ISI.EDU.
VENERA.ISI.EDU. A       128.9.0.32
                A       10.1.0.52
VAXA.ISI.EDU.   A       10.2.0.27
                A       128.9.0.33

세 개의 도메인 이름에 두 개씩, 레코드 여섯입니다. MX(Mail eXchange, 메일 교환) 레코드의 RDATA 는 16비트 숫자 하나와 그 뒤에 오는 도메인 이름으로 이루어집니다. 주소 레코드(앞서 본 A 레코드)는 표준 IP 주소 형식으로 32비트 인터넷 주소를 담습니다. IN 클래스와 TTL 값은 명료함을 위해 예시에서 자주 생략됩니다.

클래스가 갈리는 경우도 같은 표기로 보입니다.

XX.LCS.MIT.EDU. IN      A       10.0.0.44
                CH      A       MIT.EDU. 2420

XX.LCS.MIT.EDU 하나에 주소가 둘입니다. 각각 클래스가 다릅니다. 클래스가 다르면 같은 타입이라도 RDATA 형식이 달라질 수 있습니다 — CH 클래스의 A 레코드는 IN 클래스의 A 레코드와 달리 도메인 이름과 숫자의 조합을 RDATA 로 가집니다.

이름의 옥텟 배치

RFC 1035 4.1.4 는 한 데이터그램이 F.ISI.ARPA, FOO.F.ISI.ARPA, ARPA, 루트를 쓸 때 그 이름들이 어떻게 놓일 수 있는지를 옥텟으로 보입니다. 메시지의 다른 필드는 무시하고 이름만 본 그림입니다.

메시지 안의 도메인 이름은 세 꼴 중 하나입니다 — 0 옥텟으로 끝나는 라벨의 나열이거나, 포인터이거나, 라벨의 나열 뒤에 포인터가 붙은 것입니다. 포인터는 이미 나온 라벨의 나열을 통째로 다시 적지 않고 그 시작 위치만 두 옥텟으로 가리켜 메시지 크기를 줄입니다. 포인터는 앞 두 비트가 1 입니다. 라벨은 63 옥텟 이하라 길이 옥텟이 0 으로 시작해야 하므로 이 둘이 구분됩니다. 10 과 01 조합은 나중을 위해 예약되어 있습니다. OFFSET 은 메시지 시작(헤더 ID 필드의 첫 옥텟)부터 센 옥텟 수입니다.

아래 그림들의 칸은 옥텟 하나씩이고, 칸 안에 적은 첫 수가 메시지 안 실제 옥텟 번호입니다.

오프셋 20 부터가 F.ISI.ARPA 입니다. 라벨마다 길이 옥텟이 앞서고 마지막의 0 옥텟이 루트의 빈 라벨입니다.

packet-beta
title F.ISI.ARPA — 오프셋 20부터
0-7: "20 · 길이 1"
8-15: "21 · F"
16-23: "22 · 길이 3"
24-31: "23 · I"
32-39: "24 · S"
40-47: "25 · I"
48-55: "26 · 길이 4"
56-63: "27 · A"
64-71: "28 · R"
72-79: "29 · P"
80-87: "30 · A"
88-95: "31 · 끝(0)"

오프셋 40 부터가 FOO.F.ISI.ARPA 입니다. 자기 라벨 FOO 를 적고 나서 두 옥텟짜리 포인터로 오프셋 20 을 가리킵니다. F.ISI.ARPA 를 다시 12 옥텟으로 안 적고 포인터 2 옥텟으로 대신하는 것이 이 압축이 아끼는 몫입니다.

packet-beta
title FOO.F.ISI.ARPA — 오프셋 40부터
0-7: "40 · 길이 3"
8-15: "41 · F"
16-23: "42 · O"
24-31: "43 · O"
32-47: "44~45 · 포인터 → 오프셋 20"

이 옥텟 배치는 앞의 마스터 파일 줄과 같은 레코드의 덤프가 아니라, 레코드의 owner 이름(NAME 필드)이 메시지 안에서 실제로 어떻게 압축되어 놓이는지를 보인 것입니다. 명세는 두 꼴을 각각 다른 자리에서 보입니다.

형태

모든 레코드가 같은 최상위 형식을 가집니다. DNS 메시지는 헤더 뒤에 여러 섹션을 둡니다. 응답 섹션과 권한 섹션과 추가 섹션이 이 형식을 함께 씁니다. 각 섹션에 레코드가 몇 개 실렸는지는 헤더의 해당 카운트 필드가 적습니다.

NAME 과 RDATA 가 가변 길이라 레코드 전체에는 고정된 비트 자리가 없습니다. 대신 여섯 필드가 아래 순서로, 아래 폭을 두고 이어 놓입니다. 이 여섯은 상세가 적은 고정 헤더 셋(종류·소속·유효기간)과 가변부(RDATA)에, owner 이름 자리(NAME)와 RDATA 의 길이 자리(RDLENGTH)를 더한 것입니다.

block-beta
columns 20
  n1["NAME · 가변"]:5
  n2["TYPE · 2옥텟"]:2
  n3["CLASS · 2옥텟"]:2
  n4["TTL · 4옥텟"]:4
  n5["RDLENGTH · 2옥텟"]:2
  n6["RDATA · 가변"]:5
필드 길이 무엇을 적나
NAME 가변 이 레코드가 딸린 도메인 이름. RFC 1035 3.2.1 은 이것을 owner name, 곧 이 레코드가 관계하는 노드의 이름이라고 적는다
TYPE 2 옥텟 RR(Resource Record, 리소스 레코드) 타입 코드 하나. RDATA 필드에 든 데이터의 뜻을 정한다
CLASS 2 옥텟 RDATA 필드에 든 데이터의 클래스
TTL 4 옥텟 이 레코드를 버리기 전까지 캐시해도 되는 시간 간격. 단위는 초
RDLENGTH 2 옥텟 RDATA 필드의 옥텟 길이. 부호 없는 16비트 정수
RDATA 가변 자원을 기술하는 가변 길이 옥텟 문자열

NAME 이 가변인 것은 이름이 라벨의 나열이거나 포인터이거나 그 둘의 조합이기 때문입니다. RDLENGTH 가 RDATA 앞에 놓이므로, 타입을 모르는 쪽도 RDATA 를 건너뛰어 다음 레코드로 갈 수 있습니다.

RDATA 의 형식은 레코드의 TYPE 과 CLASS 에 따라 달라집니다. TYPE 이 A 이고 CLASS 가 IN 이면 RDATA 는 4 옥텟짜리 인터넷 주소입니다. A 레코드의 RDATA 는 ADDRESS 필드 하나이고 32비트 인터넷 주소가 들어갑니다.

경계

RFC 2181 은 레코드를 label 과 class 와 type 과 data 넷으로 말합니다. 여기서 label 은 이름을 이루는 라벨 한 토막이 아니라 레코드의 owner 이름 전체이고, data 는 RDATA 입니다.

같은 label 과 class 와 type 을 가지고 data 만 서로 다른 레코드가 여럿 있습니다. 이 묶음도 리소스 레코드 하나인가. 아닙니다. 레코드 하나는 한 label·class·type 에 data 가 하나일 때 씁니다. data 가 여럿이면 레코드도 그 수만큼 여럿이어야 하고, 그 여럿을 레코드 하나로 합쳐 적을 자리는 없습니다. RFC 2181 은 그런 무리를 Resource Record Set 이라는 별도 이름으로 정의합니다.

근거는 두 갈래입니다.

첫째, 레코드의 동일성은 label, class, type, data 넷으로 판정됩니다. 넷이 모두 같은 레코드 둘이 존재하는 것은 무의미하고, 서버는 그런 중복을 만나면 억눌러야 합니다. 반면 대부분의 레코드 타입은 label 과 class 와 type 이 같고 data 만 다른 채로 존재할 수 있습니다. 그러니 묶음 안의 레코드들은 서로 다른 레코드입니다.

둘째, 묶음에만 걸리는 규정이 따로 있습니다. 특정 label, class, type 에 대한 질의는 하나든 여럿이든 그 묶음의 모든 레코드를 언제나 돌려줍니다. 묶음 안 레코드들의 TTL 은 모두 같아야 합니다. 서로 다른 TTL 을 쓰는 것은 폐기되었고, 서버는 어떤 경우에도 TTL 이 모두 같지 않은 묶음을 보내서는 안 됩니다. 서버는 응답에 실려 온 레코드를 자기 캐시의 레코드와 합쳐 묶음을 만들어서도 안 됩니다. 응답 쪽을 무시하거나 캐시에 있던 묶음 전체를 버리거나 둘 중 하나를 택합니다.

레코드 하나가 혼자 정하지 못하는 것이 여기서 갈립니다. 자기 TTL 을 얼마로 적을지는 레코드가 가지지만, 그 값이 옆 레코드와 같아야 한다는 요구는 묶음이 가집니다. 순서도 마찬가지입니다. 한 벌 안에서 레코드의 순서는 뜻이 없고, 네임서버나 리졸버나 DNS 의 다른 부분이 그 순서를 보존할 필요도 없습니다.

관련 항목

DNS 와 그 필드·레코드 종류

DNS · TTL · A 레코드 · MX 레코드 · SOA 레코드 · TXT 레코드 · NS 레코드

레코드가 실제로 사는 시스템과 이웃 개념

네임서버 · 리졸버 · 마스터 파일 · 존 · Resource Record Set

다른 이름: resource record · 자원 레코드