Ubuntu Postfix Mail Server 設定筆記 (一) MTA (SPF, DKIM, rDNS 及 DMARC)

本系列第一篇: 設定 MTA (Mail Transfer Agent)
先讓郵件成功向外發送吧!

互聯網出現以先, Email Server 設定本來就很簡單,
甚至各大 ISP 都有提供免費 Open Relay,讓公眾任意傳送郵件。

但隨著垃圾郵件的猖獗,釣魚郵件的犯罪活動,一切已變得不一樣。
Open Relay再不存在,每封郵件都需要經過重重把關才能送到收信者的 Inbox。
否則會被扔到 Spam Folder 甚至直接拒收。

用過 SMTP 的應該都知道 “From” Address 是可以隨便冒認的。
如果銀行等的 Email Address 被冒認來發釣魚網站連結後果就嚴重了!
SPF 和 DKIM 的出現是要解決這保安漏洞。

本篇首先設定好 MTA 外送郵件的設定。

本系列設定環境:Ubuntu 12.04
(為免被 Spam bot 找到,本系列的出現的 Domain 都是假的)

Updated 2017-04-26: 更新了文章格式,經測試 Ubuntu 16.04 可用

1. 首先當然要安裝 Postfix

apt-get install postfix mailutils

Postfix 設定網上已很多,在此不多詳述。詳情參見: http://linux.vbird.org/linux_server/0380mail.php

mailutils 提供 mail 等工具方便後面測試

2. 設定 Mailname 及 Hostname

此步驟很重要,否則 SPF 和 DKIM 都會因為 hostname 不符而 Fail

修改 /etc/mailname,設定為要使用的 FQDN

修改 /etc/postfix/main.cf ,設定 myhostname 為要使用的 FQDN

myhostname = domain.com

(經測試前者會影響 “From” Address, Return-Path, 後者只影響 “Received” header,
還是兩個改成一樣比較方便)

3. 設定 DKIM (DomainKeys Identified Mail)

DKIM 的原理是用公私鑰驗證 Sender 的真偽。
Public Key 放在 DNS TXT Record,而 Private Key 存放在 Server,而每封 Email 帶有 DKIM-Signature。
這樣只要驗證 DKIM-Signature 是否和 Public key 相符就可以知道郵件的真偽。

安裝 OpenDKIM 及 OpenDKIM Tools

apt-get install opendkim opendkim-tools

修改 /etc/default/opendkim, Listen 本地 8891 Port

SOCKET="inet:8891@localhost"

以下有兩種作法,建議直接做 Multi Domain 免除麻煩


如果有多於一個Domain要DKIM簽名:
(DKIM signing multiple domain names)

為每個新增Domain Name新增一個Directory

mkdir -p /etc/opendkim/keys/domain1.com
mkdir -p /etc/opendkim/keys/domain2.com

為每個 Domain 生成 Public key 及 Private key

cd /etc/opendkim/keys/domain1.com/
opendkim-genkey -t -s mail -d domain1.com

cd /etc/opendkim/keys/domain2.com/ 
opendkim-genkey -t -s mail -d domain2.com

照樣把各 mail.txt 的內容各自加入到 DNS Zone 或 把引號 ” 內加入到Delegated DNS Server

Name: mail._domainkey

Value: v=DKIM1; k=rsa; t=y; p=MIG...QAB

不要忘記修改 Permission 讓 opendkim 讀取 keys

chown -R opendkim:opendkim /etc/opendkim

修改 /etc/opendkim.conf, 新增以下設定

# Key table
KeyTable           /etc/opendkim/KeyTable
SigningTable       /etc/opendkim/SigningTable

建立 /etc/opendkim/KeyTable, 新增以下設定

mail._domainkey.domain1.com domain1.com:mail:/etc/opendkim/keys/domain1.com/mail.private
mail._domainkey.domain2.com domain2.com:mail:/etc/opendkim/keys/domain2.com/mail.private

建立 /etc/opendkim/SigningTable, 新增以下設定

domain1.com mail._domainkey.domain1.com
domain2.com mail._domainkey.domain2.com


如果只有一個 Domain 需要DKIM簽名:
(DKIM signing single domain name)

生成 Public key 及 Private key

opendkim-genkey -t -s mail -d domain.com

當前目錄會出現 mail.privatemail.txt, 前者是 Private Key, 後者是 DNS TXT Record

把  mail.txt 的內容加入到 DNS Zone 或 把引號 ” 內加入到Delegated DNS Server
然後把 Private key 複製到 Postfix directory

