DNS란 무엇이며 도메인 연결이 안 되는 이유
DNS 레코드 설정과 네임서버의 역할을 이해하고 도메인이 VPS에 연결되지 않는 원인을 해결합니다. TTL 캐싱으로 인한 반영 지연 문제와 도메인 등록 대행자 및 DNS 호스트의 차이점을 상세히 설명합니다.
DNS란 무엇이며, 왜 도메인이 아직 VPS에 연결되지 않는가
DNS(Domain Name System)는 example.com와 같은 이름을 203.0.113.10과 같은 IP(Internet Protocol) 주소로 변환합니다. 브라우저는 이름에 직접 연결할 수 없습니다. 주소에 연결해야 하므로 모든 페이지 로드는 DNS 질의와 응답으로 시작됩니다. 도메인과 나만의 VPS를 막 구매했는데 아무것도 로드되지 않는다면, 다음 두 가지 중 하나가 원인입니다. 이름을 서버 주소에 연결하는 레코드가 아직 없거나, 레코드는 존재하지만 경로상의 어딘가에서 여전히 이전 응답을 제공하고 있는 경우입니다.
두 상황 모두 정상이며, 무언가 고장 났다는 의미는 아닙니다. 아래 섹션에서는 가장 많은 시간을 낭비하게 만드는 원인인 '어떤 제어판이 실제로 레코드를 관리하는가'부터 시작하여, 마주하게 될 순서대로 내용을 다룹니다.
이곳의 모든 확인 작업은 dig을 사용하며, 이는 새로 설치된 Ubuntu나 Debian 시스템에 기본적으로 설치되어 있지 않습니다.
sudo apt update && sudo apt install -y bind9-dnsutils도메인 등록 대행자, 네임서버, DNS 호스트: 무엇을 수정해야 하는가
이 세 가지 명칭은 서로 다른 역할을 의미합니다. 이들을 혼동하는 것이 수정 사항이 적용되지 않는 가장 흔한 원인입니다.
- 도메인 등록 대행자(Registrar)는 도메인을 구매한 회사입니다. 이들의 핵심 업무는 위임입니다. TLD(최상위 도메인,
.com부분)를 운영하는 레지스트리에 귀하의 도메인에 대한 권한을 가진 네임서버가 무엇인지 알려줍니다. - 권한 있는 네임서버(Authoritative nameservers)는 귀하의 존(zone)에 대한 실제 레코드를 보유합니다. 존은 귀하의 도메인과 그 하위 도메인들을 의미합니다.
- DNS 호스트는 해당 네임서버를 운영하는 주체입니다. 등록 대행자일 수도 있고, 별도의 제공업체일 수도 있으며, 귀하가 소유한 서버에서 실행 중인
bind9일 수도 있습니다.
도메인은 등록 대행자에게서 구매하지만, 설정은 DNS 호스트에서 수정해야 합니다. 만약 다른 제공업체의 네임서버로 도메인을 이전했다면, 등록 대행자의 DNS 패널에는 여전히 존 정보가 표시되고 수정 사항도 저장되겠지만, 인터넷상의 누구도 해당 존에 질의하지 않습니다. 레코드는 존재하지만, 아무도 참조하지 않는 상태가 됩니다.
현재 전 세계가 어디에 질의하고 있는지 확인하는 방법은 다음과 같습니다.
dig example.com NS +short
dig +trace example.com첫 번째 명령은 오늘날 해당 도메인에 대해 응답하는 네임서버를 출력합니다. 두 번째 명령은 루트 서버부터 시작하여 체인을 따라가며 TLD 서버가 제공하는 위임 정보를 출력하는데, 이는 귀하의 등록 대행자가 제어하는 위임 정보와 같습니다. 만약 출력된 네임서버가 알 수 없는 제공업체의 것이라면, 해당 제공업체가 귀하가 수정해야 할 패널을 운영하고 있는 것입니다.
단일 조회가 이루어지는 과정
네 개의 주체가 관여하며, 각 주체는 학습한 내용을 복사본으로 보관합니다.
- 사용자의 기기에 있는 stub resolver입니다. 이 리졸버는 직접 검색을 수행하지 않습니다. 설정된 서버 하나에 질의하고 그 응답을 그대로 신뢰합니다. Ubuntu에서
/etc/resolv.conf는 보통/run/systemd/resolve/stub-resolv.conf로 연결되는 심볼릭 링크이며,127.0.0.53을 가리킵니다. 이는 자체 캐시를 가지고 로컬에서 실행되는systemd-resolved입니다. - recursive resolver입니다. ISP(인터넷 서비스 제공업체)가 운영하거나,
1.1.1.1과 같은 공용 리졸버, 혹은 직접 운영하는 리졸버가 여기에 해당합니다. 이 리졸버가 실제 답변을 찾아내는 작업을 수행합니다. - root 및 TLD 서버입니다. recursive resolver가 root 서버에 질의하면, root 서버는 해당 주소를 직접 알지는 못하지만
.com서버에 대한 참조(referral)를 응답합니다. 이후 해당 서버들이 다시 사용자의 네임서버에 대한 참조를 응답합니다. - authoritative nameserver입니다. 이 서버는 누구에게도 묻지 않습니다. 자신의 영역(zone) 내에서 답변을 제공하며, 해당 답변이 권한 있는 응답임을 표시합니다.
dig +trace example.com은 이 과정을 보여줍니다. 이 도구는 root에서 직접 시작하여 캐시에 묻는 대신 각 참조를 출력하기 때문입니다. 이는 위임(delegation)과 영역(zone) 설정이 일치하는지 확인하는 가장 빠른 방법입니다.
서버 운영 시 중요한 DNS 레코드
A: 도메인 이름을 IPv4 주소로 연결합니다.example.com. A 203.0.113.10. 이 레코드가 도메인을 VPS로 가리키게 합니다.AAAA: 도메인 이름을 IPv6 주소로 연결합니다(예:2001:db8::10). 서비스가 해당 주소에서 실제로 응답할 때만 게시하십시오. IPv6 네트워크의 클라이언트는 AAAA 레코드를 우선적으로 시도하므로, 응답이 없는 주소를 설정하면 모든 접속 시 지연이 발생합니다.CNAME: 한 이름을 다른 이름으로 연결하는 별칭입니다.www.example.com. CNAME example.com.은www의 방문자를 도메인 루트가 가리키는 곳으로 보냅니다. CNAME은 도메인 루트(example.com)에 설정할 수 없습니다. 루트 도메인은 SOA(Start of Authority) 및 NS 레코드를 반드시 포함해야 하는데, CNAME은 다른 레코드와 이름을 공유할 수 없기 때문입니다. DNS 제공업체는 이를 위해 ALIAS, ANAME 또는 CNAME flattening과 같은 우회 방법을 제공합니다.MX: 도메인으로 오는 메일을 전달할 서버를 지정합니다. 호스트 이름과 우선순위 번호를 포함하며, 숫자가 낮을수록 우선순위가 높습니다. MX 레코드는 반드시 주소 레코드(A 또는 AAAA)를 가진 이름을 가리켜야 합니다. CNAME을 가리키는 것은 유효하지 않으며, 일부 메일 발송 서버는 이를 거부할 수 있습니다.TXT: 인증 및 정책 설정을 위한 자유 텍스트 필드입니다. 메일 인증 레코드(SPF, DKIM, DMARC)가 여기에 위치하며, 와일드카드 인증서 발급을 위한 ACME(Automatic Certificate Management Environment) 토큰도 여기에 저장합니다.NS: 해당 존을 관리하는 네임서버를 지정합니다. 외부에서 참조하는 네임서버 정보는 도메인 등록 기관의 위임 설정을 통해 결정되며, 존 파일 내부에 작성된 정보가 아닙니다.
레코드 유형 자체보다 두 가지 세부 사항이 더 많은 혼란을 야기합니다. 점(.)으로 끝나는 이름은 절대 경로를 의미하므로, www.example.com.는 정확히 그 이름 자체를 의미합니다. 대부분의 관리 패널은 상대 경로를 입력받아 자동으로 도메인을 덧붙입니다. 따라서 이름 입력란에 www.example.com을 입력하면 www.example.com.example.com가 되어 아무도 해석할 수 없는 주소가 됩니다. 다른 하나는 @인데, 거의 모든 패널에서 이는 서브도메인이 없는 도메인 루트 자체를 의미합니다.
VPS에 A 레코드 지정하기
먼저 인터넷에서 서버를 식별하는 주소를 확인합니다.
curl -4 https://ifconfig.me
ip -brief -4 address show그런 다음 DNS 호스트에서 레코드 하나를 생성합니다. 유형은 A, 이름은 @, 값은 해당 주소, TTL(time to live)은 300으로 설정합니다. www에 대한 두 번째 레코드를 추가합니다. 동일한 주소를 가진 또 다른 A 레코드이거나, apex를 가리키는 CNAME 레코드여야 합니다.
이제 서버 자체가 아닌 노트북에서 정상적으로 해석되는지 확인합니다.
dig example.com A +short
dig @1.1.1.1 example.com A +short
dig @ns1.your-dns-host.net example.com A +short첫 번째 명령은 캐시를 포함하여 사용자의 컴퓨터가 사용하는 일반적인 경로를 거칩니다. 두 번째 명령은 로컬 캐시를 건너뛰고 공개 재귀 리졸버(recursive resolver)에 질의합니다. 세 번째 명령은 권한 있는 네임서버(authoritative nameserver)에 직접 질의하므로, 경로상에 캐시가 전혀 없는 현재의 실제 값을 반환합니다. 세 번째 명령은 주소를 반환하는데 첫 번째 명령은 그렇지 않다면, DNS 설정은 올바르게 완료된 것이며 이전 응답의 캐시가 만료되기를 기다리는 상태입니다.
이름 해석이 로드되지 않는 문제 해결
이름 해석은 DNS가 정상적으로 작동함을 증명합니다. 이는 웹 서버에 대해서는 아무것도 증명하지 않습니다. dig이 올바른 주소를 반환하면, 다음 명령으로 연결을 테스트하십시오:
curl -I http://example.comcurl: (6) Could not resolve host: example.com는 DNS 문제입니다. curl: (7) Failed to connect to example.com port 80 after 21 ms: Connection refused은 DNS 문제가 아닙니다. 이름은 해석되었고 패킷은 도착했으므로, 해당 포트에서 아무것도 수신 대기 중이지 않은 것이 문제입니다. 요청이 응답 없이 대기하다가 시간 초과(timeout)가 발생한다면, 보통 방화벽이 패킷을 거부하지 않고 조용히 폐기했음을 의미합니다. 이 시점부터는 DNS가 논의 대상에서 제외되며, 포트 및 수신 대기 소켓과 VPS의 ufw 방화벽 규칙이 문제를 다루게 됩니다. 연결이 완료된 후, 나머지 페이지 로드는 HTTP의 역할입니다.
브라우저에 여전히 이전 호스트 정보가 표시되는 이유
DNS 정보는 전파되지 않습니다. 어떤 서버도 변경 사항을 외부로 밀어내지 않습니다. 권한 있는 네임서버(authoritative nameserver)는 저장 즉시 새로운 값을 보유하지만, 이전 응답의 캐시 복사본은 각자의 타이머가 만료될 때까지 유효합니다. 이 타이머가 바로 레코드가 전달될 때 포함된 TTL(초 단위)입니다.
복사본은 예상보다 더 많은 곳에 존재합니다. 브라우저 자체의 짧은 캐시, 시스템의 스텁 리졸버(stub resolver), 네트워크에서 사용하는 재귀적 리졸버(recursive resolver), 그리고 클라이언트에 설치된 VPN이 사용하는 리졸버 등이 있습니다. 각 리졸버는 수신한 TTL만큼 복사본을 유지합니다. 서로 다른 네트워크에 있는 두 사람이 몇 시간 동안 서로 다른 응답을 볼 수 있으며, 두 기기 모두 정상적으로 동작하는 상태입니다.
캐싱 리졸버를 대상으로 카운트다운을 확인하십시오.
dig @1.1.1.1 example.com +noall +answer몇 초 간격으로 두 번 실행하십시오. 응답 내의 TTL이 줄어듭니다. TTL이 0에 도달하면 리졸버는 해당 레코드를 폐기하고 네임서버에 다시 질의합니다.
거의 아무도 고려하지 않는 두 번째 캐시가 있는데, 바로 부정 응답(negative answer)입니다. 리졸버가 특정 이름이 존재하지 않는다는 응답을 받으면, 해당 NXDOMAIN 정보도 존(zone)의 SOA 레코드 마지막 필드에 설정된 시간만큼 캐싱합니다.
dig example.com SOA +short해당 줄의 마지막 숫자가 부정 TTL이며, 보통 3600으로 설정됩니다. 따라서 레코드를 생성하기 전에 staging.example.com를 조회하면, 레코드를 생성한 후에도 한 시간 동안 해당 레코드가 보이지 않을 수 있습니다. 레코드를 먼저 생성한 뒤에 조회하십시오.
네임서버 변경은 레코드 변경보다 느리며, 그 이유는 기계적인 특성 때문입니다. .com 존의 위임(delegation) 레코드는 172800초, 즉 2일의 TTL로 제공됩니다. 따라서 이전 네임서버를 캐싱한 리졸버는 그 기간만큼 계속해서 이전 네임서버에 질의할 수 있습니다. "최대 48시간까지 기다리라"는 조언은 여기서 비롯되었습니다. 이는 네임서버 변경에 적용되는 말이며, 일반적인 레코드 수정에는 해당하지 않습니다.
TTL과 싸우지 말고 TTL을 고려하여 마이그레이션을 계획하십시오.
- 레코드의 TTL을 300으로 낮추고 저장합니다.
- 이전 TTL보다 긴 시간을 기다려 이전 값을 가진 모든 캐시 복사본이 만료되도록 합니다.
- 주소를 변경합니다.
- 트래픽이 이동한 후에는 TTL을 다시 3600 이상으로 높입니다. TTL이 낮으면 모든 리졸버가 네임서버에 훨씬 더 자주 질의하게 되기 때문입니다.
사용 중인 기기의 캐시를 비우려면 다음을 수행하십시오.
resolvectl flush-caches
resolvectl statisticsresolvectl statistics은 적중(hit) 및 미적중(miss) 카운터가 포함된 캐시 섹션을 출력하므로, 캐시를 비운 직후 다음 조회는 미적중으로 나타납니다. 브라우저는 별도의 캐시를 유지하므로 시스템 캐시를 비운 후에도 Chrome은 여전히 이전 응답을 사용할 수 있습니다. 해당 캐시는 chrome://net-internals/#dns에서 비우십시오. /etc/hosts도 확인하십시오. 여기에 남아 있는 줄은 해당 기기 내에서 DNS보다 우선순위가 높기 때문입니다. getent hosts example.com는 /etc/hosts을 포함하여 시스템이 실제로 사용할 응답을 보여줍니다.
와일드카드 인증서는 TXT 레코드로 검증합니다
CA(인증 기관)는 인증서를 발급하기 전에 해당 도메인에 대한 제어권을 확인합니다. HTTP-01 챌린지는 특정 호스트네임의 80번 포트로 파일을 제공하는 방식이며, 단일 도메인에는 적합합니다. 와일드카드 인증서는 *.example.com과 같이 CA가 직접 파일에 접근할 수 없는 광범위한 호스트네임 범위를 포함하므로, Let's Encrypt는 DNS-01 챌린지를 통해서만 와일드카드 인증서를 발급합니다. 사용자는 CA가 제공한 토큰을 포함하는 TXT 레코드를 _acme-challenge.example.com에 게시해야 하며, 이 DNS 영역에 대한 제어권이 곧 검증의 증거가 됩니다.
이 방식은 DNS 호스트를 인증서 갱신 과정의 일부로 만듭니다. Certbot은 사용자의 개입 없이 갱신할 때마다 해당 TXT 레코드를 생성하고 삭제해야 하므로, DNS 제공업체에 맞는 API와 플러그인이 필요합니다. 검증에 실패할 경우 주로 DNS problem: NXDOMAIN looking up TXT for _acme-challenge.example.com 메시지가 나타나는데, 이는 CA가 레코드가 전파되기 전에 확인을 시도했음을 의미합니다. 즉, 레코드가 저장되지 않았거나 이전의 부정 응답(negative answer)이 캐시되어 있는 상태입니다. 전체 절차는 DNS-01 챌린지를 이용한 와일드카드 인증서 가이드에서 확인할 수 있습니다.
VPN이 리졸버를 가로챌 때
VPN(가상 사설망) 클라이언트는 연결된 동안 시스템 리졸버를 대체하는 것이 일반적입니다. 로컬 네트워크로 조회를 보내면 방문하는 모든 사이트의 도메인 이름이 해당 네트워크에 노출되기 때문입니다. 이는 올바른 동작 방식이지만, 두 가지 방향에서 문제가 발생할 수 있습니다.
터널이 활성화된 후 IP 주소는 통신이 되는데 도메인 이름 해석만 되지 않는다면, 클라이언트가 설정한 리졸버에 터널 내부에서 접근할 수 없는 상태입니다. ping 1.1.1.1는 성공하지만 curl https://example.com는 curl: (6) Could not resolve host: example.com을 반환합니다. 반대로 터널이 활성화되었는데도 조회가 여전히 현재 접속 중인 로컬 네트워크로 전달된다면, 트래픽은 터널링되지만 로컬 리졸버는 사용자가 요청하는 모든 도메인 이름을 그대로 확인하게 됩니다.
resolvectl status이 명령은 각 링크에서 사용 중인 리졸버를 출력하므로, 터널이 어떤 리졸버를 설정했는지, 그리고 의도한 리졸버가 맞는지 확인할 수 있습니다. WireGuard 터널은 클라이언트 설정 파일의 DNS = 줄에서 이를 지정하며, WireGuard가 리졸버를 가로챌 때 DNS 문제 해결하기에서 systemd-resolved 및 resolvconf 관련 사례를 자세히 다룹니다.
응답 코드와 각 코드가 의미하는 바
NXDOMAIN: 권한 있는 서버가 해당 이름이 존재하지 않는다고 응답합니다. 철자를 확인하고, 도메인 접미사가 중복되지 않았는지 확인하며, 위임이 가리키는 영역(zone)을 올바르게 수정했는지 점검하십시오.ANSWER SECTION이 비어 있는NOERROR: 이름은 존재하지만 요청한 유형의 레코드가 없습니다.A만 존재하는 상황에서AAAA을 요청하면 정확히 이 결과가 나타납니다.SERVFAIL: 리졸버가 시도했으나 답을 얻지 못했습니다. 흔한 원인은 권한 있는 서버가 응답하지 않는 경우와 DNSSEC(domain name system security extensions) 검증 실패입니다. 검증을 비활성화하는dig @1.1.1.1 example.com A +cd로 테스트하십시오. 검증을 껐을 때+cd와SERVFAIL이 포함된 응답이 온다면 서명 문제이며, 이는 네임서버 이전 후 상위 도메인에 이전 DS(delegation signer) 레코드가 남아 있을 때 발생합니다.REFUSED: 질의한 서버가 해당 질문에 응답하지 않습니다. 보통 해당 도메인을 관리하지 않는 권한 있는 서버에dig을 지정했을 때 발생합니다.;; connection timed out; no servers could be reached: dig가 리졸버에 도달하지 못했습니다. 이는 사용자 측의 네트워크나 리졸버 문제이므로 도메인 자체의 문제는 아닙니다.
ping: example.com: Temporary failure in name resolution은 dig가 아닌 glibc에서 보고하는 동일한 유형의 오류입니다.
자신의 VPS에서 네임서버를 직접 운영해야 할까요?
운영할 수 있습니다. bind9, knot 또는 nsd을 사용하면 서버에서 직접 존(zone)을 서비스할 수 있으며, 어떤 관리 패널을 사용하는 것보다 DNS에 대해 더 깊이 배울 수 있습니다. 하지만 실무적인 측면에서 반대 의견도 존재합니다. 도메인은 최소 두 개의 서로 다른 네트워크에 네임서버를 두어야 합니다. 따라서 단일 VPS에서 운영할 경우 해당 도메인의 모든 서비스(메일 포함)가 단일 장애 지점이 됩니다. 자신이 서비스하는 도메인 내부에 네임서버를 지정하려면 등록 대행자(registrar) 측에 글루 레코드(glue record)가 필요합니다. 이는 상위 존에 저장된 ns1.example.com의 주소이며, 이 정보가 없으면 조회 자체가 시작될 수 없습니다. 리졸버가 네임서버에 도달하지 못하면 웹사이트로 대체 연결되는 것이 아니라, 해당 사용자에게는 도메인 전체가 사라진 것처럼 보입니다. 대부분의 경우 API를 제공하는 호스팅 DNS를 사용하는 것이 위험 부담이 적습니다. 자신의 서버를 위해 VPS에서 캐싱 리졸버를 운영하는 것은 별개의 작업이며, 훨씬 적은 부담으로 수행할 수 있습니다.
FAQ
DNS 변경 사항이 아직 반영되지 않는 이유는 무엇입니까?
DNS는 전파되는 것이 아닙니다. 권한 있는 네임서버(authoritative nameserver)는 저장하는 즉시 새로운 값을 보유하며, 이미 질의를 수행한 모든 리졸버는 수신한 TTL이 만료될 때까지 캐시된 복사본을 유지합니다. dig @ns1.your-dns-host.net example.com A +short를 사용하여 권한 있는 서버에 직접 질의하십시오. 해당 명령이 새로운 주소를 반환한다면 변경 사항은 적용된 것이며, 나머지는 모두 캐싱 문제입니다. 레코드가 아닌 네임서버 자체를 변경했다면 TLD 위임(delegation)의 TTL이 2일로 설정되어 있으므로 훨씬 더 긴 시간이 소요될 수 있습니다.
내 도메인이 실제로 어떤 네임서버를 사용하는지 어떻게 확인합니까?
dig example.com NS +short은 현재 해당 도메인에 응답하는 네임서버를 출력하며, dig +trace example.com은 TLD 서버가 제공하는 위임을 포함하여 루트로부터의 참조 체인을 보여줍니다. 만약 출력된 네임서버가 귀하가 설정을 변경하고 있는 제공업체의 서버가 아니라면, 그것이 바로 문제의 원인입니다. 위임에 명시된 제공업체에서 레코드를 수정하거나, 등록 대행자(registrar)의 설정을 변경하여 원하는 곳을 가리키도록 하십시오.
도메인 해석은 되는데 사이트가 로드되지 않습니다. 어떻게 해야 합니까?
dig example.com A +short이 서버 주소를 반환하는 시점에서 DNS 작업은 완료된 것입니다. 그 이후의 문제는 연결의 문제입니다. curl -I http://example.com가 Connection refused을 반환한다면 해당 포트에서 대기 중인 서비스가 없다는 뜻입니다. 요청이 타임아웃될 때까지 응답이 없다면 방화벽이 패킷을 차단한 것입니다. 웹 서버가 실행 중이며 공인 IP 주소에 바인딩되어 있는지 확인하고, 서버 내부 방화벽과 제공업체 제어판의 네트워크 방화벽 설정을 점검하십시오.
루트 도메인에 CNAME을 설정할 수 없는 이유는 무엇입니까?
CNAME은 특정 이름이 다른 이름의 별칭임을 나타내며, CNAME이 설정된 이름에는 다른 어떤 레코드도 공존할 수 없습니다. 루트 도메인은 존(zone)으로서 존재하기 위해 반드시 SOA 및 NS 레코드를 포함해야 하므로 CNAME이 될 수 없습니다. 루트 위치에 주소를 담은 A 레코드를 사용하거나, ALIAS, ANAME, CNAME flattening 등으로 불리는 제공업체 기능을 사용하십시오. 이 기능은 이름을 저장해 두었다가 해당 이름이 현재 가리키는 주소로 질의에 응답합니다.