dns는 누구나 아는거지만 실제 dns에 대한 여정을 세부적으로 파다보니 재미있는 정보들이 많아서 잠깐 정리해봤어.
- 개요
모두 알다시피 DNS는 Domain Name System의 약자로 도메인 이름(보통 웹사이트)을 IP 주소로 변환해주는 시스템을 말해. 도메인 이름 변환 시 보통은 아래 순서로 알려져 있어.
1. /etc/hosts 에 등록된 도메인
2. 로컬 dns 캐시
3. 설정된 dns 서버로 요청
운영체제마다 다르지만 보통 hosts 파일로 통칭되는데, 여기 정의된 매핑을 가장 최우선으로 확인하고 반환하게 돼. 이 파일에서는 아래같이 IP와 도메인이 짝을 이루는 형식으로 추가할 수 있어. 실무에서는 내부망으로 통합 테스트할 때 hosts 파일을 수정하기도 해. (인증이나 결제가 테스트 서버로 가도록)
// /etc/hosts
132.203.40.88 auth.frogred8.io
132.203.40.89 pay.frogred8.io
- dns 요청 순서
그런데 사실 dns 요청 시 검색 순서를 변경할 수 있는데 그 설정이 바로 /etc/nsswitch.conf 파일이야. nsswitch 시스템은 Name Service Switch의 약자로, dns 뿐만 아니라 이런 식으로 각 서비스마다 순차적으로 찾아볼 항목이 나열되어 있는 설정 파일을 제공해.
// /etc/nsswitch.conf
passwd: files systemd
group: files systemd
hosts: files dns
networks: files
...
만약 내가 /etc/hosts 설정을 무시하고 항상 dns 서버로 요청하고 싶다면 hosts란에 dns만 남기면, 원하는대로 hosts 파일은 건너뛰고 dns 서버로 먼저 요청할거야. 로컬에 저장된 dns 캐시는 보통 dns 결과에 있는 만료 시간으로 설정되는데 때에 따라서는 dns 캐시 시스템의 기본값으로 설정되는 경우도 있어. (ex. 3600초)
- dns 서버 설정
외부로 요청하는 dns 서버는 /etc/resolv.conf 파일에서 확인할 수 있어.
// /etc/resolv.conf
...
# This file is automatically generated.
nameserver 168.126.63.1
nameserver 168.126.63.2
보통 개인 컴퓨터에서 아무런 설정을 하지 않았는데도 이렇게 dns 서버가 설정되는데 그 이유는, 컴퓨터에서 인터넷 연결 시 ISP(Internet Service Provider) 업체로부터 DHCP(Dynamic Host Configuration Protocol)로 동적 IP를 할당받게 되는데 이 때 해당 ISP에서 지정된 dns 서버 주소도 같이 전달받게 되고, 이 값으로 resolv.conf 파일이 자동으로 생성되기 때문에 그래.
만약 resolv.conf 파일에 저렇게 자동 생성되었다는 메시지가 있다면 이 파일을 변경한 후 인터넷 재연결을 해보면 내가 변경한 내용이 없어지고 이전과 동일한 값으로 파일이 생성되는걸 확인할 수 있을거야. 난 인터넷이 kt망이라 168로 시작하는 dns 서버로 나오는데 sk나 lg는 주소가 다르게 나올 수도 있어.
- 국내 vs 구글 dns 속도 테스트
예전에 dns 서버 설정을 8.8.8.8로 바꾸면 인터넷이 빨라진다는 얘기가 많았는데 사실 더 느릴 가능성이 높아. 왜냐하면 구글 dns는 해외 dns 서버라서 국내망이 아닌 해외망을 통해 외부로 요청할거라 상대적으로 더 높은 latency를 가지게 되겠지.
이론과 실제가 일치하는지 테스트를 해봤는데 먼저 kt는 168.~ 주소이고, 구글은 8.~ 주소야.
❯ ping -c 2 168.126.63.1
64 bytes from 168.126.63.1: icmp_seq=0 ttl=58 time=14.721 ms
64 bytes from 168.126.63.1: icmp_seq=1 ttl=58 time=13.302 ms
❯ ping -c 2 8.8.8.8
64 bytes from 8.8.8.8: icmp_seq=0 ttl=57 time=44.794 ms
64 bytes from 8.8.8.8: icmp_seq=1 ttl=57 time=46.336 ms
// ping 테스트 결과
kt: 14ms
google: 45ms
ping은 그저 icmp 요청에 대한 응답일 뿐 dns 서버 자체를 의미하지 않으니 dig로 dns 서버를 거치도록 테스트를 한번 더 해봤어.
❯ dig www.google.com
;; Query time: 17 msec
;; Query time: 19 msec
❯ dig www.google.com
;; Query time: 44 msec
;; Query time: 41 msec
// dig 테스트
kt: 11ms
google: 43ms
로컬 dns 캐시나 그런거 없이 순수하게 dns 서버만 변경 후 여러번 테스트해서 나온 평균값이야. 역시 예상대로 국내 dns가 구글 dns보다 빨랐어. 여기서 더 나아가서, 현재 연결된 ISP 업체와 동일한 dns 서버는 더 빠르지 않을까 싶었는데 (예를 들어 kt망이면 kt dns가, sk망이면 sk dns가 제일 빠르다던가..) kt망으로 kt,sk dns 번갈아가며 테스트해봐도 별다른 차이가 없어서 증명은 못했어.
개인적인 생각으로 2000년대 초반에 구글 dns가 더 빠르다고 소문난 이유는 국내망에서 거치는 특정 라우터가 안좋았거나 국내 dns 서버 자체가 너무 느렸던게 아닐까 하는 짐작만 있는 상태였는데, 우연히 한국인터넷진흥원에서 F-root server 미러 운영을 하고 있다는 기사를 봤어.
이걸 자세히 알아보니, 정부에서는 2003년에 새로운 root 서버를 할당받고 싶어서 요청했는데, dns의 512byte 패킷 제한으로 root 서버를 현재의 13개에서 더 이상 추가할 수 없다는 거절을 받게 되었대.
그래서 그 대안으로 F-root 서버 미러 운영을 승인받아 2004년에 도입하여 지금까지 운영 중인가봐.
지금은 다른 root 서버군에서도 우리나라에서 운영 중이라 인터넷 안전성이 더 높아진 상태라고 보면 될 것 같아. 2000년대 초기에 국내망 dns가 느린건 이런 이유도 있겠구나 싶기도 하고, root 서버에 대한 질의조차 느렸던 시절이 있었다는게 감회가 새롭네.
- dns 탐색
우리가 보통 설정하는 dns 서버는 사실 recusive resolver(이하 RR. 아래에 자주 나올거야)라고 불리는 서버를 말하는데, 요청받은 도메인을 root 서버로 보내고, 여기서 받은 정보를 다시 tld 서버로, 그리고 권한있는 dns 서버로 순차적인 요청을 하여 최종 결과를 반환하는 기능을 하고 있어.
유저 -> RR -> root 서버 -> RR -> tld 서버 -> RR -> authoritative dns 서버 -> RR -> 유저
우리가 쉽게 보내는 dns 요청 하나가 실제 RR에서는 여러 번의 요청 및 응답을 대기하는 동작이 발생하게 돼. 물론 이걸 매번 하진 않고 RR에서 이전에 캐시한 정보를 먼저 찾아보기 때문에 평균적으로는 매우 빠르지만 캐시에 없는 도메인의 경우엔 평소보다 응답이 느릴 수도 있겠지.
이제 RR에서 일어나는 순차적인 동작과 해당 서버의 특징을 자세히 알아볼게.
- root 서버
RR에서는 먼저 root 서버의 목록을 알아와야 하는데 이 목록은 보통 RR 설정 파일을 통해 갱신되는 방식을 쓴다고 해. root 서버 목록은 이런 식으로 되어있어.
. 518400 IN NS a.root-servers.net.
. 518400 IN NS b.root-servers.net.
a.root-servers.net. 518400 IN A 198.41.0.4
a.root-servers.net. 518400 IN AAAA 2001:503:ba3e:0:0:0:2:30
b.root-servers.net. 518400 IN A 170.247.170.2
b.root-servers.net. 518400 IN AAAA 2801:1b8:10:0:0:0:0:b
...
NS(Name Server), A레코드(ipv4), AAAA레코드(ipv6) 등의 정보를 나열한 root 서버가 A-M까지 총 13개가 등록되어 있어. 이 13개의 root 서버는 서로 동일한 정보를 가지고 있어서 만약 하나의 서버가 다운된다 하더라도 다른 서버가 보완해주는데 사실 그럴 일은 거의 없을거야. 왜냐하면 한 개의 서버군만 해도 전세계에 흩어져 수십개의 다중화가 되어있어서 동시에 다운될 확률이 없다시피 할테니까 말이야.
root 서버의 만료 시간은 518400초(=6일), tld 서버는 대부분 172800초(=2일)로 설정되어 있더라.
아래 링크에 있는 root 서버 지도를 보면 특정 지역의 idc에 어떤 서버군이 존재하는지 찾아볼 수 있는데 꽤 잘 만들었으니 한번 가서 살펴봐도 재미있을거야.
https://root-servers.org
- TLD(Top-Level Domain) 서버
이런 root 서버에 현재 도메인으로 요청하면 그 도메인에 해당되는 TLD 서버 목록을 응답받을 수 있어. 이렇게 받게 되는 TLD 서버에는 두 가지 종류가 있는데 gTLD(generic Top-Level Domain), ccTLD(country code Top-Level Domain) 으로 분류가 가능해.
gTLD: 일반적인 용도의 최상위 도메인 (.com, net, org...)
ccTLD: 국가 지정 코드 최상위 도메인 (.kr, jp, uk...)
왜 이런 종류가 나눠지냐면 gTLD의 운영 주체는 IANA(Internet Assigned Numbers Authority)이고, ccTLD는 개별 국가라서 그래. 물론 IANA가 전체적인 TLD 관리/감독과 ccTLD 관리 기관에 대한 승인 등을 하고 있긴 해.
ccTLD의 서브 도메인은 국가마다 별도로 관리하는데, 한국을 예로 들면 ccTLD은 kr을 사용 중이고 서브 도메인으로 co.kr이나 과거에 개인 홈페이지에서 자주 쓰인 pe.kr도 있어. 지금은 딱히 선호하는 것 같진 않지만..
그리고 한국인터넷진흥원의 최근 소식을 잠깐 구경했는데 ai.kr, io.kr 등의 서브 도메인을 추가하는 법령이 통과되었고, 이제는 25년 3월 이후에 등록이 가능한가봐. 보면서 재미있던거 하나 더 말해보면, 55회차에서 승인되었던 세종시 전용 sejong.kr 서브 도메인이 56회차에서 취소되었는데 그 이유가 이미 sejong.kr 도메인이 등록되어있어서 서브 도메인을 만들 수 없어서 취소됨. 검색안해보고 안건올린 담당자 혼났을듯 ㅋㅋ
어쨌든 여기 ccTLD에 등록되는 코드는 알파벳 영문 두글자로 되어있는 국가 코드를 사용하는데, 국가라고 판단하기 애매한 나라도 있잖아? 쿠데타로 정부가 반이 나눠진 상태라던가 등등. 그래서 이걸 자체적으로 판단하지 않고 ISO-3166 규약에 있는 국가 코드를 참조하여 ccTLD로 사용하고 있어. 여기에 북한 국가 코드도 있던데 Korea (the Democratic People's Republic of)라서 kp로 쓰더라.
이건 사족인데, 국가 코드가 쉽거나 의미 부여가 가능할 경우에 의외로 수입원이 되는 경우도 있어. AI 열풍이 불면서 .ai 국가 코드를 가진 나라(앵귈라, 1만6천명 거주)의 도메인 가격이 높아져서 GDP의 10%를 도메인 수입으로 벌어들이기도 했다고 해.
https://n.news.naver.com/article/025/0003349403
.io도 살펴보면 gTLD가 아니라 영국령 인도양 지역(British Indian Ocean Territory)을 나타내는 ccTLD 중 하나이고.
이거 외에 IDN ccTLD(Internationalized country code TLD)라는 것도 있는데 거의 안쓰이긴 해. 영문이 아닌 글자의 도메인 관리 방식인데 https://후이즈검색.한국 이렇게 쓰는게 조금 어색하긴 하잖아? 우리나라에서 정한 도메인 가격은 대충 이렇더라.
https://krnic.or.kr/jsp/popup/agencyFeePop.jsp
- 권한있는 dns 서버 (Authoritative DNS Server)
도메인을 TLD 서버로 요청하면 우리가 찾는 도메인의 실제 ip 매칭 정보가 있는 dns 서버 목록을 반환하게 돼. 그 서버를 권한있는 dns 서버라고 부르는데 도메인의 등록/갱신을 책임지는 서버들이라고 보면 돼. 이를 registrar(발음은 레지스트라)라고 부르기도 해.
godaddy, cloudflare, 가비아, 후이즈 같은 도메인 업체에서 구입한 건 대부분 여기로 연결되 있는데 기업들은 aws랑 연결해서 쓰던지 따로 구축한 서버를 연결해놨더라고.
// 개인 도메인
❯ dig NS lordz.io
lordz.io. 861 IN NS linda.ns.cloudflare.com.
lordz.io. 861 IN NS clark.ns.cloudflare.com.
clark.ns.cloudflare.com. 85051 IN A 108.162.193.87
clark.ns.cloudflare.com. 85051 IN A 172.64.33.87
...
// 기업 도메인
❯ dig NS google.com
google.com. 114424 IN NS ns3.google.com.
google.com. 114424 IN NS ns2.google.com.
...
ns1.google.com. 116338 IN A 216.239.32.10
ns2.google.com. 137282 IN A 216.239.34.10
❯ dig NS naver.com
naver.com. 43372 IN NS ns2.naver.com.
naver.com. 43372 IN NS ns1.naver.com.
...
ns1.naver.com. 12796 IN A 125.209.248.6
ns2.naver.com. 12850 IN A 125.209.249.6
- dns 쿼리 여정의 끝
이런 긴 과정을 거쳐서 RR(recusive resolver, 우리가 지정한 dns 서버)에서는 권한있는 dns 서버 주소를 획득하게 되고, 여기에 있는 ip로 질의하여 마침내 도메인과 연결된 ip를 얻을 수 있어. 이렇게 얻은 ip를 RR에서 요청한 유저에게 반환하면 마침내 dns 쿼리에 대한 응답을 받을 수 있는거지.
위에서 한번 적었지만 여기까지 왔다면 이 순서도가 이제 이해가 되겠지?
유저 -> RR -> root 서버 -> RR -> tld 서버 -> RR -> authoritative dns 서버 -> RR -> 유저
- dns 수정에 대한 배포
사족 하나 더 추가해보면, 도메인과 연결된 ip는 언제든 변경할 수 있지만 모든 dns 서버가 바로 바뀌진 않고 제대로 배포되는데 보통 몇시간은 걸리는 편이야.
왜냐하면 dns 서버가 최초에 분산 데이터베이스 시스템을 기반으로 만들었기 때문에 db의 CAP(일관성, 가용성, 분산 허용 여부) 이론 중 일관성을 포기한 AP를 만족하는 시스템이기 때문이야.
그래서 dns 값에 변경이 있어도 애초에 모든 dns 서버의 데이터가 일괄적으로 즉시 바뀌는걸 보장하지 않기 때문에 대다수의 dns 서버들은 캐시를 적용해놓고 쓰고 있어.
그 캐시 시간이 만료된 이후에야 새로 받아올거라서 dns의 변경 적용은 시간이 걸리는 편이지. 이런 특징 때문에 로컬이나 서버에서 dns 캐시를 적극적으로 사용할 수 있는 기반이 되기도 해.
- 결론
1) dns 검색 순서는 nsswitch.conf 파일에서 변경할 수 있다.
2) dns 쿼리는 root, TLD, authoritative 서버를 거쳐서 도메인의 ip를 반환한다.
3) TLD는 gTLD(.com), ccTLD(.kr) 두 종류가 있고, 그 관리 주체가 IANA, 개별 국가로 나눠진다.
4) 좋은 국가 코드(.ai, .io)는 의외로 수익원이 될 수 있다.
이전글: https://frogred8.github.io/
#frogred8 #network #dns