SOA 레코드
고친 사람 github-actions[bot]
SOA 레코드는 한 도메인을 어떻게 관리할지 정해 줍니다. 원본을 어느 이름 서버가 들고 있는지 적습니다. 사본을 가진 서버가 얼마마다 새 판을 확인할지도 적습니다. 없는 이름이라는 답을 얼마 동안 기억해도 되는지도 이 레코드가 정합니다.
쉽고 빠른 이해
이름 서버는 보통 여러 대를 둡니다. 한 대가 원본을 들고 나머지는 사본을 받아 갑니다. 원본을 고쳐도 사본을 든 서버는 그 사실을 모릅니다. 언제 새로 받을지 정해 두지 않으면 서버마다 다른 답을 냅니다.
SOA 레코드는 도메인 하나마다 붙는 관리 카드입니다. example.com 의 카드에는 「원본은 ns1 이
들고 있다 · 지금 판 번호는 2026092401 · 사본은 두 시간마다 확인해라」 같은 값이 적힙니다.
없는 이름이라는 답을 받아 간 서버가 그 답을 몇 분 동안 기억할지도 이 카드가 정합니다.
- 원본을 고치면 판 번호를 올립니다
- 사본을 든 서버는 정해진 간격마다 원본의 판 번호를 물어봅니다
- 번호가 커졌으면 새 판을 통째로 받아 갑니다
대가는 늦음입니다. 고친 내용은 확인 간격만큼 늦게 퍼집니다. 판 번호 올리기를 잊으면 사본은 옛 내용을 계속 답합니다.
상세
이 절은 먼저 이 레코드가 풀려는 문제를 봅니다. 이어서 설정 파일에 적힌 SOA 레코드 한 벌을 읽으며 값 일곱 개를 하나씩 풉니다. 마지막으로 그 값들이 사본을 맞추는 일과 캐시에 어떻게 쓰이는지 봅니다.
DNS(Domain Name System, 도메인 이름 체계)는 api.example.com 같은 이름을 IP 주소(Internet
Protocol address)로 바꿔 주는 체계입니다. 이름을 물으면 답해 주는 서버를 이름 서버라고 부릅니다.
이름 정보는 한곳에 모여 있지 않습니다. 도메인마다 그 도메인을 맡은 이름 서버가 따로 들고 있습니다.
한 이름 서버 무리가 책임지고 답하는 도메인 묶음을 존(zone)이라고 합니다. example.com 과 그
아래의 www.example.com · api.example.com 이 한 존을 이룰 수 있습니다. 앞에서 「한 도메인」이라고
부른 단위가 이 존입니다.
존 안의 정보는 리소스 레코드라는 한 줄짜리 항목으로 적습니다. 한 줄에 이름 · 종류 · 수명 ·
값이 들어갑니다. 「www.example.com 의 주소는 192.0.2.10」이 레코드 한 줄입니다.
SOA(Start of Authority, 권한 시작) 레코드는 존마다 꼭 하나 있는 리소스 레코드입니다. 존의 맨 꼭대기
이름, 곧 example.com 자신에만 붙습니다. 같은 존의 www.example.com 에는 따로 붙지 않습니다.
다른 레코드는 이름 하나의 값을 적습니다. SOA 레코드는 존 자체를 어떻게 관리할지를 적습니다.
원본 서버와 사본 서버
이 레코드가 없으면 무엇이 곤란한지부터 봅니다. 출발점은 이름 서버를 여러 대 둔다는 것입니다.
이름 서버를 한 대만 두면 그 서버가 멈출 때 존의 이름이 전부 안 풀립니다. 그래서 한 존을 여러 대가 나눠 맡습니다. 그중 한 대가 원본을 듭니다. 나머지는 원본을 복사해 갑니다.
원본을 든 서버를 주 서버(primary)라고 부릅니다. 복사해 가는 서버는 보조 서버(secondary)입니다.
보조 서버가 주 서버에서 존 내용을 통째로 받아 가는 일을 존 전송이라고 합니다. 이 전송이 끝나야 보조 서버가 원본과 같은 답을 냅니다.
곤란한 점은 보조 서버가 원본이 언제 바뀌었는지 모른다는 것입니다. 너무 드물게 확인하면 옛 내용을 오래 답합니다. 너무 자주 확인하면 주 서버가 쓸데없는 문의를 받습니다.
그래서 확인 간격을 누군가 정해 줘야 합니다. 주 서버와 연락이 안 될 때 얼마나 버틸지도 정해야 합니다. SOA 레코드가 이 값들을 존 안에 적어 둡니다. 보조 서버는 존을 받아 갈 때 이 값도 함께 받습니다.
존 파일에 적힌 SOA 레코드
존 설정을 적는 텍스트 파일을 존 파일이라고 합니다. 아래는 그 파일 맨 위에 오는 SOA 레코드 하나입니다. 괄호 안에서 값이 여러 줄로 이어지지만 레코드는 하나입니다.
example.com. 3600 IN SOA ns1.example.com. (
hostmaster.example.com. ; 책임자 메일
2026092401 ; 판 번호
7200 ; 확인 간격
900 ; 실패 뒤 재시도
1209600 ; 사본을 버리는 시한
300 ) ; 없다는 답의 수명
예의 이름은 모두 점으로 끝납니다. 끝 점은 「이름이 여기서 끝난다」는 표시입니다. 끝 점까지 붙은
이름을 완전한 도메인 이름(FQDN, Fully Qualified Domain Name)이라고 부릅니다. 끝 점은 값의
일부가 아니어서 example.com. 은 example.com 으로 읽으면 됩니다.
첫 줄의 3600 은 이 레코드 자신의 TTL(Time to Live, 살아 있을 시간)입니다. 이 답을 받아 간
서버가 몇 초 동안 캐시해 둬도 되는지를 적습니다. 받아 가는 서버가 누구인지는 「없다는 답의
수명」 소절에서 풉니다.
IN 은 인터넷용 레코드라는 표시입니다. TTL 과 IN 은 모든 리소스 레코드가 똑같이 갖는 칸입니다.
SOA 레코드만의 값은 SOA 뒤에 옵니다.
그 값 일곱 개를 표로 모으면 이렇습니다. 앞의 둘은 이름입니다. 뒤의 다섯은 숫자입니다.
| 칸 | 담는 것 | 위 예의 값 |
|---|---|---|
MNAME |
원본을 든 주 서버의 이름 | ns1.example.com. |
RNAME |
이 존을 책임지는 사람의 메일 주소 | hostmaster.example.com. |
SERIAL |
존의 판 번호 | 2026092401 |
REFRESH |
보조 서버가 새 판을 확인하는 간격 | 7200 · 2시간 |
RETRY |
확인에 실패한 뒤 다시 해 보는 간격 | 900 · 15분 |
EXPIRE |
주 서버와 연락이 끊긴 채 사본으로 답해도 되는 한도 | 1209600 · 14일 |
MINIMUM |
없는 이름이라는 답을 캐시해 둘 시간 | 300 · 5분 |
숫자 다섯은 모두 32비트 정수입니다. 판 번호를 뺀 넷은 초 단위 시간입니다.
RNAME 은 메일 주소를 도메인 이름 꼴로 바꿔 적습니다. 첫 점이 @ 를 대신합니다. 그래서
hostmaster.example.com. 은 [email protected] 으로 읽습니다. 메일 주소 앞부분에 점이
들어 있으면 그 점 앞에 역슬래시를 붙여 @ 가 아님을 표시합니다.
dig 같은 조회 명령으로 한 도메인의 SOA 레코드를 물으면 이 일곱 값이 한 줄로 나옵니다. 순서는 위 표와 같습니다.
판 번호로 알리는 새 판
보조 서버가 새 판을 알아채는 과정입니다. 신호는 SERIAL 하나뿐입니다.
보조 서버는 REFRESH 간격마다 주 서버에 SOA 레코드만 물어봅니다. 받은 판 번호를 자기 사본의
번호와 견줍니다. 주 서버 쪽이 크면 존 전송을 요청해 새 판을 받아 갑니다.
sequenceDiagram
participant 보조 as 보조 서버
participant 주 as 주 서버
보조->>주: SOA 레코드를 달라
주-->>보조: 판 번호 2026092402
Note over 보조: 내 사본은 2026092401 이다
보조->>주: 존 전송을 요청한다
주-->>보조: 존의 레코드 전부
Note over 보조,주: 번호가 같으면 첫 왕복에서 끝난다
SOA 레코드 하나는 몇십 바이트입니다. 존 전체는 수천 줄일 수 있습니다. 작은 값 하나를 먼저 물어서 큰 전송은 판이 바뀌었을 때만 합니다.
레코드를 고쳐 놓고 번호를 안 올리면 보조 서버는 번호가 같으니 받아 가지 않습니다. 그러면 질의가 어느 서버에 닿느냐에 따라 새 값과 옛 값이 섞여 나갑니다.
번호는 커지기만 해야 합니다. 번호를 낮추면 보조 서버는 그것을 옛 판으로 보고 받지 않습니다.
그래서 흔히 날짜 뒤에 두 자리 순번을 붙여 2026092401 처럼 적습니다. 오늘 날짜로 시작하니 어제
번호보다 늘 큽니다. 같은 날 또 고치면 뒤 두 자리를 하나 올립니다.
간격을 다 기다리지 않는 방법도 있습니다. 주 서버가 존을 고친 즉시 보조 서버에 알림을 보냅니다. 이 알림을 DNS NOTIFY(Notify, 알림)라고 부릅니다. 알림을 받은 보조 서버는 위 그림과 같은 순서로 판 번호부터 확인합니다.
주 서버와 연락이 끊겼을 때
RETRY 와 EXPIRE 는 확인이 실패했을 때 쓰는 값입니다.
확인이 실패하면 보조 서버는 REFRESH 보다 짧은 RETRY 간격으로 다시 물어봅니다. 그동안에는 손에
든 사본으로 계속 답합니다. 주 서버가 잠깐 멈춰도 이 존의 이름이 계속 풀리는 까닭입니다.
실패가 EXPIRE 만큼 이어지면 보조 서버는 그 사본을 더는 믿지 않습니다. 이 존을 맡은 서버 노릇을
그만둡니다. 그 뒤로 이 존을 묻는 질의에는 답 대신 오류를 돌려줍니다. 낡은 사본이 언제까지고 답하는
일을 막는 상한입니다.
stateDiagram-v2
state "사본으로 답한다" as 답함
state "RETRY 간격으로 다시 묻는다 · 사본으로 계속 답한다" as 재시도
state "서버 노릇을 그만둔다 · 이 존을 묻는 질의에 오류로 답한다" as 멈춤
[*] --> 답함
답함 --> 재시도: 확인 실패
재시도 --> 답함: 확인 성공
재시도 --> 멈춤: 실패가 EXPIRE 만큼 이어짐
없다는 답의 수명
마지막 값 MINIMUM 은 사본 맞추기가 아니라 캐시에 쓰입니다. 먼저 캐시를 쥔 서버부터 봅니다.
앱이 이름을 물을 때 보통 이름 서버까지 직접 가지 않습니다. 중간에서 대신 물어 주고 답을 캐시해 두는 서버가 있습니다. 이 서버를 리졸버라고 부릅니다. 회사망이나 클라우드가 내주는 DNS 서버가 대개 리졸버입니다.
없는 이름을 물으면 이름 서버는 NXDOMAIN(Non-Existent Domain, 없는 도메인)으로 답합니다. 「그런 이름은 없다」는 뜻의 답입니다. 오타 난 이름이나 아직 안 만든 이름을 물으면 이 답이 옵니다.
리졸버는 이 「없다」도 캐시합니다. 같은 없는 이름을 매번 끝까지 물으러 가지 않으려는 것입니다. 이렇게 없다는 답을 캐시하는 일을 부정 캐싱이라고 합니다.
「없다」를 얼마나 기억할지는 SOA 레코드가 정합니다. MINIMUM 값과 SOA 레코드 자신의 TTL 가운데
작은 쪽입니다. 위 예라면 300초와 3600초 중 작은 300초, 곧 5분입니다.
리졸버가 이 계산을 할 수 있도록 이름 서버는 「없다」는 답에 존의 SOA 레코드를 함께 실어 보냅니다. 물은 종류의 레코드만 없을 때도 같습니다. 이름 자체는 있는 경우입니다.
백엔드 개발자가 이 값을 만나는 때는 대개 새 도메인을 열 때입니다. 레코드를 만들기 전에 누군가 그 이름을 먼저 물어봤다고 해 봅시다. 그 리졸버는 레코드를 만든 뒤에도 캐시된 「없다」가 끝날 때까지 없다고 답합니다.
sequenceDiagram
participant 앱
participant 리졸버
participant 이름 as 이름 서버
participant 운영자
앱->>리졸버: api.example.com 주소를 묻는다
리졸버->>이름: 대신 묻는다
이름-->>리졸버: NXDOMAIN · SOA 레코드를 함께 싣는다
Note over 리졸버: 없다는 답을 300초 기억한다
운영자->>이름: api.example.com 레코드를 추가한다
앱->>리졸버: 다시 묻는다
리졸버-->>앱: 캐시에 든 NXDOMAIN
MINIMUM 을 짧게 잡으면 이 기다림이 줄어듭니다. 대신 리졸버가 없는 이름을 더 자주 물으러 옵니다.
이름이 「최소」인 것은 처음 뜻의 흔적입니다. 처음에는 존의 모든 레코드에 붙일 가장 작은 TTL 이라는 뜻이었습니다.
쓰는 곳마다 뜻이 갈렸습니다. 나중에 없다는 답의 수명 하나로 정리됐습니다. 필드 이름만 보고 최소 TTL 로 읽으면 틀립니다.
SOA 레코드의 TTL 도 같은 흐름으로 바뀌었습니다. 처음 규칙은 SOA 레코드를 TTL 0 으로 내보내 캐시하지 못하게 했습니다.
나중에 없다는 답의 수명을 SOA 레코드의 TTL 과 견주게 됐습니다. 그러면 TTL 이 0 일 때 「없다」도
캐시할 수 없습니다. 지금 쓰는 존 파일이 위 예의 3600 처럼 SOA 레코드에도 0 보다 큰 TTL 을 주는
까닭입니다.
관련 항목
이 레코드가 속하는 상위 분류
리소스 레코드 · DNS · 존 · 존 파일 · RDATA
이 레코드를 정의하는 표준 문서
RFC 1035 · RFC 1034 · RFC 2308 · RFC 1982 · RFC 1996 · RFC 2181
한 존 안에 함께 적히는 다른 레코드
NS 레코드 · A 레코드 · AAAA 레코드 · CNAME · MX 레코드 · TXT 레코드 · PTR 레코드
이 레코드의 값을 따라 움직이는 서버
이름 서버 · 주 서버 · 보조 서버 · 권한 있는 이름 서버 · 리졸버 · 재귀 이름 서버
이 레코드가 조율하는 존 복제 절차
존 전송 · AXFR · IXFR · DNS NOTIFY · 일련번호 산술
이 레코드가 수명을 정하는 캐시
캐싱 · 캐시 · TTL · 부정 캐싱 · NXDOMAIN · NODATA · DNS 전파
이 레코드를 조회하는 명령
dig · nslookup · drill
이름이 겹치는 헷갈리는 이웃
SOA · 서비스 지향 아키텍처 · SOAP
다른 이름: SOA record · Start of Authority record · 권한 시작 레코드