TECH 으로 돌아가기
TECH HACKER NEWS 오늘 6분 읽기 34 READS

메일이 자꾸 스팸함으로 가나요? SPF 레코드 문법 완전 정복

이메일 인증의 첫 관문, SPF가 뭐길래

회사에서 이메일 발송 기능을 만들어본 적 있으신가요? 코드는 분명히 잘 동작하는데 메일이 자꾸 스팸함으로 들어가거나 아예 반송되는 경험, 한 번쯤 해보셨을 거예요. 이메일 세계에는 "이 메일이 진짜 그 도메인에서 보낸 게 맞나?"를 확인하는 인증 장치들이 있는데요, 그중 가장 기본이 되는 게 바로 SPF(Sender Policy Framework)거든요.

SPF가 뭐냐면, 쉽게 말해 "우리 도메인 이름으로 메일을 보내도 되는 서버 목록"을 DNS에 공개해두는 거예요. 메일을 받는 쪽(Gmail, 네이버 메일 같은 수신 서버)이 실제 발신 서버의 IP 주소와 이 목록을 대조해서, 목록에 없는 서버가 보낸 메일이면 "사칭이네?" 하고 걸러내는 방식이죠. 스팸 발송자가 남의 도메인을 도용하는 걸 막는 1차 방어선인 셈이에요.

레코드 한 줄을 뜯어보면

SPF 레코드는 DNS의 TXT 레코드에 딱 한 줄로 들어가요. 실제로는 이렇게 생겼어요.

v=spf1 ip4:203.0.113.0/24 include:_spf.google.com -all

이 한 줄이 세 가지 부품으로 이뤄져 있는데요. 첫째가 메커니즘(mechanism)이에요. "어떤 서버를 허용할지"를 지정하는 부분으로, ip4/ip6는 IP 주소를 직접 적는 거고, amx는 도메인의 A 레코드나 MX 레코드에 등록된 서버를 허용한다는 뜻이에요. 제일 많이 쓰는 include는 "다른 도메인의 SPF 목록을 통째로 가져와서 검사해라"는 의미인데, 구글 워크스페이스나 SendGrid 같은 외부 서비스로 메일을 보낼 때 이걸 써요. 마지막의 all은 "위에서 아무것도 안 걸린 나머지 전부"를 뜻하고요.

둘째가 한정자(qualifier)예요. 각 메커니즘 앞에 붙는 기호인데, +는 통과(기본값이라 보통 생략), -는 명확한 실패, ~는 소프트 실패, ?는 중립이에요. 그래서 맨 끝의 -all은 "목록에 없으면 무조건 거부해라", ~all은 "거부까진 아니어도 의심스럽게 봐라"라는 뉘앙스 차이가 있어요. 도입 초기엔 ~all로 시작해서 우리 회사의 발송 경로를 전부 파악한 뒤에 -all로 조여가는 게 정석이거든요.

셋째가 수정자(modifier)인데요, redirect=는 SPF 평가 자체를 다른 도메인으로 통째로 넘기는 거고, exp=는 인증 실패 시 보여줄 설명 메시지를 지정해요. 여기에 더해 %{i}(발신 IP), %{s}(발신자 주소) 같은 매크로 문법도 있어서, exists 메커니즘과 조합하면 발신 IP마다 동적으로 DNS 조회를 해서 판정하는 고급 구성도 가능해요. 허용 IP 목록이 너무 길어진 대형 메일 서비스들이 쓰는 기법이에요.

가장 많이 밟는 지뢰: DNS 조회 10회 제한

SPF에는 함정이 하나 있어요. 검사 과정에서 DNS 조회를 유발하는 메커니즘(include, a, mx, exists, redirect)이 합쳐서 10회를 넘으면 permerror로 그냥 실패 처리되거든요. 문제는 include가 중첩된다는 거예요. 구글 워크스페이스 넣고, 마케팅 툴 넣고, 헬프데스크 툴 넣고… 하다 보면 각 서비스가 내부적으로 또 include를 몇 개씩 물고 있어서 어느새 10회를 훌쩍 넘겨요. 멀쩡히 잘 가던 메일이 어느 날 갑자기 스팸 처리되기 시작했다면 십중팔구 이 문제예요.

SPF 하나로는 부족해요

SPF는 메일 봉투에 적힌 발신 주소만 검사하기 때문에, 메일이 다른 서버를 거쳐 포워딩되면 인증이 깨지는 약점이 있어요. 그래서 메일 본문에 암호학적 서명을 붙이는 DKIM, 그리고 두 결과를 종합해서 정책을 정하는 DMARC와 세트로 써야 해요. 특히 Gmail과 Yahoo는 2024년부터 대량 발송자에게 이 세 가지를 사실상 의무화했기 때문에, 가입 메일이나 알림 메일을 보내는 서비스라면 이제 선택이 아니라 필수가 됐어요.

마무리

터미널에서 dig txt 회사도메인.com 한 번 쳐보는 것부터 시작해보세요. 지금 우리 도메인의 SPF가 어떻게 생겼는지, include 체인이 10회 제한에 얼마나 가까운지 확인하는 것만으로도 큰 수확이거든요. 여러분 회사의 SPF 레코드는 -all로 끝나나요, 아직 ~all인가요? 운영하면서 겪은 메일 전송 실패 사례가 있다면 댓글로 공유해주세요.


🔗 출처: Hacker News

SOURCE · HACKER NEWS
원문 전체 보기 → https://dmarcguard.io/blog/spf-record-syntax/
SHARE
처리 중...