📧 시작: 메일이 스팸으로 가는 이유

자체 메일 서버를 구축하면서 가장 큰 고민은 “내가 보낸 메일이 스팸함으로 가지 않을까?“였습니다.

오늘은 Gmail, Outlook 등 주요 메일 서비스에서 신뢰받는 메일 서버를 구축하고, Mail-Tester에서 10/10 만점을 받기까지의 과정을 공유합니다.

🛠️ 초기 설정: 기본 인증 체계

SPF 레코드

가장 먼저 SPF(Sender Policy Framework)를 설정했습니다.

1
chloe.ai.kr.  TXT  "v=spf1 ip4:152.69.234.128 ~all"

이 레코드는 “이 도메인의 메일은 152.69.234.128 IP에서만 발송됩니다"라고 선언합니다.

DMARC 정책

DMARC는 SPF와 DKIM의 인증 실패 시 어떻게 처리할지 정의합니다.

1
_dmarc.chloe.ai.kr.  TXT  "v=DMARC1; p=none; rua=mailto:postmaster@chloe.ai.kr"

초기에는 p=none으로 모니터링 모드로 운영합니다.

rDNS (역방향 DNS)

IP 주소를 도메인으로 역조회했을 때 올바른 호스트명이 나와야 합니다.

1
2
$ dig +short -x 152.69.234.128
mail.yeonghoon.kim.

🚨 문제 1: DNS 레코드 길이 제한

문제 발견

DKIM 키를 2048비트 RSA로 생성했더니 TXT 레코드 값이 420글자가 되었습니다. 하지만 DNS 공급자는 250자 제한이 있었죠.

1
2
3
# 기존 DKIM 키 확인
$ docker exec smtp-server cat /etc/opendkim/keys/chloe.ai.kr/mail.txt
# 결과: 420글자 (너무 길다!)

해결 방법

1024비트 RSA로 재생성하여 244글자로 줄였습니다.

1
2
3
4
5
6
7
8
9
# 1024비트로 재생성
$ docker exec smtp-server bash -c '
  cd /etc/opendkim/keys/chloe.ai.kr
  opendkim-genkey -b 1024 -d chloe.ai.kr -s mail
  chown opendkim:opendkim mail.private mail.txt
'

# SMTP 서버 재시작
$ docker restart smtp-server

결과: 244글자로 DNS 등록 성공 ✅

⚠️ 참고: 1024비트는 2048비트보다 보안 강도가 낮지만, DNS 제한 때문에 어쩔 수 없는 선택이었습니다.

🔍 문제 2: HELO/rDNS 불일치

문제 발견

Gmail 헤더를 확인하니 불일치가 발견되었습니다:

Received: from smtp.yeonghoon.kim (mail.yeonghoon.kim. [152.69.234.128])
              ^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^^
              HELO 이름            rDNS 이름 (불일치!)

SMTP 서버가 자신을 smtp.yeonghoon.kim으로 소개하는데, rDNS는 mail.yeonghoon.kim로 설정되어 있었습니다.

해결 방법

Postfix 설정을 수정했습니다.

1
2
$ docker exec smtp-server postconf -e "myhostname = mail.yeonghoon.kim"
$ docker exec smtp-server postfix reload

결과: 완벽 일치! ✅

Received: from mail.yeonghoon.kim (mail.yeonghoon.kim. [152.69.234.128])
              ^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^^
              완벽 일치!

📉 문제 3: SpamAssassin 점수 개선

초기 상태

Mail-Tester 결과: 8.6/10

SpamAssassin 분석 결과:

Score: -1.4

감점 항목:
  -1.396  MISSING_DATE    Date 헤더 누락
  -0.14   MISSING_MID     Message-ID 헤더 누락

해결 방법

Python 메일 발송 코드에 두 줄만 추가했습니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
from email.utils import formatdate, make_msgid

# 메일 생성
msg = MIMEMultipart()
msg['From'] = formataddr(("Chloe", "chloe@chloe.ai.kr"))
msg['To'] = "recipient@example.com"
msg['Subject'] = "Test Email"

# ✨ 핵심: 이 두 줄 추가
msg['Date'] = formatdate(localtime=True)
msg['Message-ID'] = make_msgid(domain="chloe.ai.kr")

# 본문 추가 및 발송
# ...

결과

Mail-Tester: 10/10 만점! 🏆

SpamAssassin 점수: -1.4 → -2.9 (약 1.5점 개선)

모든 인증 항목 PASS:

  • ✅ SPF: PASS
  • ✅ DKIM: PASS
  • ✅ DMARC: PASS
  • ✅ rDNS: PASS
  • ✅ Headers: PASS

💡 학습 포인트

1. 메일 인증의 4대 요소

항목목적설정 위치
SPFIP 인증DNS TXT 레코드
DKIM서명 검증DNS TXT 레코드 + SMTP 서버
DMARC정책 설정DNS TXT 레코드
rDNS역방향 조회ISP/호스팅 제공자

2. DNS 레코드 길이 제한

  • 대부분의 DNS 제공자: 255자 제한
  • DKIM 키 선택:
    • 2048비트: 더 안전하지만 420자 (❌ DNS 제한 초과)
    • 1024비트: 덜 안전하지만 244자 (✅ DNS 등록 가능)

3. SMTP 설정의 일관성

HELO 이름과 rDNS는 반드시 일치해야 합니다. 불일치는 스팸 지표로 사용됩니다.

4. 메일 헤더의 중요성

DateMessage-ID 헤더 누락은 SpamAssassin에서 큰 감점 요소입니다. 반드시 포함하세요!

🎯 최종 결과

인증 상태

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# SPF 확인
$ dig +short TXT chloe.ai.kr | grep spf
"v=spf1 ip4:152.69.234.128 ~all"

# DKIM 확인
$ dig +short TXT mail._domainkey.chloe.ai.kr
"v=DKIM1; h=sha256; k=rsa; p=MIGfMA0GCS..."

# DMARC 확인
$ dig +short TXT _dmarc.chloe.ai.kr
"v=DMARC1; p=none; rua=mailto:postmaster@chloe.ai.kr"

# rDNS 확인
$ dig +short -x 152.69.234.128
mail.yeonghoon.kim.

📚 참고 자료

마치며

자체 메일 서버 구축은 처음에는 복잡해 보이지만, 각 인증 요소를 하나씩 점검하면 충분히 신뢰받는 메일 서버를 만들 수 있습니다.

특히 Date와 Message-ID 헤더 추가만으로도 점수가 크게 올라가는 것을 보고, 작은 디테일이 얼마나 중요한지 다시 한번 느꼈습니다.

이제 Gmail, Outlook, Yahoo 등 어디든 차단 없이 메일을 보낼 수 있게 되었습니다! 🎉


이 글은 실제 메일 서버 구축 경험을 바탕으로 작성되었습니다.