1. 왜 지금 다시 이메일 인증인가

몇 년 전까지만 해도 SPF/DKIM/DMARC는 "메일 잘 가게 하려면 박아두는 DNS 레코드" 정도였다. 한 번 설정하고 잊는 영역. 그런데 2024년 초 Google과 Yahoo가 대량 발송자(하루 5천 통 이상)에게 DMARC 구성을 사실상 의무화하면서 상황이 바뀌었다. 이제 인증은 "안 하면 메일이 안 가는" 전제 조건이 됐다. 원문(Fastmail)에서는 이걸 웹의 HTTPS가 걸어온 길에 비유한다. 모범 사례 → 기대사항 → 인프라. 자물쇠 없는 사이트가 경고로 취급되듯, 인증 없는 메일도 점점 그렇게 돼간다.

여기에 한 겹 더 얹힌 게 AI다. 원문이 짚는 핵심은 이거다. 예전엔 사람이 의심스러운 메일을 직접 읽으며 "도메인에 글자 하나 더 붙었네", "긴급하다는 말투가 어색하네" 같은 신호를 잡아냈다. 그런데 받은편지함을 요약하고, 할 일을 뽑아내고, 답장 초안을 쓰고, 경우에 따라 사용자를 대신해 행동까지 하는 AI 어시스턴트가 표준 기능이 되면 그 휴리스틱이 사라진다. AI는 내용과 긴급성을 읽고 그대로 실행해버린다. 그래서 설득력 있는 스푸핑 메일은 받은편지함에 도달하기 전에 인증으로 막아야 한다는 게 글의 논지다.

솔직히 말하면 원문은 Fastmail의 포지셔닝성 글이라 "그래서 뭘 발표한다는 거냐"는 댓글 반응이 많았다. 나도 동의한다. 다만 인프라 엔지니어 입장에서 보면 인증 체계 자체는 여전히 우리가 직접 설정하고 운영하고 트러블슈팅해야 하는 실무 영역이고, AI 필터가 인증 결과를 핵심 입력값으로 쓰기 시작했다는 맥락은 충분히 시의성이 있다. 그 지점만 떼어내서 실무 관점으로 풀어보자.

2. SPF·DKIM·DMARC 동작 원리 — 세 개가 어떻게 맞물리나

이 셋은 따로 노는 표준이 아니라 체인으로 물려 있다. 비유하자면 이렇다.

  • SPF: "이 봉투를 부친 우체국이 우리 회사 지정 우체국이 맞나?" — 발송 서버의 권한 검증
  • DKIM: "봉투 안 편지에 우리 회사 봉인 도장이 찍혀 있고, 운송 중에 뜯긴 흔적이 없나?" — 메시지의 무결성 + 서명 검증
  • DMARC: "SPF랑 DKIM 둘 중 하나라도 통과했고, 그게 From 도메인이랑 일치하나? 실패하면 어떻게 처리할까?" — 정책 결합 + 실패 시 처리 방침

SPF — 어느 서버가 보낼 권한이 있는가

도메인의 TXT 레코드에 발송 권한이 있는 서버 목록을 적어둔다. 수신 서버는 메일을 받을 때 실제 접속해온 IP가 이 목록에 있는지 본다.

$ dig +short TXT example.com
"v=spf1 include:_spf.google.com include:sendgrid.net ~all"

여기서 ~all(SoftFail)이냐 -all(HardFail)이냐가 운영 정책의 핵심이다. ~all은 "목록에 없는 서버에서 와도 일단 통과는 시키되 의심해", -all은 "목록에 없으면 거부해". 처음 도입할 땐 ~all로 시작하는 게 안전하다.

SPF의 가장 큰 함정은 DNS 조회 10회 제한이다. include가 중첩되면서 조회 횟수가 10을 넘으면 SPF 평가 자체가 permerror로 떨어진다. SaaS 메일 서비스 서너 개만 물려도 금방 초과한다. 이건 뒤 함정 섹션에서 에러까지 같이 본다.

DKIM — 메시지에 서명을 붙인다

발송 서버가 개인키로 메일 헤더+본문 일부에 서명을 만들어 DKIM-Signature 헤더에 넣는다. 공개키는 DNS에 올려둔다. 수신 서버는 그 공개키로 서명을 검증해서 전송 중 변조가 없었는지 확인한다.

$ dig +short TXT selector1._domainkey.example.com
"v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC..."

