내 도메인에서 보낸 이메일은 어떻게 진짜임을 증명할까

블로그에 구독 메일을 붙이면서 Resend를 사용했습니다. 프로그램에서 이메일을 발송할 수 있게 해 주는 서비스입니다. 구독자에게 보일 발신 주소는
newsletter@wonkooklee.com입니다.제가 Resend에 발송을 요청하면 Resend의 메일 서버가 받는 사람의 메일 서버로 메일을 전달합니다. Gmail을 쓰는 구독자라면 Google의 서버가 받아서 메일함에 넣습니다.
Gmail은 이 메일을 정말 wonkooklee.com에서 보냈다고 어떻게 판단할까요?
이 글에서 다루는 내용
제 도메인으로 메일을 보낸다고 해서 메일 서버까지 직접 운영해야 하는 것은 아닙니다. 외부 서비스에 발송을 맡길 수도 있습니다. 받는 쪽에서 확인할 것은 그 서비스가 제 도메인으로 메일을 보낼 권한을 받았는가입니다.
이 글은 newsletter@wonkooklee.com으로 보낸 메일을 따라가며 수신 서버가 그 권한을 확인하는 과정을 정리합니다.
1. 보낸 사람 칸에 제 주소가 있다고 제가 보낸 메일은 아닙니다
이메일에는 본문 외에도 제목과 보낸 사람 같은 정보를 담는 헤더가 있습니다. 다음은 그중 보낸 사람을 나타내는 From 헤더입니다.
From: Wonkook Lee <newsletter@wonkooklee.com>
메일 앱은 이 값을 읽어 보낸 사람을 표시합니다. 하지만 From은 메일을 구성하는 쪽에서 작성하는 값입니다. 이 문자열을 적었다고 해서 도메인을 소유했거나 그 도메인으로 메일을 보낼 권한이 있다는 증거가 생기지는 않습니다.
물론 정상적인 발송 서비스는 사용자가 아무 주소로나 메일을 보내지 못하도록 제한합니다. 그러나 받는 쪽에서는 상대가 그런 서비스를 썼는지부터 알 수 없습니다. 제 도메인을 사칭하려는 사람이 자기 서버에서 From을 써서 보낼 수도 있습니다.
수신 서버는 메일 안에 적힌 주장 외에 확인할 근거가 필요합니다. 여기서 도메인의 DNS 설정을 사용합니다. DNS는 도메인의 IP 주소를 찾는 데 쓰이지만, 도메인 관리자가 공개하는 텍스트 정보도 저장할 수 있습니다. 발송 권한과 서명 검증에 필요한 정보도 여기에 등록합니다.
DNS 정보는 누구나 읽을 수 있지만, 내용을 등록하거나 바꾸려면 해당 도메인의 DNS 관리 권한이 있어야 합니다. 사칭 메일을 만든 사람이 From을 바꿀 수는 있어도, 제 도메인의 DNS 설정까지 마음대로 바꿀 수는 없습니다. 수신 서버는 메일과 별개로 이 설정을 조회해 검사합니다. (Resend의 발신 인증 안내)
2. SPF와 DKIM은 서로 다른 것을 확인합니다
SPF: 이 서버가 보내도 되는가
SPF(Sender Policy Framework)는 도메인 관리자가 DNS에 '이 서버들은 우리 도메인으로 메일을 보내도 된다'고 등록하는 방식입니다. 수신 서버는 자신에게 메일을 전달한 서버의 IP 주소가 허용된 범위에 있는지 확인합니다.
그런데 이메일에는 보낸 사람을 표시하는 주소 외에, 배달에 실패했을 때 알림을 받을 주소도 있습니다. 발송 서비스가 잘못된 수신 주소 등을 관리할 수 있도록 이 주소를 따로 지정할 수 있습니다. 메일을 전달하는 과정에서는 이를 MAIL FROM이라고 부릅니다.
구독 메일에서 두 주소가 다음과 같다고 가정해 보겠습니다. 설명을 위한 예시이며 실제 메일에서 추출한 값은 아닙니다.
독자에게 보이는 보낸 사람 (From): newsletter@wonkooklee.com
배달 실패 알림을 받을 주소 (MAIL FROM): bounces@send.wonkooklee.com
SPF는 여기서 MAIL FROM의 도메인인 send.wonkooklee.com의 DNS 설정을 조회합니다. 발송 서버가 허용된 서버라면 SPF를 통과합니다. 화면에 보이는 From 주소가 진짜인지까지 확인한 것은 아닙니다. (SPF 명세)

