메일서버 수신 인증 점검하기 (SPF / DKIM / DMARC 검증편)
목차
이 글이 왜 필요한가 (송신 검증 vs 수신 검증) #
메일 서버를 처음 구축하면 보통 “내가 보낸 메일이 스팸함에 안 가게” 하는 데 집중합니다. 그래서 mail-tester.com 같은 곳에서 DKIM 10/10 받으면 “다 끝났다"고 생각하기 쉬운데, 사실 그건 내가 보내는(송신) 메일에 서명을 잘 달고 있는지만 확인한 겁니다.
이 글에서 다루는 건 반대 방향, 즉 다른 사람이 내 서버로 보낸 메일을 받을 때, 그 메일이 진짜인지(SPF/DKIM/DMARC 통과하는지) 내 서버가 검사하고 있는가입니다. 이 검증이 빠져 있으면, 발신자를 위조한 스팸/피싱 메일이 그대로 내 받은편지함에 들어올 수 있습니다.
용어부터 짧게 정리하면:
- SPF (Sender Policy Framework): “이 도메인 메일은 이 IP에서만 보내야 정상"이라고 DNS에 미리 선언해두고, 받는 쪽이 실제 발신 IP와 대조하는 방식입니다.
- DKIM (DomainKeys Identified Mail): 메일 본문/헤더에 암호 서명을 붙여서, 중간에 내용이 바뀌지 않았고 진짜 그 도메인에서 보냈다는 걸 증명하는 방식입니다.
- DMARC (Domain-based Message Authentication): SPF/DKIM 검사 결과를 종합해서 “둘 다 실패하면 어떻게 처리할지(거부/격리/통과)“를 DNS에 선언해두는 정책입니다.
셋 다 “송신"과 “수신” 양쪽에 각각 관련 기능이 있는데, 이 글은 수신 검증에 집중합니다.
1단계: 지금 뭐가 켜져 있고 뭐가 빠져 있는지 확인하기 #
1-1. DKIM이 “검증 모드"로 동작하는가 #
sudo opendkim-testkey -d snsoz.com -s mail -vvv
이 명령은 송신용 확인입니다. 내 DKIM 개인키/공개키(DNS TXT 레코드)가 서로 짝이 맞는지 확인하는 것이지, 수신 메일을 검증하고 있는지는 알려주지 않습니다.
수신 검증 여부는 아래로 확인합니다.
grep -E "Mode|Socket" /etc/opendkim.conf
결과 예시와 의미:
| 결과 | 의미 |
|---|---|
Mode s |
서명(송신)만 함. 수신 검증 안 함. |
Mode v |
검증(수신)만 함. 서명 안 함. |
Mode sv |
서명 + 검증 둘 다 함. (원하는 상태) |
s만 있고 v가 없다면 아래처럼 고쳐줍니다.
sudo nano /etc/opendkim.conf
Mode 줄을 찾아서:
Mode sv
로 바꾸고 저장한 뒤 재시작합니다.
sudo systemctl restart opendkim
참고:
smtpd_milters에 이미 opendkim 소켓이 등록돼 있다면(대부분 처음 DKIM 서명 설정할 때 등록해뒀을 것입니다), Postfix 쪽은 따로 손댈 게 없습니다.Mode에v만 추가하면 같은 milter가 수신 메일도 검증하기 시작합니다.
1-2. SPF 검증기가 설치돼 있는가 #
dpkg -l | grep spf
또는
postconf -n | grep policy
postfix-policyd-spf-python 또는 postfix-policyd-spf-perl 같은 패키지가
안 보이고, postconf -n 결과에도 check_policy_service 관련 줄이 없다면
SPF 검증을 전혀 안 하고 있는 상태입니다. (2단계에서 설치)
1-3. DMARC 검증기가 설치돼 있는가 #
systemctl status opendmarc
또는
dpkg -l | grep dmarc
Unit opendmarc.service could not be found 같은 메시지가 뜨거나 dpkg 목록에
아무것도 안 잡히면 DMARC 검증도 안 하고 있는 상태입니다. (3단계에서 설치)
한 번에 세 가지 다 확인하고 싶으면:
grep Mode /etc/opendkim.conf
dpkg -l | egrep "spf|dmarc"
postconf -n | grep policy
2단계: SPF 검증 추가하기 #
설치 #
sudo apt update
sudo apt install postfix-policyd-spf-python
설치 확인:
dpkg -l | grep spf
master.cf에 SPF 검사 프로세스 등록 #
sudo nano /etc/postfix/master.cf
맨 아래에 추가:
policyd-spf unix - n n - 0 spawn
user=policyd-spf argv=/usr/bin/policyd-spf
두 번째 줄은 반드시 탭(Tab)이나 스페이스로 들여쓰기가 돼 있어야 첫 줄과 이어지는 설정으로 인식됩니다. 그냥 줄바꿈만 하면 별개 서비스로 잘못 인식되니 주의하세요.
main.cf에서 실제로 검사하도록 연결 #
sudo nano /etc/postfix/main.cf
smtpd_recipient_restrictions에 check_policy_service 줄을 추가합니다.
기존에 이미 설정이 있다면 통째로 바꾸지 말고, 그 안에 한 줄만 끼워 넣으세요.
없다면 아래처럼 통째로 넣어도 됩니다:
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_pipelining,
reject_non_fqdn_recipient,
reject_unknown_recipient_domain,
check_policy_service unix:private/policyd-spf,
reject_unknown_client_hostname,
reject_unauth_destination
check_policy_service는 가급적 뒤쪽(내 서버로 보내도 되는 사람인지
1차 필터링이 끝난 뒤)에 두는 게 일반적입니다. 너무 앞에 두면 SPF 조회
때문에 정상 발송자도 지연될 수 있습니다.
(빠졌던 부분) policyd-spf 자체 설정 파일 확인 #
기본 설정 파일은 보통 /etc/postfix-policyd-spf-python/policyd-spf.conf에
있습니다. 대부분 기본값으로 충분하지만, 문제가 생겼을 때 로그를 자세히 보고
싶으면 이 파일에서 debugLevel을 올려볼 수 있습니다 (0~4, 기본은 1).
sudo nano /etc/postfix-policyd-spf-python/policyd-spf.conf
debugLevel = 2
재시작 #
sudo systemctl restart postfix
확인 방법 #
외부에서 메일을 하나 보내달라고 한 뒤, 헤더를 열어보면
Received-SPF: Pass (...) 같은 줄이 붙어있어야 정상 동작하는 것입니다.
또는 실시간으로 로그를 보면서 확인할 수 있습니다:
sudo tail -f /var/log/mail.log | grep -i spf
3단계: DMARC 검증 추가하기 #
설치 #
sudo apt install opendmarc
opendmarc.conf 설정 #
sudo nano /etc/opendmarc.conf
원본 질문에는 소켓 줄만 있었는데, 실제로 동작하려면 최소한 아래 항목들이 채워져 있어야 합니다 (빠져 있으면 추가하세요):
AuthservID mail.snsoz.com
TrustedAuthservIDs mail.snsoz.com
Socket local:/run/opendmarc/opendmarc.sock
RejectFailures false
Syslog true
SyslogFacility mail
UMask 0002
각 항목이 뭘 하는지:
- AuthservID: 결과를 표시할 때 어떤 이름으로 표시할지(보통 자기 메일서버 도메인).
- TrustedAuthservIDs: 위 값과 보통 동일하게 맞춥니다.
- Socket: opendkim처럼 Postfix와 통신할 통로(유닉스 소켓) 경로.
- RejectFailures:
true로 하면 DMARC 검증에 실패한 메일을 바로 거부합니다. 처음 켤 때는 오탐(정상 메일이 걸리는 것)이 있을 수 있으니false로 시작해서 로그만 쌓다가, 며칠 지켜보고 문제없으면true로 바꾸는 걸 권장합니다. - Syslog / SyslogFacility: 검증 결과를
/var/log/mail.log에 남길지 여부.
(빠졌던 부분) 소켓 권한 문제 미리 막기 #
opendmarc는 opendmarc라는 전용 계정으로 실행되는데, Postfix는 postfix
계정으로 실행됩니다. 이 둘이 같은 소켓 파일을 주고받으려면 권한을 맞춰줘야
합니다. 이 단계를 빼먹으면 “Milter가 응답하지 않는다"거나 메일이 아예
지연/거부되는 문제가 흔히 발생합니다.
sudo gpasswd -a postfix opendmarc
opendkim을 처음 설정할 때도 같은 이유로 sudo gpasswd -a postfix opendkim을
했었다면, 이미 익숙한 절차일 겁니다.
서비스 활성화 #
sudo systemctl enable --now opendmarc
sudo systemctl status opendmarc
active (running)으로 뜨는지 확인하세요.
Postfix에 연결하기 #
sudo nano /etc/postfix/main.cf
기존:
smtpd_milters = unix:opendkim/opendkim.sock
수정 (opendmarc 추가):
smtpd_milters =
unix:opendkim/opendkim.sock,
unix:/run/opendmarc/opendmarc.sock
non_smtpd_milters =
unix:opendkim/opendkim.sock,
unix:/run/opendmarc/opendmarc.sock
한 줄로 써도 됩니다:
smtpd_milters = unix:opendkim/opendkim.sock,unix:/run/opendmarc/opendmarc.sock
non_smtpd_milters = unix:opendkim/opendkim.sock,unix:/run/opendmarc/opendmarc.sock
주의(빠졌던 부분): 경로 표기가 서로 다릅니다. opendkim 소켓은
unix:opendkim/opendkim.sock처럼 앞에/가 없는 상대경로이고, opendmarc는unix:/run/opendmarc/opendmarc.sock처럼/로 시작하는 절대경로입니다. 우분투 기본 Postfix 패키지는 chroot가 꺼져 있어서(둘 다) 대부분 문제없이 동작하지만, 만약 milter 연결이 안 되는 문제가 생기면 아래 명령으로 chroot 설정부터 확인해보세요.postconf -Mf | grep smtp
smtp inet n - n - - smtpd처럼 다섯 번째 칸이n이면 chroot가 꺼진 정상 상태입니다. 혹시y로 돼 있다면 opendkim처럼 상대경로로 통일하거나,/etc/postfix/master.cf에서 chroot 칸을n으로 바꿔주세요.
또한, milter 서비스가 죽었을 때 메일이 전부 막히는 걸 원치 않는다면
아래 옵션도 함께 확인해두면 안전합니다 (기본값이 tempfail이라
milter가 안 살아있으면 메일이 전부 지연됩니다):
milter_default_action = accept
단, accept로 하면 milter가 죽었을 때 검증 없이 그냥 통과시킨다는
뜻이니, “검증이 원래 목적"이라면 오히려 tempfail(기본값) 그대로 두고
opendkim/opendmarc 서비스 자체가 죽지 않게 모니터링하는 쪽을 권장합니다.
재시작 #
sudo systemctl restart postfix
4단계: 실제로 잘 되는지 확인하기 #
설정만 하고 끝내지 말고, 꼭 실제 메일로 확인하세요.
방법 1: 받은 메일 헤더 직접 보기 #
Gmail 기준: 메일 열기 → 우측 상단 점 3개 → “원본 보기”. 헤더에서
Authentication-Results: 줄을 찾으면 아래처럼 보입니다.
Authentication-Results: mail.snsoz.com;
dkim=pass header.d=example.com;
spf=pass smtp.mailfrom=example.com;
dmarc=pass header.from=example.com
셋 다 pass면 정상 동작하는 것입니다.
방법 2: 로그로 실시간 확인 #
sudo tail -f /var/log/mail.log | egrep -i "dkim|spf|dmarc"
이 상태로 외부 메일 계정에서 테스트 메일을 하나 보내면서 로그가 어떻게 찍히는지 보면 어디서 걸리는지 바로 알 수 있습니다.
방법 3: mail-tester.com #
이건 원래 송신 품질을 보는 도구라 수신 검증 자체를 알려주진 않지만, DNS의 SPF/DMARC 레코드 문법이 맞는지 교차 확인하는 용도로는 여전히 유용합니다.
자주 걸리는 문제 정리 #
| 증상 | 원인/확인 |
|---|---|
DKIM Mode를 sv로 바꿨는데도 검증 결과가 헤더에 안 보임 |
smtpd_milters에 opendkim 소켓이 실제로 등록돼 있는지 postconf -n | grep milter로 확인 |
SPF policyd 설치했는데 헤더에 Received-SPF가 안 붙음 |
master.cf의 policyd-spf 항목 들여쓰기 확인, check_policy_service 줄이 smtpd_recipient_restrictions에 실제로 들어갔는지 재확인 |
| opendmarc 재시작 후 메일이 전부 지연/거부됨 | 소켓 권한 문제일 가능성 높음 → sudo gpasswd -a postfix opendmarc 후 postfix, opendmarc 둘 다 재시작 |
systemctl status opendmarc가 바로 죽음(failed) |
/etc/opendmarc.conf 문법 오류 가능성 → journalctl -u opendmarc -n 50으로 에러 메시지 확인 |
| DMARC는 pass인데 실제 스팸이 계속 들어옴 | DMARC는 “From 헤더 도메인"만 검증합니다. 발신자가 아예 다른 도메인을 쓰는 일반 스팸은 DMARC로 못 거른다는 점을 기억하세요(SPF/DKIM/DMARC는 ‘도메인 위조’를 막는 것이지 스팸 전체를 막는 필터가 아닙니다) |
요약 #
grep Mode /etc/opendkim.conf→sv가 아니면 고치고 opendkim 재시작postfix-policyd-spf-python설치 + master.cf/main.cf 연결 + postfix 재시작opendmarc설치 + 소켓 권한(gpasswd) + main.cf milters 연결 + postfix 재시작- 실제 메일 헤더의
Authentication-Results에서 세 개 다pass뜨는지 확인
이 네 단계만 순서대로 밟으면 “내가 보낸 메일 검사"뿐 아니라 “내가 받는 메일 검사"까지 갖춘 완전한 메일서버가 됩니다.