여기서 selector1 부분이 셀렉터(selector)다. 한 도메인이 여러 발송 서비스를 쓸 때 셀렉터로 키를 구분한다. Google은 google, SendGrid는 s1/s2 같은 식으로 자기들 셀렉터를 쓴다. 메일 원본 헤더의 DKIM-Signature에서 s= 값을 보면 어떤 셀렉터를 조회해야 하는지 나온다.

DMARC — 둘을 묶고, 실패 시 행동을 지시한다

DMARC가 추가하는 핵심 개념이 alignment(정렬)다. 단순히 SPF/DKIM이 통과했다고 끝이 아니라, 그 통과한 도메인이 사용자에게 보이는 From: 도메인과 일치해야 한다. 이게 스푸핑 방어의 진짜 핵심이다.

$ dig +short TXT _dmarc.example.com
"v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com; adkim=s; aspf=r; pct=100"

읽어보면 이렇다.

  • p=quarantine: 실패한 메일은 격리(스팸함). 정책은 none(관찰만) → quarantinereject 순으로 강화한다.
  • rua=mailto:: 집계 리포트(aggregate report)를 받을 주소. 이게 4번 섹션의 핵심이다.
  • adkim=s: DKIM 정렬을 strict로. r(relaxed)이면 서브도메인까지 허용한다.
  • pct=100: 정책을 적용할 메일 비율. 롤아웃 초기엔 pct=10처럼 낮춰서 점진 적용한다.

3. 실무 관점 — 트레이드오프와 흔한 함정

흔한 함정 1: SPF DNS 조회 10회 초과 (permerror)

실무에서 제일 자주 만나는 사고다. 마케팅팀이 새 메일 SaaS를 붙여달라고 해서 include를 하나 더 추가했더니, 어느 날부터 갑자기 정상 메일까지 SPF가 깨지기 시작한다. 원인은 조회 횟수 초과. DMARC 리포트나 메일 헤더의 Authentication-Results에 이런 식으로 찍힌다.

Authentication-Results: mx.google.com;
       spf=permerror (google.com: permanent error in processing during
       lookup of user@example.com: DNS error) smtp.mailfrom=example.com

permerror는 "SPF 레코드 자체가 RFC 위반 상태라 평가 불가"라는 뜻이다. ~all이든 -all이든 평가가 무의미해진다. 해결은 (1) 안 쓰는 include 정리, (2) SPF flattening(include를 실제 IP 대역으로 펼쳐 조회 횟수를 줄임) 정도다. flattening은 SaaS 쪽 IP가 바뀌면 깨지므로 자동 갱신 도구 없이 손으로 하면 나중에 폭탄이 된다. 트레이드오프가 분명하니 도입 전 팀 내 합의가 필요하다.

흔한 함정 2: 포워딩이 SPF를 깨뜨린다

메일링 리스트나 .forward로 메일을 전달하면 발송 IP가 중간 서버로 바뀐다. 그러면 원래 도메인의 SPF에는 그 중간 서버 IP가 없으니 SPF가 실패한다. 이래서 DMARC는 SPF 또는 DKIM 둘 중 하나만 정렬+통과해도 PASS로 친다. DKIM 서명은 본문이 안 바뀌면 포워딩돼도 살아남기 때문이다. 그런데 메일링 리스트가 본문에 footer를 붙이거나 제목에 [list]를 끼워넣으면 DKIM 서명까지 깨진다. 원문이 언급한 ARC(Authenticated Received Chain) 실험이 바로 이 "복잡한 전달 경로에서 인증을 어떻게 이어붙일까" 문제를 다루려던 거다. 다만 원문 댓글에서도 ARC가 완전한 해법은 아니라는 지적이 나온다.

흔한 함정 3: DMARC를 처음부터 p=reject로 박는다

의욕 넘쳐서 처음부터 p=reject로 가면 거의 100% 사고난다. 사내에 미처 파악 못 한 발송 경로(레거시 배치 서버, 사내 모니터링 알림, 협력사가 대신 보내는 메일)가 한두 개는 꼭 있고, 그게 다 거부당해서 "왜 우리 알림 메일이 안 와요" 티켓이 폭주한다. 반드시 p=none으로 시작해 리포트로 발송원을 다 파악한 뒤 단계적으로 올려야 한다.

대안/한계 — 인증은 신원이지 의도가 아니다

