도메인 설정을 바꿨는데 접속 결과가 404였다가 200이었다가 연결 실패였다가 했습니다.
캐시 문제인 줄 알았는데 아니었습니다. DNS 레코드 두 개가 충돌하고 있었습니다.
결론부터
CNAME 레코드는 같은 이름에 다른 레코드와 함께 존재할 수 없습니다. DNS 규격입니다.
그런데 관리 화면에서는 두 개가 나란히 등록되기도 합니다. 그러면 이렇게 됩니다.
example.com. 600 IN A 121.254.x.x ← 새로 추가한 것
example.com. 600 IN CNAME host.example.net. ← 예전에 있던 것
이 상태에서는 조회하는 리졸버마다 다른 답을 줍니다. 어떤 곳은 A를 따라가고 어떤 곳은 CNAME을 따라갑니다. 내 브라우저에서는 되는데 다른 데서는 안 되는 상황이 벌어집니다.
해결은 간단합니다. 둘 중 하나를 지우면 됩니다.
왜 공존할 수 없나
CNAME은 "이 이름은 저 이름의 별칭이다"라는 뜻입니다. 별칭이면 그 이름에 대한 모든 질의가 대상 쪽으로 넘어가야 합니다.
그런데 같은 이름에 A 레코드가 또 있으면 모순이 생깁니다. "별칭인데 자기 주소도 갖고 있다"가 되니까요. 그래서 DNS 규격은 CNAME이 있으면 그 이름에 다른 타입의 레코드를 둘 수 없다고 못박고 있습니다.
MX나 TXT도 마찬가지입니다. 루트에 CNAME을 걸어두면 메일(MX)이나 SPF(TXT)를 추가할 수 없습니다.
루트 도메인이 특히 문제인 이유
blog.example.com 같은 하위 도메인은 CNAME을 마음껏 걸 수 있습니다. 문제는 루트(example.com) 입니다.
루트에는 SOA와 NS 레코드가 반드시 존재합니다. 그런데 CNAME은 다른 레코드와 공존할 수 없으니, 규격대로라면 루트에는 CNAME을 둘 수 없습니다.
그럼에도 국내 등록기관 관리 화면에서는 루트에 CNAME이 등록됩니다. 자체적으로 우회 처리를 하는 것인데, 다른 레코드와 겹치는 순간 예측 불가능한 상태가 됩니다.
참고로 이 문제를 정식으로 푸는 방식이 ALIAS / ANAME / CNAME 플래트닝입니다.
겉으로는 CNAME처럼 쓰지만 응답할 때는 A 레코드로 바꿔서 내보냅니다.
지원 여부는 DNS 제공자마다 다릅니다.
진단 — 캐시를 믿지 마세요
일반 조회는 리졸버 캐시를 타기 때문에 답이 오락가락합니다. 권위 네임서버에 직접 물어봐야 확실합니다.
# 그 도메인의 네임서버 확인
dig +short NS example.com
# 권위 서버에 직접 질의 (캐시 우회)
dig @ns.example-dns.com example.com ANY +noall +answer
충돌이 있으면 이렇게 나옵니다.
example.com. 600 IN A 121.254.x.x
example.com. 600 IN CNAME host.example.net.
example.com. 86400 IN SOA ...
example.com. 3600 IN NS ...
A와 CNAME이 같이 보이면 그게 충돌입니다.
타입별로 하나씩 봐도 됩니다.
for t in A AAAA CNAME MX TXT; do
printf "%-6s " "$t"; dig +short $t example.com | tr '\n' ' '; echo
done
CNAME이 걸려 있으면 MX나 TXT를 물어봐도 CNAME 대상이 돌아옵니다. 이게 보이면 그 이름에는 CNAME이 있다는 뜻입니다.
실제로 겪은 증상
같은 주소를 몇 분 간격으로 조회했는데 이렇게 나왔습니다.
| 시점 | 결과 |
|---|---|
| 처음 | 404 (CNAME 쪽 서버가 응답) |
| 잠시 후 | 200 (A 쪽 서버가 응답) |
| 그 다음 | 000 (연결 실패) |
어느 쪽이 이길지는 리졸버 구현과 캐시 상태에 달려 있습니다. 검색엔진 크롤러가 어느 쪽을 볼지도 알 수 없습니다.
<<<<< 여기 직접 쓰기: 이 증상을 처음 마주쳤을 때 무엇으로 착각했는지, 얼마나 헤맸는지 >>>>>
해결
- DNS 레코드 전체를 먼저 백업합니다. 화면 캡처든 텍스트든 남겨두세요
- 남길 레코드를 정합니다 (A로 갈지 CNAME으로 갈지)
- 다른 하나를 지웁니다
- 권위 서버에 직접 질의해서 하나만 남았는지 확인합니다
- TTL만큼 기다립니다 (위 예시는 600초 = 10분)
지우기 전에 그 레코드에 딸린 서비스가 있는지 확인하세요.
하위 도메인 CNAME 하나가 통째로 사이트 하나일 수 있습니다.
저는 밖에서 조회해서 3개인 줄 알았는데 관리 화면에는 12개가 있었습니다.
정리
- CNAME은 같은 이름의 다른 레코드와 공존할 수 없습니다
- 관리 화면이 허용해도 실제로는 접속 결과가 복불복이 됩니다
- 진단은 권위 네임서버에 직접 질의. 캐시된 답은 믿을 수 없습니다
- 루트 도메인에 CNAME이 필요하면 ALIAS/ANAME 지원 여부를 확인하세요
- 지우기 전에 백업하고, 그 레코드에 딸린 서비스를 먼저 확인하세요