Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

Contents

SPF

SPF(Sender Policy Framework)는 스팸 메일의 발송을 방지하기 위해서 사용하는 전자 메일 인증 방법이다. 메일은 도메인 이름을 사용하는데, 해당 도메인에서 허용하는 IP 주소목록을 등록한다.

foo@example.com을 예로 들어보면, 메일 서버 도메인은 example.com 인데, 메일 서버의 주소인 1.1.1.1, 1.1.1.2을 SPF에 등록을 한다. 스팸발송자가 자신의 메일서버를(2.2.2.2라고 하자.) 이용 example.com 도메인을 위조해서 메일을 보내면, 수신 메일 서버는 example.com 에 대한 SPF를 도메인서버에 요청한다. 2.2.2.2는 SPF 목록에 없으므로, 스팸메일로 분류해서 반송처리 한다.

SPF는 DNS의 TXT 레코드로 관리한다. DNS 관리자는 SPF 목록을 DNS TXT 레코드에 등록하면 된다.

SPF 작동방식을 그림으로 묘사했다.

 SPF

SPF 등록

SPF는 DNS의 TXT 레코드에 등록한다. 등록포멧은 아래와 같다.
"v=spf1 ip4:213.165.64.0/23 -all"
  • spf1 : spf 버전 1을 사용한다.
  • ip4 : ip4 주소를 사용한다.
  • -all : 해당 도메인에 대해서 213.164.64.0/23 발송 메일을 pass 하고 나머지는 fail
AWS Route 53으로 테스트를 해보자. joinc.io. 도메인을 하나 만들었다.
# aws route53 list-hosted-zones
{
    "HostedZones": [
        {
            "ResourceRecordSetCount": 4, 
            "CallerReference": "B21543AF-6XXXXXXXXXXXXXXX", 
            "Config": {
                "PrivateZone": false
            }, 
            "Id": "/hostedzone/Z3XXXXXXXXXXXX", 
            "Name": "joinc.io."
        }
    ]
}

아래와 같이 SPF 레코드를 추가했다.

  1. TYPE : SPF를 선택
  2. Value : SPF 레코드를 추가
추가후 레코드 상태를 확인했다.
# aws route53 list-resource-record-sets --hosted-zone-id /hostedzone/Z3XXXXXXXXXXXX
{
    "ResourceRecordSets": [
        {
            "ResourceRecords": [
                {
                    "Value": "ns-1505.awsdns-60.org."
                }
            ], 
            "Type": "NS", 
            "Name": "joinc.io.", 
            "TTL": 172800
        }, 
        {
            "ResourceRecords": [
                {
                    "Value": "\"v=spf1 ip4:213.165.64.0/23 -all\""
                }
            ], 
            "Type": "SPF", 
            "Name": "joinc.io.", 
            "TTL": 300
        }
    ]
}
(일부 내용만 출력했다.)SPF 레코드가 추가된 걸 확인 할 수 있다.

Linux dig 명령을 이용해서 확인해보자.
# dig @205.251.197.225 joinc.io SPF

; <<>> DiG 9.11.5-P1-1ubuntu2.5-Ubuntu <<>> @205.251.197.225 joinc.io SPF
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 17811
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 4, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;joinc.io.			IN	SPF

;; ANSWER SECTION:
joinc.io.		300	IN	SPF	"v=spf1 ip4:213.165.64.0/23 -all"

;; AUTHORITY SECTION:
joinc.io.		172800	IN	NS	ns-1505.awsdns-60.org.
joinc.io.		172800	IN	NS	ns-2015.awsdns-59.co.uk.
joinc.io.		172800	IN	NS	ns-496.awsdns-62.com.
joinc.io.		172800	IN	NS	ns-567.awsdns-06.net.

;; Query time: 173 msec
;; SERVER: 205.251.197.225#53(205.251.197.225)
;; WHEN: 금  8월 09 14:24:34 KST 2019
;; MSG SIZE  rcvd: 221
joinc.io 에 대한 SPF 가 보인다. 메일 수신 서버는 도메인이 joinc.io일 경우(ex. yundream@joinc.io, foo@joinc.io) 213.165.64.0/23 에서 발송한 메일만 수신한다.

AWS SES 에서 SPF 레코드 설정

나는 SES를 이용해서 joinc.io 도메인으로 메일을 전송하는 시스템을 만들계획이다. 메일이 제대로 도착하게 하려면 SPF 설정을 해야 한다. 아래와 같이 SPF 레코드를 추가하면 된다.
"v=spf1 include:amazonses.com ~all"

joinc.io는 이미 spf 레코드가 존재하므로 아래와 같이 수정했다.
"v=spf1 ip4:213.165.64.0/23 include:amazonses.com -all"

SPF 판정 값

SPF 처리가 완료되면 Received-SPF 헤더에 처리 결과가 기록된다. Gmail에서 수신한 메일에 대한 원본 보기로 이 헤더를 볼 수 있다. 내용의 일부분이다.
...... 생략
Return-Path: <798-HZF-887.0.16576.0.0.4291.9.17425918@em-sj-77.mktomail.com>
Received: from em-sj-02.mktomail.com (em-sj-02.mktomail.com. [199.15.214.202])
        by mx.google.com with ESMTPS id a3si42359434pfb.171.2019.08.05.17.16.26
        for <yundream@gmail.com>
        (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
        Mon, 05 Aug 2019 17:16:26 -0700 (PDT)
Received-SPF: pass (google.com: domain of 798-hzf-887.0.16576.0.0.4291.9.17425918@em-sj-77.mktomail.com designates 199.15.214.202 as permitted sender) client-ip=199.15.214.202;
...... 생략 

본문......
pass 상태임을 알 수 있다.

참고