DKIM: 어느 도메인의 서명인가
DKIM(DomainKeys Identified Mail)은 메일에 전자서명을 붙여 어느 도메인이 서명했는지 확인할 수 있게 합니다. 여기서 서명은 메일 끝에 붙이는 이름이나 연락처가 아니라, 메일 내용을 바탕으로 계산한 검증용 데이터입니다.
발송 측은 비밀로 보관하는 개인키로 서명을 만듭니다. 수신 측은 그 키와 짝을 이루는 공개키로 서명을 검사합니다. 공개키는 DNS에서 누구나 읽을 수 있지만, 공개키만으로 같은 서명을 만들 수는 없습니다. 이 검사를 통해 서명에 사용한 키를 확인하고, 서명으로 보호한 내용의 변조를 감지할 수 있습니다. (DKIM 명세)
예를 들어 Resend가 제 도메인용 개인키로 서명하고, 저는 그에 대응하는 공개키를 제 도메인의 DNS에 등록할 수 있습니다. 수신 서버는 서명에 적힌 d=wonkooklee.com과 s=resend를 합쳐 resend._domainkey.wonkooklee.com에서 공개키를 찾아 검증합니다. d=는 서명에 사용하는 도메인이고, s=는 그 도메인에 등록된 여러 키 중 하나를 고르는 이름(셀렉터)입니다. 그래서 Zoho(zmail)와 Resend(resend)가 같은 도메인에 각자 공개키를 둘 수 있습니다. (Resend 도메인 설정)
다만 다른 도메인의 관리자도 자기 키로 서명할 수 있습니다. 유효한 서명이 있다는 사실만으로 그 메일이 제 도메인에서 왔다고 판단할 수는 없습니다.
3. 인증한 도메인과 From을 연결하는 DMARC
누군가 자신이 관리하는 sender.example 도메인으로 메일을 보내면서, 독자에게 보이는 From만 제 주소로 바꿨다고 가정해 보겠습니다.
화면에 보이는 From: newsletter@wonkooklee.com
MAIL FROM: bounces@sender.example
DKIM 서명 도메인: d=sender.example
SPF: sender.example이 허용한 서버이므로 통과
DKIM: sender.example의 키로 만든 유효한 서명이므로 통과
SPF와 DKIM은 각각 확인해야 할 것을 제대로 확인했습니다. 하지만 두 검사가 확인한 도메인은 모두 sender.example입니다. 독자가 보는 wonkooklee.com은 아직 아무도 확인하지 않았습니다.
DMARC(Domain-based Message Authentication, Reporting and Conformance)는 SPF나 DKIM이 확인한 도메인을 From의 도메인과 비교합니다. 위 예제에서는 서로 다른 도메인이므로 DMARC에 실패합니다.
이제 실제 도메인 관리자가 발송을 맡긴 경우를 생각해 보겠습니다. 발송 서비스가 wonkooklee.com에 등록된 공개키와 짝이 되는 개인키로 서명하면 결과가 달라집니다.
화면에 보이는 From: newsletter@wonkooklee.com
DKIM 서명 도메인: d=wonkooklee.com
DKIM 서명 검증: 통과
From의 도메인과 서명 도메인 비교: 일치
→ DMARC 통과
이처럼 인증한 도메인과 From의 도메인이 맞는 관계를 정렬(alignment)이라고 부릅니다. DMARC는 다음 중 한쪽만 만족해도 통과합니다.
(SPF 통과 + SPF 도메인이 From과 정렬)
또는
(DKIM 통과 + 서명 도메인이 From과 정렬)
→ DMARC 통과
따라서 SPF가 실패해도 DKIM의 인증과 정렬을 모두 만족했다면 DMARC는 통과합니다. 반대로 앞의 사칭 예제처럼 SPF와 DKIM을 모두 통과해도 어느 쪽도 From과 정렬되지 않으면 실패합니다. (DMARC 명세의 정렬 설명)
앞서 SPF 예제에 나온 send.wonkooklee.com은 어떨까요? 기본 설정에서는 같은 조직 도메인을 공유하는 하위 도메인도 정렬을 허용합니다. 그래서 이 예제에서는 send.wonkooklee.com과 wonkooklee.com도 정렬됩니다. 도메인이 완전히 같아야 하는 엄격한 설정도 있지만, 여기서는 기본 동작을 기준으로 설명합니다.
DMARC가 쓰는 정보는 수신 서버에 도착하는 시점도 다릅니다. 메일은 발송 서버와 수신 서버가 주고받는 SMTP 대화로 전달됩니다. 발송 서버는 연결한 다음 반송 주소(MAIL FROM)와 받는 주소(RCPT TO)를 먼저 알리고, DATA 명령 뒤에 From을 포함한 헤더와 본문을 보냅니다. SMTP에서는 앞의 두 주소를 봉투(envelope), DATA로 보내는 헤더와 본문을 내용(content)이라고 부릅니다. (SMTP 명세)
이 순서 때문에 SPF 레코드를 -all로 끝낼 때는 주의해야 합니다. -all은 목록 밖의 서버를 실패로 판정해 달라는 뜻이라, 수신 서버가 SPF만 보고 DATA 전에 메일을 거부할 수 있습니다. 그러면 DKIM이 정렬되어 DMARC를 통과했을 메일도 전달되지 못합니다. From이 드러나기 전에 끝났으므로 DMARC 집계 보고서에도 남지 않습니다. (DMARC 명세의 SPF 관련 주의)
wonkooklee.com과 send.wonkooklee.com의 SPF 레코드는 둘 다 ~all로 끝납니다. SPF 명세는 softfail 결과만으로 메일을 거부하지 않도록 권고하므로, 이 설정에서는 SPF 하나 때문에 메일이 먼저 거부될 가능성이 작습니다. (SPF 명세의 softfail)
4. 통과하지 못한 메일을 어떻게 다룰 것인가
DMARC에 실패했다고 판단한 다음에는 그 메일을 어떻게 처리할지 결정해야 합니다. 도메인 관리자는 DNS의 DMARC 설정에 p라는 항목으로 처리 방침을 공개합니다.
p=none: DMARC 실패를 이유로 특별히 격리하거나 거부해 달라고 요청하지 않습니다.p=quarantine: 의심스러운 메일로 취급해 달라고 요청합니다. 정크 메일함으로 보내는 처리가 여기에 해당할 수 있습니다.p=reject: 수신을 거부해 달라고 요청합니다.
최종 처리는 수신 서버가 자체 정책까지 고려해 결정합니다. none이라고 무조건 받은편지함에 들어가는 것도, reject라고 모든 수신 서비스가 예외 없이 차단하는 것도 아닙니다. (Resend의 DMARC 정책 설명)
처음부터 reject로 설정하면 사칭 메일을 강하게 막을 수 있을 것 같습니다. 문제는 정상 메일의 설정도 빠져 있을 수 있다는 점입니다.
예를 들어 일반 메일을 보내는 서비스인 Zoho와 구독 메일을 보내는 Resend가 같은 From 도메인을 사용한다고 하겠습니다. Zoho 쪽만 검사한 뒤 정책을 강화했는데, Resend 쪽은 From과 정렬되지 않는 도메인으로만 인증되고 있었다면 구독 메일도 거부 대상이 됩니다. 도메인 관리자가 실제로 발송을 맡겼더라도, 수신 서버가 그 권한을 확인할 수 있도록 설정하지 않으면 정상 메일도 검사에 실패할 수 있습니다.
그래서 처음에는 none으로 두고 보고서를 받도록 설정합니다. 정상 메일의 인증과 정렬을 확인한 뒤 quarantine이나 reject를 검토합니다. none → quarantine → reject는 반드시 밟아야 하는 절차라기보다 정상 메일을 차단할 위험을 줄이면서 정책을 강화하는 운영 방법입니다. (DMARC 명세의 도입 절차)
보고서는 제가 놓친 발송 경로를 보여 줍니다
제가 보낸 메일이 Gmail에서 인증을 통과했는지는 제 서버의 발송 기록만으로 알 수 없습니다. 받는 쪽에서 검사한 결과를 알려 주어야 합니다.
DMARC에는 이를 위한 집계 보고서 기능이 있습니다. DNS 설정의 rua 항목에 보고서를 받을 이메일 주소를 지정하면, 보고 기능을 제공하는 수신 서비스가 검사 결과를 모아 보내 줍니다. 보고서에는 발송 서버의 IP, 메일 수, SPF·DKIM 및 DMARC 평가 결과 등이 들어갑니다. (DMARC 집계 보고서 명세)
제 rua 주소에는 Google이 보낸 보고서가 이렇게 도착했습니다. 검사 결과는 압축한 XML 첨부 파일에 들어 있습니다.