cp mail.private /etc/postfix/dkim.key

修改 /etc/opendkim.conf, Domain 設成自己的FQDN

Domain                  domain.com
KeyFile                 /etc/postfix/dkim.key
Selector                mail


修改 /etc/postfix/main.cf 指示 Postfix 使用 DKIM Sign Outgoing mail

# DKIM
milter_default_action = accept
milter_protocol = 6
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891

Start OpenDKIM 及 Restart Postfix

service opendkim start
service postfix restart

DKIM 設定完成,之後再設定完 SPF 再一併測試

參見:DKIM with Postfix – https://rtcamp.com/tutorials/mail/dkim-postfix-ubuntu/

4. 設定 SPF (Sender Policy Framework)

SPF 其實也只是一種 TXT 紀錄,用途是讓某 Domain 授權特定 IP Address 代表其發信。
收件伺服器收到郵件後,會驗證該地址 Domain 的 SPF 紀錄是否跟 Sender Address 相符。

新增一個與收信 (Sub)domain 相乎的 TXT Record

v=spf1 ip4:54.249.120.50 ~all

v=spf1 a ~all

v=spf1 指定協議版本,不能改變

ip4:54.249.120.50 允許 54.249.120.50 代表 domain2.com 發信
可以設定為 CIDR 格式,例如 54.249.120.0/24

a 允許 A Record 和 AAAA Record 中的 IP Address 發信

~all 代表 除非乎合以上條件,否則 Return “SoftFail”
日後測試完成,需要更強保安可以改為 -all ,即 Return “HardFail”
這樣冒認的電郵就較可能被拒收

陷阱: SPF 所在的 (Sub)Domain 不能有其他 CNAME Record

其實 CNAME Record 並不能和其他任何 Record 共存,很奇怪這在多數 DNS Service 是合法的

If a CNAME RR is present at a node, no other data should be present; this ensures that the data for a canonical name and its aliases cannot be different.

RFC1034 section 3.6.2

順帶一提,其實 MX Record 也不能指向 CNAME Record

The domain name used as the value of a NS resource record, or part of the value of a MX resource record must not be an alias.

RFC 2181 section 10.3

SPF Record Syntax: http://www.openspf.org/SPF_Record_Syntax
SPF Record Generator: http://www.spfwizard.net/

5. 設定 DNS 反解 (Reverse DNS)

rDNS 需要 Hosting / ISP 的配合,或許需要收費。
我用的是 Amazon EC2,這服務是免費的,只需要簡單申請。

(EC2 有郵件發送限制,此表格可以順道解除它)

Request to Remove Email Sending Limitations – https://portal.aws.amazon.com/gp/aws/html-forms-controller/contactus/ec2-email-limit-rdns-request

5. DMARC (Domain-based Message Authentication, Reporting & Conformance) 設定

這應該是最少人認識的設定吧?我是查看 Paypal 發來的郵件的 Header 發現的。
用途大約是讓收件的 MTA 知道發現 SPF 或 DKIM 不符的疑似假冒郵件時該怎樣做,以及控制驗證的嚴格程度。
而且還可以建議 MTA 通知真正的 Domain owner。
所以 DMARC 必需先設定好 SPF 和 DKIM 才能使用。

這是 2013 年才定下的標準,相關文檔不多。但 Google 有一個 相當好的說明
DMARC 的設定相當簡單,只要新增一個 TXT Record 就好了。

這個階段暫時設定為不隔離或拒絕郵件好了。

在 _dmarc.domain1.com 新增 TXT 紀錄:

v=DMARC1; p=none; rua=mailto:[email protected]

6. 測試設定

直接用 Command Line 發送測試 Email,把 test.txt 當作郵件內文

mail -s "This is a Mail Test" [email protected] < test.txt

成功在 Gmail 收到此 Email,Gmail 驗證過 DKIM 和 SPF 都 Pass 了

Delivered-To: [email protected]
Received: by 10.221.37.72 with SMTP id td8csp28135vcb;
        Thu, 20 Feb 2014 00:18:40 -0800 (PST)
X-Received: by 10.68.189.100 with SMTP id gh4mr506307pbc.21.1392884320460;
        Thu, 20 Feb 2014 00:18:40 -0800 (PST)
Return-Path: <[email protected]>
Received: from domain1.com (ec2-54-249-120-50.ap-northeast-1.compute.amazonaws.com. [54.249.120.50])
        by mx.google.com with ESMTP id io5si3105660pbc.354.2014.02.20.00.18.39
        for <[email protected]>;
        Thu, 20 Feb 2014 00:18:40 -0800 (PST)
