문제
blog.example.com, 아니면 app., staging. — 서브도메인 — 이 필요한데, 연결하려는 플랫폼은 “DNS 레코드를 추가하세요”라고만 합니다. 그래서 DNS 관리 화면을 열었더니 타입 드롭다운, 이름 칸, 값 칸이 있는 폼이 뜨고, 아무것도 스스로 설명해 주지 않습니다. 타입을 잘못 고르거나 이름 칸에 엉뚱한 걸 넣으면 서브도메인은 아무 반응이 없거나, 헛웃음 나올 만큼 뒤엉킨 이름으로 해석됩니다.
좋은 소식: 서브도메인은 어딘가에서 ‘생성’하는 특별한 물건이 아닙니다. “서브도메인 만들기” 버튼 같은 건 없고, 따로 등록하는 것도 없습니다. 서브도메인은 그냥 이름 앞에 라벨이 붙은 DNS 레코드입니다. 이렇게 보면 전부 두 가지 결정 — 어떤 레코드 타입을 쓸지, 이름 칸에 뭘 넣을지 — 로 줄어들고, 둘 다 답은 간단합니다.
서브도메인이 실제로 뭔지
DNS는 트리입니다. example.com은 그 트리의 한 이름이고, blog.example.com은 그 한 단계 아래 이름입니다. “서브도메인을 만든다”는 건, 이미 내가 관리하는 존 안에서 그 아래 이름에 레코드를 하나 게시하는 것뿐입니다. example.com에 답하는 네임서버는 그 아래 전부에 답합니다 — 일부를 명시적으로 넘기지 않는 한(마지막에 다룹니다).
이게 모델의 전부입니다. www도 서브도메인, mail도 서브도메인. 이메일 설정이 쓰는 _dmarc나 selector._domainkey도 전부 서브도메인입니다. 라벨이 앞에 붙은 레코드일 뿐이고, 추가하는 방법은 똑같습니다.
두 가지 결정
1. 레코드 타입: A냐 CNAME이냐
서브도메인은 — 도메인의 apex(루트)와 달리 — 둘 다 쓸 수 있고, 선택은 무엇을 가리키느냐로 갈립니다.
- IP 주소가 있다(내 서버, VPS, 고정 IP): IPv4는 A 레코드, IPv6는 AAAA 레코드. 값은 주소 원형, 예:
203.0.113.10. - 플랫폼이 가리킬 호스트 이름을 줬다(
cname.vercel-dns.com,yourname.github.io,d1a2b3.cloudfront.net, 로드밸런서 DNS 이름): CNAME 레코드. 값은 그 호스트 이름. 여기서 CNAME을 쓰는 이유는 그 플랫폼의 실제 IP가 예고 없이 바뀌는데, CNAME은 매번 다시 해석해 따라가기 때문입니다. 그들의 IP를 A 레코드에 박아 두면, 재할당되는 날 서브도메인이 깨지고 이유도 모릅니다.
하나뿐인 강한 규칙: CNAME은 같은 이름에 다른 레코드와 공존할 수 없습니다. RFC 1034 §3.6.2는 CNAME이 있는 이름에는 다른 데이터가 없다고 못 박습니다 — 그래서 같은 서브도메인에 CNAME과 MX(또는 TXT, 또 다른 A)를 함께 둘 수 없습니다. 한 이름에 메일과 CNAME이 둘 다 필요하면 불가능하니 A 레코드를 쓰세요. 이미 CNAME인 서브도메인에 인증용 TXT를 얹으려다 걸리는 흔한 함정입니다.
apex 혼동은 정리하고 넘어가면: 루트 example.com은 CNAME으로 만들 수 없습니다. apex에는 필수인 SOA·NS 레코드가 이미 있어 CNAME과 충돌하기 때문입니다. 이 제약은 실재하지만 apex의 문제입니다. 서브도메인에서 CNAME은 완전히 정상입니다.
2. 이름 칸에 넣는 것: 라벨, 오직 라벨만
모든 DNS 화면에는 이름(또는 호스트) 칸이 있고, 거의 전부 입력한 값 뒤에 도메인을 자동으로 붙입니다. 그래서 blog.example.com을 만들려면 이렇게만 넣습니다:
blog
blog.example.com이 아닙니다. 전체 이름을 넣으면 존이 뒤에 붙어 blog.example.com.example.com 레코드가 되고, 아무에게도 해석되지 않습니다. 서브도메인 실수 중 가장 흔하고, 조회해서 두 번 붙은 이름을 보기 전까지는 안 보입니다.
일부 화면은 “이게 완전한 이름이니 붙이지 마라”는 뜻으로 끝에 점을 요구하고(blog.example.com.), Cloudflare UI는 전체 이름을 넣어도 조용히 존을 떼어 줍니다. 하지만 어디서나 통하는 안전한 기본값은: 라벨만 넣는다. api.staging.example.com 같은 다단계 서브도메인이면 라벨은 api.staging입니다.
와일드카드, 그리고 정말 필요한 때
와일드카드 레코드 — 이름 * — 는 자기 레코드가 없는 아무 라벨에나 답합니다. *.example.com을 A 레코드로 두면 무엇이든.example.com이 그 IP로 해석됩니다. 멀티테넌트 구성(customer1., customer2. … 전부 한 앱으로)에서 테넌트마다 레코드를 만들지 않아도 되니 정말 유용합니다.
하지만 와일드카드는 생각보다 좁고, RFC 4592가 함정을 짚어 둡니다. 와일드카드는 명시적 레코드가 없는 이름만 매칭합니다 — blog.example.com을 추가하는 순간 와일드카드는 blog를 더는 커버하지 않습니다. 여러 단계도 매칭하지 않습니다: *.example.com은 a.example.com은 커버해도 a.b.example.com은 못 합니다. 그리고 맞는 TLS 인증서를 마법처럼 만들어 주지도 않습니다 — 와일드카드 DNS 레코드와 와일드카드 SSL 인증서는 각각 따로 설정해야 하는 별개입니다. *는 기본값이 아니라 폴백으로 다루세요. 더는 안 쓰는 앱을 가리키는 와일드카드는 서브도메인 탈취의 표면이 됩니다.
DechoNet으로 확인
- DNS 조회는 정확한 서브도메인을 해석해 레코드가 실제로 무엇을 반환하는지 보여줍니다 — 두 번 붙은 이름 함정(답에
blog.example.com.example.com이 보입니다)을 잡거나, CNAME이 의도한 곳을 가리키는지 확인하거나, 아직 레코드가 없다는NXDOMAIN을 보는 가장 빠른 길입니다. - DNS 전파는 전 세계 리졸버에서 서브도메인을 한꺼번에 확인해, “더 기다려야 한다”(일부 리졸버는 보이고 일부는 아직)와 “레코드가 틀렸다”(아무도 못 봄)를 구분해 줍니다.
해결 체크리스트
- 타입 결정: IP가 있으면 A/AAAA, 플랫폼이 준 호스트 이름을 가리키면 CNAME.
- 이름/호스트 칸에는 라벨만(
blog), 절대blog.example.com전체를 넣지 말 것 — 존은 자동으로 붙습니다. - CNAME이면 그 이름에 다른 레코드가 없는지 확인(MX·TXT·또 다른 A 금지) — RFC 1034 위반입니다.
- 저장한 뒤 DNS 조회로 서브도메인을 조회해, 답이 두 번 붙은 이름이 아니라 내가 넣은 값인지 확인.
- 일부 리졸버만 보이면 옛 TTL이 지날 때까지 기다릴 것 — 이미 맞는 레코드를 다시 고치지 말고 전파를 확인하세요.
이럴 땐 더 파고들기
- 서브도메인이 위임된 경우. 내 존에 서브도메인용
NS레코드가 있다면 그 이름은 다른 네임서버들에 넘어간 것이고, A/CNAME은 이 존이 아니라 그쪽에 만들어야 합니다. 부모 존에서 레코드를 편집해도 아무 일도 안 일어납니다. 변경이 먹어야 마땅한데 안 먹으면 서브도메인 NS 레코드부터 확인하세요. - 아무도 안 읽는 존을 편집 중인 경우. 뭘 바꿔도 반영이 안 되면, 도메인의 권위 네임서버가 지금 편집 중인 DNS 호스트를 실제로 가리키는지 확인하세요. 네임서버를 다른 곳으로 옮긴 도메인은 옛 화면에서 낡은 레코드를 얼마든지 편집하게 놔둡니다.
- 한 이름에 메일과 CNAME이 둘 다 필요한 경우. 불가능합니다. 그 이름을 A 레코드로 바꾸거나, CNAME으로 연결하는 서비스를 다른 라벨로 옮기세요.
내 도메인에서 바로 확인
무료, 가입 불필요. 이 가이드가 다루는 항목을 바로 검사하고 조치 방법을 알려드립니다.