이 보고서를 보면 어떤 발송 경로가 정상적으로 인증되는지, 예상하지 못한 서버가 제 도메인을 사용하는지 살펴볼 수 있습니다. 실패한 기록이 있다면 사칭 시도인지, 제가 사용하는 서비스의 설정 누락인지 조사할 단서가 됩니다. (Resend의 보고서 읽기 안내)
보고서가 모든 메일의 배달 결과를 알려 주는 것은 아닙니다. 보고 기능을 제공하는 수신자가 관측한 인증 결과이며, 실제로 사람이 읽었는지까지 알려 주지는 않습니다. 정책을 강화하기 전에 정상적인 발송이 빠져 있지 않은지 살피는 데 사용합니다.
5. 내 도메인에서는 어디까지 설정되어 있을까
2026년 9월 27일 조회한 DNS에는 wonkooklee.com의 SPF에 Zoho가 등록되어 있었습니다. Resend용 설정은 따로 있었습니다. 반송용 하위 도메인인 send.wonkooklee.com의 SPF와, Resend가 서명한 메일을 검증할 공개키가 등록되어 있었습니다.
wonkooklee.com의 SPF에 Zoho만 보인다고 해서 Resend 설정이 누락되었다고 판단할 수는 없습니다. SPF는 메일의 실제 MAIL FROM 도메인에서 검사하기 때문입니다. Resend도 반송용 하위 도메인에 SPF를 설정하는 구조를 안내합니다. (Resend의 반송 주소 설정 안내)
DMARC의 처리 방침은 p=none이었고, rua 보고서 수신 주소도 등록되어 있었습니다. 실패한 메일을 거부해 달라고 요청하기 전에 보고서를 받아 살펴볼 수 있는 설정입니다.

