확인 명령
다섯 번의 조회로 도메인의 메일 설정을 거의 다 알 수 있습니다. 웹사이트 호스트명이 아니라 From: 주소에 쓰는 도메인으로 조회하세요(둘이 다를 수 있습니다).
dig +short MX example.com # 받는 메일이 가는 곳
dig +short A mx1.example.com # MX 대상마다 주소로 해석되는지
dig +short TXT example.com | grep -i spf1 # SPF
dig +short TXT _dmarc.example.com # DMARC
dig +short TXT s1._domainkey.example.com # DKIM, 셀렉터를 안다면(여기서는 s1)
Windows에서는 이렇게 합니다.
nslookup -type=mx example.com
nslookup -type=txt _dmarc.example.com
Resolve-DnsName example.com -Type MX
Resolve-DnsName _dmarc.example.com -Type TXT
직접 운영하는 정상 도메인은 이런 모양입니다.
$ dig +short MX example.com
10 mx1.example.com.
20 mx2.example.com.
$ dig +short A mx1.example.com
203.0.113.25
$ dig +short TXT example.com | grep -i spf1
"v=spf1 mx include:_spf.google.com ~all"
$ dig +short TXT _dmarc.example.com
"v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@example.com"
명령을 돌리기 싫다면 이메일 점검이 이 조회를 한 번에 하고 블랙리스트와 정책 점검까지 더해 줍니다. 무엇을 보고 무엇을 보지 않는지는 이 글 끝에 정리했습니다. DNS 조회는 레코드 하나를 게시된 그대로 보여 줍니다.
아래는 응답마다 확인할 것들입니다.
MX: 받는 메일이 가는 곳
MX 한 줄은 우선순위와 호스트명입니다. 보내는 서버는 숫자가 낮은 것부터 시도하고, 숫자가 같으면 나눠서 보냅니다. 흔한 업체 값은 이렇습니다.
- Google Workspace: 새로 설정했다면
1 smtp.google.com., 예전 설정이라면aspmx.l.google.com형태의 레코드 다섯 개. 둘 다 동작합니다. - Microsoft 365:
0 example-com.mail.protection.outlook.com.같은 레코드 하나(최근 설정 중에는mx.microsoft아래 이름을 받는 경우도 있습니다).
자주 틀리는 것들입니다.
- MX가 아예 없음. 보내는 서버는 도메인의 A 레코드로 대신 배달을 시도하고, 대개 메일을 받지 않는 웹 서버로 갑니다. 정말 메일을 받지 않는 도메인이라면 null MX로 알리세요.
example.com. IN MX 0 .(RFC 7505). - 호스트명 대신 IP 주소.
10 203.0.113.25는 잘못된 레코드입니다. MX에는 호스트 이름을 적고, 그 호스트에 A/AAAA 레코드를 둡니다. - 대상이 해석되지 않음. 오타이거나 지워진 호스트입니다. MX 대상마다 두 번째 명령을 돌려 보세요.
- 대상이 CNAME. 표준은 이것을 허용하지 않습니다. 대부분의 발신 서버는 넘어가 주지만 그렇지 않은 곳도 있습니다. MX는 자기 A 레코드가 있는 이름을 가리키게 하세요.
- 이전 작업의 잔재. 새 업체 레코드가 우선순위 1, 예전 업체 레코드가 10으로 남아 있으면, 새 업체가 응답하지 않을 때마다 메일이 예전 시스템으로 갑니다. 이전을 마쳤으면 예전 MX는 지우세요.
- 메일 호스트명이 웹 프록시 뒤에 있음. Cloudflare에서 프록시(주황색 구름)를 켠 레코드는 웹 트래픽만 전달합니다. 그 이름으로 가는 25번 포트 연결은 아무 데도 닿지 않습니다. 메일 호스트명은 DNS 전용이어야 합니다.
DNS가 맞아도 서버가 응답한다는 증명은 아닙니다. 25번 포트로 밖에 나갈 수 있는 곳에서 확인하세요(가정용 인터넷과 많은 클라우드 업체가 이 포트를 막기 때문에, 내 노트북에서 실패했다고 해서 알 수 있는 것은 별로 없습니다).
$ nc -v mx1.example.com 25
Connection to mx1.example.com 25 port [tcp/smtp] succeeded!
220 mx1.example.com ESMTP Postfix
220 인사말이 오면 메일 서버가 듣고 있는 것입니다. STARTTLS에서 내놓는 인증서를 보려면 이렇게 합니다.
openssl s_client -starttls smtp -connect mx1.example.com:25 -servername mx1.example.com </dev/null 2>/dev/null \
| openssl x509 -noout -subject -dates
SPF: 보낼 수 있는 곳
SPF는 도메인 자체에 두는 TXT 레코드이고 v=spf1로 시작합니다. 도메인에는 사이트 소유 확인용 등 다른 TXT 레코드도 있으니 spf1로 걸러서 보세요.
자주 틀리는 것들입니다.
- SPF 레코드가 두 개.
v=spf1로 시작하는 TXT 레코드가 두 개면 영구 오류이고, 수신 서버는 유효한 SPF가 없는 것으로 봅니다. 두 번째 업체의 설정 안내에 “이 레코드를 추가하세요”라고 적혀 있고 누군가 정말 그대로 추가했을 때 흔히 생깁니다. 하나로 합치세요. - 조회 횟수 초과.
include,a,mx,ptr,exists,redirect가 DNS 조회를 하나씩 쓰고, include 안의 include도 세며, 한도는 10회입니다.ip4:와ip6:는 조회를 쓰지 않습니다. 전체 트리를 세고 줄이는 방법은 SPF PermError: DNS 조회 10회 초과에 있습니다. - 끝이
+all. 인터넷 전체에 권한을 주는 것입니다.~all이나-all을 쓰세요. - 더는 쓰지 않는 서비스의 include. 조회 횟수를 낭비하고, 남에게 계속 내 도메인으로 보낼 권한을 줍니다.
- 엉뚱한 이름에 둔 SPF. SPF는 상속되지 않습니다.
news.example.com이 봉투 발신자에 그 도메인을 써서 메일을 보낸다면news.example.com에 별도 레코드가 필요합니다.
SPF는 From: 주소가 아니라 봉투 발신자(Return-Path)를 검사합니다. 그래서 메일 서비스가 자기 반송 도메인을 쓰면 SPF 레코드가 완벽해도 DMARC에는 도움이 되지 않습니다. 이 부분은 이메일 전달률 가이드에서 다룹니다.
DMARC: 정책
DMARC는 도메인 앞에 _dmarc.을 붙인 이름의 TXT 레코드입니다. 확인할 것은 이렇습니다.
- 이름이 맞는지. 도메인 자체나
dmarc.example.com이 아니라_dmarc.example.com입니다. v=DMARC1이 맨 앞에 있고, 그다음p=가 있는지.- 레코드가 정확히 하나인지. DMARC 레코드가 두 개면 수신 서버는 아무것도 적용하지 않습니다.
- 정책.
p=none은 모니터링 전용이고 보안 점검 도구가 지적하는 값입니다.quarantine과reject가 강제 정책입니다. 안전하게 올리는 방법은 DMARC p=none·quarantine·reject 차이와 올리는 시점에 있습니다. rua=가 있는지. 누군가 집계 보고서를 받아야 합니다. 없으면 눈을 감고 운전하는 셈입니다.
서브도메인에 자기 DMARC 레코드가 없으면 수신 서버는 조직 도메인의 레코드를 쓰고, sp=가 있으면 그 정책을 적용합니다. 그래서 _dmarc.mail.example.com이 없다고 해서 꼭 빈틈은 아닙니다.
DKIM: 셀렉터를 알아야 한다
DKIM 키는 셀렉터._domainkey.도메인에 있고, DNS에는 이것을 목록으로 보여 주는 방법이 없습니다. 정확한 이름을 알려면 그 도메인이 보낸 메일을 열고 DKIM-Signature 헤더에서 d=(도메인)와 s=(셀렉터)를 읽으세요.
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=google; ...
$ dig +short TXT google._domainkey.example.com
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx3v..." "...IDAQAB"
한 응답 안에 따옴표로 묶인 문자열이 여러 개인 것은 2048비트 키에서 정상입니다. 같은 이름에 응답이 두 개 따로 오는 것은 비정상이고, p=가 비어 있는 것은 키를 폐기했다는 뜻입니다. Microsoft 365와 많은 메일 서비스는 셀렉터 이름이 업체가 보관하는 키를 가리키는 CNAME이라서, dig가 키 앞에 CNAME 줄을 먼저 보여 줍니다.
잘 알려진 셀렉터로는 google(Google Workspace), selector1·selector2(Microsoft 365), protonmail·protonmail2·protonmail3(Proton Mail), fm1~fm3(Fastmail), s1·s2(SendGrid 등)가 있습니다. 메일 서비스마다 자기 이름을 쓰는 경우가 많으니, 확실한 출처는 메일 헤더뿐입니다.
레코드는 있는데 수신 서버가 계속 실패를 보고한다면 다른 문제입니다. DKIM 실패와 “body hash did not verify” 원인 찾기를 보세요.
바깥에서, 그리고 변경 직후에 확인하기
내 컴퓨터는 캐시된 응답을 쓰고 있을 수 있습니다. 레코드를 바꾼 뒤에는 공용 리졸버와 권한 있는(authoritative) 서버의 답을 비교하세요.
dig +short NS example.com
dig +short TXT _dmarc.example.com @ns1.your-dns-host.net # 권한 서버의 답
dig +short TXT _dmarc.example.com @1.1.1.1
dig +short TXT _dmarc.example.com @8.8.8.8
권한 서버에는 새 값이 있는데 공용 리졸버가 아직 예전 값을 보여 준다면 캐시 때문입니다. 예전 레코드의 TTL이 지나면 따라옵니다.
DechoNet 이메일 점검이 보는 것
이메일 점검은 공용 DNS-over-HTTPS로 이 조회들을 하고 점수를 매깁니다. 결과를 제대로 읽으려면 이것을 알아 두세요.
- MX, SPF, DMARC, DKIM이 각각 점수의 4분의 1입니다. DMARC 정책이
none이거나 SPF가 조회 한도를 넘으면 그보다 작은 감점이 있습니다. - SPF 조회 횟수는 최상위 레코드만 셉니다. 레코드에 적힌 조회 메커니즘을 세는 것이고 include를 따라 들어가지 않으므로, 실제 합계는 더 클 수 있습니다.
- DKIM은 추측으로 찾습니다. 흔한 셀렉터 18개를 시도합니다.
google,default,k1,selector1,selector2,s1,s2,protonmail,protonmail2,protonmail3,mesmtp,fm1,fm2,fm3,zoho,20230601,20221208,20210112입니다. “감지 안 됨”은 이 이름들에 키가 없다는 뜻이지, 도메인이 서명하지 않는다는 뜻이 아닙니다. - 블랙리스트는 MX 호스트를 기준으로 봅니다. MX 서버 최대 4개의 IP를 Spamhaus ZEN, SpamCop, Barracuda, PSBL에 조회합니다. 즉 메일을 받는 서버입니다. 메일을 다른 서비스로 보낸다면 발신 IP를 대신 넣으세요. IP를 넣으면 그 IP의 블랙리스트 등재 여부와 역방향 DNS(PTR)를 확인합니다. Spamhaus는 공용 리졸버를 거친 조회를 거부하므로 “깨끗함”이 아니라 항상 “확인 불가”로 나옵니다.
- BIMI, MTA-STS, TLS-RPT, DANE는 참고용으로 보여 주며 점수에는 영향이 없습니다.
없는 것을 순서대로 설정하려면 이메일 전달률 가이드부터 시작하세요.
내 도메인에서 바로 확인
무료, 가입 불필요. 이 가이드가 다루는 항목을 바로 검사하고 조치 방법을 알려드립니다.