원문이 솔직하게 인정하는 한계이자, 댓글에서 제일 날카롭게 파고든 지점이다. SPF/DKIM/DMARC는 "이 메일이 진짜 그 도메인에서 왔는가"는 검증하지만 "그 내용이 사기인가"는 검증하지 못한다. 댓글에 나온 실제 공격 시나리오가 인상적이다. 공격자가 PayPal·Stripe 같은 진짜 결제 플랫폼이 메일을 발송하게 만든 뒤, 회사명 필드에 "문제 발생, 이 번호로 전화하세요"를 넣는다. 그러면 진짜 PayPal에서 나가는, 모든 인증을 통과하는 정상 메일에 그 문구가 박힌다. DMARC로는 절대 못 잡는다. 인증은 사칭의 비용과 복잡성을 높일 뿐, 만능이 아니라는 걸 분명히 알고 가야 한다.

4. DMARC 리포트로 위협 모니터링하기

rua로 받는 집계 리포트는 압축된 XML이다. 메일 수신자(Google, Microsoft 등)가 "당신 도메인을 From으로 쓴 메일을 이런 IP에서 이만큼 봤고 인증 결과는 이랬다"를 하루 단위로 보내준다. 사람이 XML 원본을 읽긴 힘들어서 보통 파서나 SaaS(예: dmarcian, Postmark 무료 분석 등)를 쓴다. 구조는 대략 이렇게 생겼다.

<record>
  <row>
    <source_ip>203.0.113.55</source_ip>
    <count>128</count>
    <policy_evaluated>
      <disposition>none</disposition>
      <dkim>fail</dkim>
      <spf>fail</spf>
    </policy_evaluated>
  </row>
  <identifiers>
    <header_from>example.com</header_from>
  </identifiers>
</record>

이 record를 보면 모르는 IP 203.0.113.55가 우리 도메인을 From으로 128통이나 보냈는데 SPF/DKIM 둘 다 fail이다. 두 가지 가능성이다. (1) 우리가 깜빡한 정상 발송 경로 → SPF/DKIM에 추가해줘야 한다. (2) 진짜 스푸핑 시도 → 정책을 강화하면 이 IP의 메일은 막힌다. 리포트를 안 보면 이 구분이 안 된다. 그래서 p=none 관찰 기간이 중요한 거다.

로컬에서 빠르게 까보고 싶으면 받은 첨부(gzip)를 이렇게 풀어볼 수 있다.

$ gunzip -c example.com\!google.com\!1700000000.xml.gz | \
    grep -E "source_ip|dkim|spf|disposition"
      <source_ip>209.85.220.41</source_ip>
      <dkim>pass</dkim>
      <spf>pass</spf>
      <disposition>none</disposition>

이런 식으로 IP별 pass/fail만 빠르게 훑고, 의심스러운 IP는 따로 조사하면 된다. 양이 많아지면 결국 파서를 붙이게 되지만, 처음 감 잡을 땐 이걸로 충분하다.

5. AI 필터·어시스턴트 환경에서 인증 실패가 미치는 영향

원문의 논점을 인프라 관점으로 다시 정리하면 이렇다. 과거에 인증 실패는 "스팸함에 들어갈 확률이 좀 올라간다" 정도의 약한 신호였다. 그런데 두 가지가 동시에 바뀌고 있다.

  1. AI 필터가 인증 결과를 점점 더 핵심 입력값으로 쓴다. 인증이 깨진 도메인은 발송원 평판과 묶여 더 강하게 페널티를 받는다. 즉, 우리 회사 메일의 DKIM 셀렉터 키를 실수로 안 올렸다거나 SPF가 permerror면, 단순히 "일부 차단"이 아니라 도메인 평판 자체가 깎이는 방향으로 작동할 수 있다.
  2. AI 어시스턴트는 인증을 통과한 메일의 내용을 그대로 신뢰하고 행동(요약, 일정 등록, 답장 초안)한다. 사람이라면 걸렀을 미묘한 사칭을 그대로 실행할 위험이 있다.

결국 인프라 담당자 입장에서 시사점은 명확하다. 인증은 "메일 잘 가게 하는 옵션"이 아니라 "우리 도메인 평판을 지키는 기본 위생"이 됐다. 그리고 원문이 언급한 BIMI(검증된 발신자가 받은편지함에 자기 로고를 표시하는 표준)는 DMARC를 p=quarantine 이상으로 강화한 도메인만 쓸 수 있다. AI 생성 피싱이 내용만으로 구분하기 어려워진 시점에, 시각적 신뢰 신호를 얻으려면 인증 체계가 단단해야 한다는 뜻이다. 다만 BIMI는 VMC(검증된 마크 인증서) 비용 등 도입 장벽이 있어서, 조직 규모와 필요에 따라 판단할 영역이다(공식 요구사항은 각 메일 사업자 문서 확인 필요).