DNS에 레코드가 있다는 사실만으로 실제 발송 메일의 통과 여부까지 알 수는 없습니다. Zoho와 Resend에서 보낸 메일을 각각 받아 수신 서버가 기록한 인증 결과를 확인하고, 집계 보고서와 대조해야 정책을 강화할 근거가 생깁니다.
6. 인증을 통과한 메일에만 붙는 로고, BIMI
BIMI(Brand Indicators for Message Identification)는 이를 지원하는 메일 서비스에서 발신 도메인과 연결된 로고를 표시하기 위한 규격입니다. 수신자가 메일 목록에서 발신자를 알아보도록 돕습니다.
그러려면 먼저 그 메일이 해당 도메인의 메일인지 확인되어야 합니다. Google의 BIMI 안내는 DMARC 통과와 함께 quarantine 또는 reject 정책을 전체 대상에 적용할 것을 요구합니다. p=none만으로는 이 요건을 만족하지 못합니다.
또 Gmail은 그 도메인과 로고에 대한 외부 인증기관의 인증서를 요구합니다. VMC와 CMC가 이런 인증서의 종류입니다. 로고 파일과 DNS 레코드만 준비한다고 곧바로 표시되는 것은 아닙니다. 지원 여부와 표시 조건은 수신 서비스마다 확인해야 합니다. (Google의 BIMI 설정 안내)

제 도메인은 앞서 확인한 시점에 p=none이었고, 기본 BIMI 레코드도 조회되지 않았습니다. 로고를 표시하려면 먼저 정상 메일이 DMARC를 통과하는지 확인하고 정책을 강화할 수 있어야 합니다. 로고 때문에 정책부터 바꿨다가 구독 메일이 거부된다면 순서가 뒤바뀐 셈입니다.
앞에서 살펴본 관계를 한 그림에 모으면 다음과 같습니다. 화살표는 수신 서버가 메일 한 통을 받아 판단하기까지의 흐름입니다.
보낸 사람을 확인하는 것과 메일을 믿는 것
newsletter@wonkooklee.com이라는 주소를 정하는 일은 간단합니다. 그 주소로 발송하도록 서비스를 설정하고, 수신자가 확인할 근거를 DNS에 공개하고, 실제로 인증이 통과하는지 살피는 일은 그 뒤에 남습니다.
DMARC가 통과하면 수신 서버는 From 도메인과 연결된 인증 근거를 확보합니다. 하지만 그 결과가 본문의 사실 여부나 링크의 안전성까지 보증하지는 않습니다. 공격자가 자기 도메인으로 보내는 메일도 발신 인증을 정상적으로 통과할 수 있습니다. (DMARC 명세의 피싱 방어 범위)
제 구독 메일에서도 다음에 확인할 것은 실제 수신 결과입니다. Zoho와 Resend에서 보낸 메일이 각각 DMARC를 통과하는지 확인하고, 보고서에서 설정을 빠뜨린 발송 경로가 없는지 살펴봐야 합니다. 그 결과가 있어야 제 도메인을 사칭한 메일을 거부해 달라는 정책도 적용할 수 있습니다.
References
- RFC 7208: SPF: 발송 서버 권한 검사와 MAIL FROM
- RFC 6376: DKIM: 도메인 서명과 검증
- RFC 9989: DMARC: From 정렬과 정책. 2026년 5월 RFC 7489를 대체한 명세입니다.
- RFC 9990: DMARC Aggregate Reporting: 집계 보고서
- Resend: Verified Domains: 외부 발송 서비스의 도메인 설정
- Google: Set up BIMI: Gmail의 로고 표시 요건
