一. 基礎(chǔ)篇
SMTP表示發(fā)件服務器莲趣,POP3(或IMAP)表示收件服務器,這些名詞就不贅述了饱溢,相信大家早已耳熟能詳喧伞。下面是一個電子郵件在網(wǎng)上簡單的交互的流程:
- 發(fā)件人:me@qq.com 收件人:you@gmail.com
- me@qq.com 用郵件客戶端(比如outlook)寫了一封郵件給you@gmail.com,點下發(fā)送按鈕后绩郎,郵件首先會發(fā)送到smtp.qq.com
- smtp.qq.com 檢索到這封郵件的收件人域名是gmail.com潘鲫,于是通過互聯(lián)網(wǎng)(WAN)將郵件發(fā)送到smtp.gmail.com
- smtp.gmail.com確認收下郵件后,將它轉(zhuǎn)存到郵件服務器的硬盤中待收肋杖。
觀察以上流程溉仑,你會發(fā)現(xiàn)smtp服務器其實身兼了 “收、發(fā)” 兩個功能状植,在整個流程中浊竟, 對于smtp.qq.com而言,是發(fā)送津畸。 而從smtp.gmail.com的角度來看振定,則是接收。那么肉拓,咱們平時經(jīng)常說起的 “收件服務器pop3” 又是怎么回事呢后频,整個流程似乎看不到它的身影?
pop3(或imap服務器暖途,與之性質(zhì)相同)更多的是起一個中轉(zhuǎn)作用卑惜,它將存儲在郵件服務器硬盤中的郵件搬運回郵件客戶端(user agent),換句話說它只負責從郵件服務器到郵件客戶端這段路徑驻售,而郵件在廣域網(wǎng)上的傳遞與它沒有關(guān)系露久。
如圖:
- SPF和DKIM又是干什么用的呢?
為了防偽欺栗,用來檢查一封電郵是否來自其所聲稱的發(fā)送者抱环。
回想一下在紙質(zhì)郵件時代,我們是怎么寫信的纸巷,
首先镇草,信紙 和 信封是不同的兩個東西,里面都包含有發(fā)件人和收件人信息瘤旨,請注意梯啤,實際上出現(xiàn)了兩個發(fā)件人,一是信封上的那個發(fā)件人存哲,另一個是信紙里落款時那個發(fā)件人因宇,兩者一般來說是一致的七婴。但也有可能不一樣,過去并沒有太好的防偽措施察滑,但通過簽名來判斷發(fā)件人身份也不失為一個方法打厘。
電子郵件也有類似的 “信封” 和 “信紙” 的概念,但電子郵件的 “信封” 對于普通用戶通常是不可見的贺辰。那么問題來了户盯,比如我收到一封email,其信封上的發(fā)件人是某詐騙網(wǎng)站badguy.com饲化,但是這封郵件自己聲稱(信紙上寫的)來自qq.com莽鸭,因為我看不到信封,我就會誤認為這封郵件真的是騰訊(qq.com)發(fā)給我的吃靠。
那么硫眨,怎么知道對方的身份是否真的就是他“聲稱”的那個呢?對不起巢块,還真沒辦法礁阁!過去在紙質(zhì)郵件時代最低限度大家還可以瞧瞧簽名是不是假的,電子郵件并沒有簽名這一說族奢,因此氮兵,防偽手段非但沒有進步,反而是更不堪了歹鱼。
為了遏制電子郵件欺詐泣栈,于是人們就想出了SPF和DKIM。
其根本目的是為了解決 “我真的是我” 這個問題弥姻。
基本原理:
SPF:通過存放在DNS服務器內(nèi)的IP來驗證電子郵件的真實來源南片。
例如example.com對應ip: 111.222.233.244,則一切發(fā)件人冠以example.com的郵件庭敦,必須是以111.222.233.244這臺服務器發(fā)出的才是真實的疼进,如果不是這個ip,則是假冒的秧廉。
DKIM:同樣通過DNS服務器來實現(xiàn)伞广,通過一對公私鑰來驗證電子郵件的真實來源。
例如example.com有一對非對稱加密的公私鑰證書疼电,公鑰已經(jīng)公布在DNS里了嚼锄,任何人都能獲取,同時example.com還根據(jù)自身持有的私鑰加密了一小段信息藏在郵件頭里蔽豺,
當該郵件發(fā)送到目標SMTP服務器的時候区丑,首先對方會在DNS服務器里找到example.com的公鑰,然后再用這把公鑰試圖去解密郵件頭里夾帶的那一小段內(nèi)容,如果解密成功沧侥,說明這封郵件確實是從example.com發(fā)過來的可霎,如果解密失敗,則說明是偽造的宴杀,如此一來癣朗,想要冒充example.com作為發(fā)件人則只剩下兩個途徑:
- 篡改放在DNS服務器里的公鑰
- 想辦法搞到example.com的私鑰
很顯然,挑戰(zhàn)以上任何一項都絕非易事旺罢,郵件欺詐者很難再像過去一樣旷余,通過盜用發(fā)件人姓名、改變附件屬性等小伎倆達到目的了主经。
如果你對所謂的非對稱加密荣暮、公鑰庭惜、私鑰這些知識還不太理解罩驻,建議先讀一下這篇文章:https://zhuanlan.zhihu.com/p/42516761 [ 對稱加密和非對稱的加密 的優(yōu)缺點和理解 ]
二.實戰(zhàn)篇 (默認你已經(jīng)裝好了postfix)
特別提示:以下所有內(nèi)容凡是出現(xiàn)example.com的地方,必須修改為你自己的域名
1.設(shè)置spf
登錄example.com的DNS管理界面护赊,添加一條TXT記錄惠遏,
host填:@
value填:v=spf1 mx ~all
@表示針對所有外域訪問者
v=spf1表示這是一個SPF記錄,并且SPF記錄的版本是SPF1
mx ~all 表示只有從本IP發(fā)出去的郵件才是這個域名下發(fā)出的真實郵件骏啰,~all表示沒有例外
- 設(shè)置完畢后节吮,回到本地系統(tǒng)。
- 輸入:
dig example.com txt
[ 驗證spf信息是否正確寫入了DNS ]
spf設(shè)置完畢判耕,即當外域smtp服務器收到example.com這個域名的郵件時透绩,會先到公眾dns服務器去查驗example.com所對應的IP地址,如果發(fā)現(xiàn)跟DNS里存儲的IP不一致壁熄,則說明是冒牌貨帚豪。
此外,example.com本身作為一臺smtp服務器時草丧,當收到外域郵件的時候狸臣,也需要具備這個功能,比如說當我們收到來自gmail.com的郵件時昌执,我們也要先去DNS上查一下gmial.com所對應的ip烛亦,看看是不是冒充的。
- 首先安裝所需的軟件包:
dnf install pypolicyd-spf -y
dnf install epel-release -y
- 添加用戶:policyd-spf :
adduser policyd-spf --user-group --no-create-home -s /bin/false
- 編輯postfix的master設(shè)置文件懂拾,在文件末尾添加以下幾行煤禽,告訴Postfix在啟動SPF策略守護程序時自行啟動。 Policyd-spf將以policyd-spf用戶身份運行:
nano /etc/postfix/master.cf
#修改為:
policyd-spf unix - n n - 0 spawn
user=policyd-spf argv=/usr/libexec/postfix/policyd-spf
- 修改postfix的main設(shè)置文件岖赋,在文件末尾添加以下幾行呜师。 第一行指定Postfix策略代理超時設(shè)置(用于查詢DNS)。 以下幾行將通過檢查SPF記錄來限制傳入電子郵件贾节。
nano /etc/postfix/main.cf
#修改為:
policyd-spf_time_limit = 3600
smtpd_recipient_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_unauth_destination,
check_policy_service unix:private/policyd-spf
- 重啟postfix:
systemctl restart postfix
2.設(shè)置DKIM
- 安裝OpenDKIM
yum install opendkim -y
systemctl start opendkim
systemctl enable opendkim
- 修改配置文件:
nano /etc/opendkim.conf
#修改以下這幾個內(nèi)容:
Mode sv
SendReports yes
KeyFile /etc/opendkim/keys/example.com/12345678.private
KeyTable /etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
InternalHosts refile:/etc/opendkim/TrustedHosts
- 創(chuàng)建簽名表
nano /etc/opendkim/SigningTable
#在此文件的末尾添加以下行:
*@example.com 12345678._domainkey.example.com
這相當于告訴OpenDKIM汁汗,如果您服務器上的發(fā)件人正在使用@example.com地址衷畦,則應使用12345678._domainkey.example.com標識的私鑰對其進行加密。
因為一個域名可以具有多個DKIM密鑰知牌,所以需要添加前綴以區(qū)分祈争,在這里12345678沒有什么特殊含義,是隨便想出來的一個標識角寸,這個標識你可以隨意設(shè)定菩混,但一定要注意前后一致,后面有多個地方會遇到它扁藕。
- 創(chuàng)建密鑰表
nano /etc/opendkim/KeyTable
#添加以下內(nèi)容:
12345678._domainkey.example.com
example.com:12345678:/etc/opendkim/keys/example.com/12345678.private
- 創(chuàng)建可信任主機列表
nano /etc/opendkim/TrustedHosts
#默認情況下沮峡,此文件中包含127.0.0.0.1和:: 1。 現(xiàn)在添加以下行:
*.example.com
告訴OpenDKIM亿柑,如果電子郵件來自example.com本域,則不執(zhí)行DKIM驗證疟游。
- 創(chuàng)建密鑰對(公鑰和私鑰)
#創(chuàng)建一個存放鑰匙的單獨目錄:
mkdir /etc/opendkim/keys/example.com
#創(chuàng)建兩把密鑰:
opendkim-genkey -b 2048 -d example.com -D /etc/opendkim/keys/example.com -s 12345678 -v
上面的命令將創(chuàng)建兩把2048位密鑰另绩。 -d(域)指定域。 -D(目錄)指定將存儲密鑰的目錄干签。 并使用12345678作為前綴, 執(zhí)行命令后竭贩,私鑰將被寫入12345678.private文件,公鑰將被寫入12345678.txt文件。公鑰創(chuàng)建完畢之后,需要手工在DNS中發(fā)布稚茅,私鑰則用于加密郵件頭绘面,請務必保管好峭竣。
- 修改權(quán)限扣墩,讓用戶opendkim能夠訪問此文件:
chown opendkim:opendkim /etc/opendkim/keys/ -R
chmod 0600 /etc/opendkim/keys
- 發(fā)布公鑰
- 在example.com的DNS管理界面中,創(chuàng)建一條TXT記錄,
host填:12345678._domainkey
那么value填什么呢濒持?這比較麻煩柑营,請按照以下操作一步一步來:
第1步:返回到本地ssh窗口奶赔,
第2步:執(zhí)行cat命令查看公鑰:
cat /etc/opendkim/keys/example.com/12345678.txt
第3步:復制括號中的所有內(nèi)容(注意:需要刪除值字段中的所有雙引號和換行符)然后回到dns管理界面瘸彤,將內(nèi)容粘貼到value中。以下是一個參考文本:
v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu+7VSgwCUwpAIV+L5Nq3pwRqFV80ylncWpW7pgVUtCylj8lPUsdSV1RLfWn5Zd6afYHqHDFwyVvA66hijqyTQYjbmnZQOXPqkBdxhOt9KEfDh610rtMbwSltH4pl5brlsD9DuBBbvWzklFR676e5lhZFsG+oSnHxUzhflVrF3TUXRM3jrNT/V/EyF6DCxJAJX0Ear9snjC0AXftSNPofbl1IvHBUeU8bSZuYpDdZqHT9Wnxo0Cm3YXoNVEcvFrLS7D0PbYwjJ5xYeuqyZSRpQh1P9tQK4BKPatCimFbmULVIlG9+neH76dqbJmx/0Qa0Q5eMSPvdie2OhLT/+NBEowIDAQAB
- 驗證私鑰和公鑰是否對得上
重啟opendkim讓設(shè)置生效:
systemctl restart opendkim
執(zhí)行:
opendkim-testkey -d example.com -s 12345678 -vvv
- 如果返回:opendkim-testkey: key OK 表示成功笛钝!
DNS更新并不是實時的质况,從幾分鐘到幾小時,這和你設(shè)置的TTL有關(guān)玻靡,如果暫時顯示“keys do not match”也不用急结榄,可以等等再試試。
- 現(xiàn)在囤捻,針對目標SMTP服務器的DKIM設(shè)置工作已經(jīng)完成了臼朗,接下來,讓咱們自己的SMTP也具備這個功能:
nano /etc/postfix/main.cf
#在此文件的末尾添加以下行蝎土,
#以便Postfix能夠通過milter協(xié)議調(diào)用OpenDKIM视哑。
#請注意,您應該使用127.0.0.1作為地址誊涯, 不要使用localhost挡毅。
# Milter configuration
milter_default_action = accept
milter_protocol = 6
smtpd_milters = inet:127.0.0.1:8891
non_smtpd_milters = $smtpd_milters
保存并關(guān)閉文件。 然后將postfix用戶添加到opendkim組暴构。
gpasswd -a postfix opendkim
systemctl restart postfix [ 重啟postfix ]
三. DMARC
- 關(guān)于 DMARC跪呈, 它相當于spf和dkim的整合,以報告的形式向管理員匯報郵件服務器的防偽情況取逾,匯報周期是可以更改的耗绿。 DMARC并不是必備的,但是添加了它之后您的郵件服務器 “尊重度” 將會提高砾隅。
具體的操作如下:
- 添加DNS TXT記錄
host填:_dmarc
value填:v=DMARC1; p=none; pct=100; fo=1; rua=mailto:dmarck-reports@example.com
dmarck-reports@example.com 這個就是郵件管理者的郵件地址误阻,即郵件報告的接收者,此賬號必須是一個可用的電子郵件賬號晴埂。
- 檢查DMARC是否生效
方法1:
dig txt +short _dmarc.littledot.net
如果回顯:"v=DMARC1; p=none; pct=100; fo=1; rua=mailto:dmarck-reports@littledot.net" 表示成功究反!
方法2:
yum install opendmarc -y
opendmarc-check littledot.net
四. 郵件服務器的 “受尊重度”
由于前些年垃圾郵件泛濫成災,大的郵件服務商都有對應的反垃圾郵件機制邑时,一些上了黑名單的服務器直接會被他們將郵件放到用戶的垃圾箱中奴紧。你肯定不希望自己的郵件進入這個黑名單吧,當然如果我們的郵件服務器是正常使用的話晶丘,倒也不至于此黍氮,一般來說一個全新的郵件服務器是不會進入黑名單的唐含。但這并不能保證你就是一個值得信任的郵件服務器,因此郵件服務器的 “受尊重度” 這個概念就產(chǎn)生了沫浆。
由于各大郵件服務商(gmail捷枯、yahoo、 網(wǎng)易专执、騰訊等等)的具體策略外人并不得而知淮捆,到底他們會將你的郵件怎么處理,所以也沒有一個準數(shù)本股。但從總體來說攀痊,國內(nèi)的幾家郵件商還是比較寬松的,基本上設(shè)好了spf和dkim拄显,都能做到通行無阻苟径。最困難的應該算是gmail了,即使 spf+dkim+dmarc 這些都設(shè)好了躬审,也不一定型棘街。它還有一些比較奇特的參考策略,比如說這個域名綁定ip的時長承边,或者這個域名有沒有對應www網(wǎng)站等等遭殉,煩不勝煩。
最后博助,這個網(wǎng)站 https://www.mail-tester.com/ 可以測試你的郵件服務器尊重度得分险污,并且會對不足之處做出專業(yè)性建議,根據(jù)其生成的報告逐步完善吧翔始。