6. 정리 — 누가 언제 어떻게

한 줄 요약: SPF/DKIM/DMARC는 이제 선택이 아니라 도메인 평판과 메일 도달성의 전제 조건이고, AI가 메일을 자율 처리할수록 "내용은 못 막아도 발송원 사칭의 비용은 올린다"는 가치가 커진다. 단, 인증은 신원 검증이지 의도 검증이 아니라는 한계를 알고 써야 한다.

프로덕션 점진 롤아웃 체크리스트:

  1. 현재 발송 경로 전수 조사 (사내 배치, 알림 서버, 협력사 대행 발송까지)
  2. SPF 레코드 정리 — include 조회 횟수 10회 이내 확인, 처음엔 ~all
  3. 모든 발송 서비스에 DKIM 셀렉터 설정 + DNS 공개키 확인
  4. DMARC를 p=none으로 배포하고 rua 리포트 수집 시작
  5. 1~2주 리포트 분석 → 누락된 정상 발송원을 SPF/DKIM에 추가
  6. pct를 낮춰가며 p=quarantinep=reject로 단계 강화
  7. 필요 시 BIMI 검토 (DMARC 강화 정책 선행 필요)

이건 누구에게나 필요하다. 대량 발송하는 서비스라면 Google/Yahoo 정책 때문에 이미 필수다. 사내 전용 도메인이라도 우리 도메인을 사칭한 피싱이 협력사·고객에게 날아가는 걸 막으려면 최소 p=quarantine은 가는 게 맞다. 다만 처음부터 p=reject로 박지 말고, 리포트로 발송원을 다 파악한 뒤 단계적으로. 그 인내심이 티켓 폭주와 평온한 금요일을 가른다.

참고 자료

728x90

안녕하세요 여러분~ 이번에는 라즈베리파이와 도메인을 이용해서 나만의 메일버서를 구축해보려고 합니다.

 

구축전에 준비물은, 라즈베리파이,자신이 등록한 도메인,DDNS와 포트포워딩을 지원하는 공유기,입니다.

(저는 RPI3에 Raspbian, 도메인은 mast3r.com, 공유기는 IPtime A3004NS로 진행합니다)

생각보다 준비물이 많네요...;;;

 

포스팅은 총 4단계로 나누어서 진행하구요, 이 글애는 메일서버구축을 위한 사전준비를 포스팅 하려고 합니다.

최대한 쉽게 따라오실 수 있게 노력했으니 도움이 됐으면 좋겠습니다.!

 

자 이제, 시작해보겠습니다.

공유기에 라즈베리파이를 물리고 전원을 켜줍니다.

켜준 뒤 첫번째로 세팅할 곳은 공유기입니다.

제일 처음 공유기에 로그인을 해주시고(보통 192.168.0.1로 접속하시면 됩니다)

고급설정 -> 네트워크 관리 -> 내부 네트워크 설정에 들어갑니다.

들어가시면 현재 라즈베리파이가 잘 연결되어 있으며 할당되어 있는 IP는 192.168.0.6인걸 확인 할 수 있습니다.

 

다음으로는 포트포워딩 설정입니다.

고급 설정 -> NAT/라우터 관리 -> 포트포워드 설정에 들어갑니다.

안에 들어가시면 위 사진과같이 설정이 되어있어야 합니다.

설정 하는 방법은 간단한데 밑에 보이는 규칙이름에 임의의 이름을 넣고 내부 IP주소,

곧 아까 확인한 192.168.0.6를 입력하면 됩니다.

그리고 외부포트와 내부포트는 각각 사진의 있는 값을 따라서 적으시면 됩니다.

 

2번의 ssh2룰은 외부에서 내부로 도메인을 사용해 ssh로 접속할때 쓰기위한 룰입니다

3번룰은 2단계에서 Letsencrypt를 사용해서 인증서를 만들때 웹서버 인증이 필요하기 때문에 필요한 룰입니다.

4,5번룰은 SMTP에서 사용하는 포트를 포워딩 해주는 룰입니다.

6~9번까지의 룰은 IMAP/POP3에서 사용하는 포트들을 포워딩 해주는 룰입니다.

 

포워딩을 마친 뒤에 고급 설정 -> 특수기능 -> DDNS설정이라고 써진 메뉴를 들어갑니다.

이 페이지 붉은색으로 네모쳐진 곳에 두가지 값을 입력해야하는데, 호스트 이름은 DDNS의 이름을 입력하는 칸이고

사용자 ID는 사용하시는 이메일 주소를 넣으시면 됩니다.