Received-SPF: pass (google.com: domain of [email protected] designates 54.249.120.50 as permitted sender) client-ip=54.249.120.50;
Authentication-Results: mx.google.com;
       spf=pass (google.com: domain of [email protected] designates 54.249.120.50 as permitted sender) [email protected];
       dkim=pass (test mode) [email protected];
       dmarc=pass (p=NONE dis=NONE) header.from=domain1.com
Received: by domain1.com (Postfix, from userid 0)
	id 060BF63CDF; Thu, 20 Feb 2014 16:18:39 +0800 (HKT)
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple;
	d=domain1.com; s=mail; t=1392884319;
	bh=fdkeB/A0FkbVP2k4J4pNPoeWH6vqBm9+b0C3OY87Cw8=;
	h=Subject:To:Date:From:From;
	b=XY4mJGjLFK8fUwBoi9SjzEAIeAf2WZjnuQgnu6wcWT6DUyYvPYh1WW0MtS0equveO
	 CluW2mxlVK2xTnw2oOC9akt2/yIbcwm4QqcsAvosrl8JoH5HdbxzUG07z3xW/3S+oe
	 VRq9hZk0XZi02aiLb1XTYo5Xu8UyvHw6GpRy8poY=
Subject: Mail Test
To: <[email protected]>
X-Mailer: mail (GNU Mailutils 2.2)
Message-Id: <[email protected]>
Date: Thu, 20 Feb 2014 16:18:39 +0800 (HKT)
From: [email protected] (root)

Test

另外也可以用 http://www.mail-tester.com/ 測試,進入後會有一個臨時電郵地址,
發送任意郵件到該地址,即可取得一個很可愛的詳細 Report。

 mail -s "Mail Test" [email protected] < test.txt

DKIM 及 SPF 都正確設定的話,應該得到不錯的分數,以及一個鳥語花香的畫面。

Spam Test Result by mail-tester.com - Mozilla Firefox_2014-02-18_14-44-33

Result: http://www.mail-tester.com/web-401S8T

否則就會出現一個很悲涼的畫面:

Spam Test Result by mail-tester.com - Mozilla Firefox_2014-02-18_14-46-52

Postfix MTA 外送的設定部分到這裡結束了。
下一篇開始談談 MDA 與 MSA 的連接。

28 Replies to “Ubuntu Postfix Mail Server 設定筆記 (一) MTA (SPF, DKIM, rDNS 及 DMARC)”

  1. 較少的既全面並以中文書寫的教學!

    筆者有考慮過使用類似Sendgrid 這類SMTP SaaS 的服務嗎?

    1. 謝謝您的閱讀
      其實我是特別用中文寫的 因為英文的教學網上已太多了

      我有考慮過 Amazon SES
      但因為我這個項目還在概念測試階段
      所以才想自己架一台伺服器 先全權控制所有東西 確定需要甚麼功能以後再修改

  2. 忘記了答謝你詳盡的教學,實在獲益良多,請繼續這類型的分享!
    就是看完你的文章後,最後決定使用MailChimp 的Mandrill SMTP service作基本的transactional mail 功用

    1. 這個扣分項目, 應該是因為郵件的內容導致的
      可能您的內容郵件太像 Pyzor 上被檢舉的內容了

  3. 想請教大大一個問題
    SPF, DKIM, rDNS 及 DMARC都已經設定完畢
    http://www.mail-tester.com/ 測試結果也都是ok
    但不論是寄給gmail yahoo hotmail
    都會便當成垃圾信
    直接被丟到垃圾信箱去
    這有可能是那邊疏忽了嗎?
    煩請大大不吝指導 十分感謝

  4. 説实在的日本好多东西和礼仪都是从中国学习来的传说中国人是它们的祖先,不管怎样人家传承下来了如巜日本京都》那里的大多数建筑都是在咱们唐朝畤期学习唐代的风格建造的还有日本的和服都是从中国古代時侯学习来的,
    宜宾市秀江园林有限公司 http://www.ybxjyL.com

  5. 为什么中国航母还没建成,别人都在我家门口耀武扬威了,还无动于衷中国人难道再受百年屈辱吗,中国人没有长远眼光吗,难道政府只知道贪污腐败养小蜜吗,让我作为中国人尔感到屈辱。
    黄陂网站建设 http://www.Hpwzjs.cn

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.