호스트이름에 넣으시는 이름이 곧 외부에서 내부로 접속할때 사용되는 DDNS이름이 됩니다!

2칸을 모두 채워주시고 생성버튼을 누르면 위 사진과 같이 DDNS가 등록되게 됩니다.

이렇게 따라와 주셨으면 공유기 설정은 모두 마쳤습니다!

 


이제 도메인을 세팅할 차례입니다.

저는 hosting.kr에서 도메인을 구입했습니다. 

hosting.kr의 서브도메인 설정화면은 위 사진과 같으며, 총 3개의 서브도메인이 보이지만... 

www도메인은 제 웹서버 도메인이므로..생략해도 됩니다 ㅋㅋ

 

최상위 도메인(아무것도 없는 도메인)에는 A레코드로 아까 만든 DDNS에 대한 IP,

(cmd에서 ping [ddns 주소]하면 실제 IP를 확인할 수 있습니다.) 

mail서브도메인에서는 CNAME으로 아까 생성했던 DDNS 주소를 입력하고 적용합니다.

여기까지 오셨으면 도메인 세팅도 끝났습니다!.


이제 라즈베리파이를 세팅할 차례입니다.

저는 putty를 사용하여 제 rpi에 접속하였습니다. 접속시 실제 도메인을 사용하여 로그인하였습니다. Host Name에는 도메인이름을 Port에는 아까 공유기에서 포트포워딩해준 포트 60001번을 넣고 Open을 눌러 접속합니다.

그리고 pi/raspberry로 로그인을 합니다. (이 계정과 비번은 기본 세팅이니 꼮 변경해주시기 바랍니다!!!!변경필쑤!!)

로그인을 한 뒤 아래 명령어를 입력 해 루트계정으로 작업을 실행합니다(매번 sudo를 치기 귀찮기 때문이죠...후훗)

sudo su

참고로 현재 상태에서는 root계정에 대해 비밀번호가 걸려있지 않기 때문에 반드시 비밀번호를 설정해주시기 바랍니다!!! 제발요.. 꼭 해주세요...

root계정으로 접근한 뒤, 아래의 명령어를 입력하여 시스템을 최신버전으로 업데이트 해줍니다.

apt update; apt upgrade -y

이 단계는 옵션입니다. 저는 개인적으로 VIM을 선호하기때문에 라즈베리파이에 설치해 줍니다.

apt install vim 

 

다음으로는 host이름을 변경합니다.

vim /etc/hostname
#이 명령어로 hostname 파일을 열고

dd
#raspberrypi 를 지워줍니다

i
#입력모드로 전환합니다. 

mast3r.com
#자신의 도메인주소를 적어줍니다

esc
#esc버튼을 눌러 입력모드를 나갑니다

:wq
#위 명령을 입력하여 저장 후 닫습니다.

다음은 /etc/hosts파일을 변경해야합니다.

 

위에서 했던 것 처럼 값을 변경/입력해줍니다. 변경할 값은 127.0.1.1 을 도메인 이름으로 변경하고 새 줄에는 DDNS대한 IP주소를 삽입 후 도메인을 입력하면 됩니다! (제 IP는 가렸습니다. 소중하니까요..ㅋㅋ어차피 ping때리면 나오는데.. 왜가렸을까)

어쨋든! 이렇게 하시면 기본설정은 끝났습니다.

이제 실제 이메일에 사용될 계정을 만들어보도록 하겠습니다.

 

이렇게 간단할 수가....

useradd linux
usermod -G mail linux
usermod -s /usr/sbin/nologin linux
passwd linux

이 4문장만 입력하시면 나중에 실제로 사용될 이메일 계정이 만들어지는 겁니다.

vim /etc/passwd
vim /etc/group

계정을 만든 뒤에 위의 파일을 열어서 실제로 계정이 추가됐는지 확인할 수 있습니다.

 마지막으로

chown :mail /home
chmod 775 /home

 /home의 그룹을 mail로 변경하고 775권한을 주는 이유는 postfix에서 Maildir형식으로 메일 디렉토리를 구성할 것이기 때문입니다.(즉 이메일 계정이 생성될 때 마다 /home/[user]/Maildir이 생성됩니다)

모든 명령을 마친 이후에 

reboot

리부팅을 해주면 모든 사전준비가 끝나게 됩니다.

따라오시느라 고생하셨습니다! 두번째 글에서는 Postfix설치 및 설정, letsencrypt를 이용한 SSL/TLS 설정을 포스팅 하도록하겠습니다.

728x90

+ Recent posts