網域認證鑰匙(DomainKeys)是Yahoo!反垃圾信小組所研發的獨家技術,反垃圾信技術發展的一大突破。能有效地判斷寄件者的網域(Domain)是否是偽造的以及寄出信件是不是來自於偽造的網域。一旦網域經過認證,網域認證鑰匙馬上再去比對信件裡的寄件者是否符合這個網域。一旦發現不符合,這封信很有可能是垃圾信或詐騙信,那麼網域認證鑰匙就在第一時間過濾掉這種信。
寄件主機為Email Sign Domainkey有兩個步驟 :
Set up:網域管理者為Domainkeys的運作,先行產生兩組Key ( publickey / privatekey)。public key存於DNS Server中,即右圖中的步驟 "A"。而privatekey存於Sending Mail Server中。
Signing:當End-user經過認證允許寄信後,DomainKey-enabled email system(dk-filter)會根據privatekey而自動產生一組數位簽章,並將數位簽章寫進欲寄出信件的mail header,再傳送到Receiving Mail Server。即右圖寄信流程中的步驟 "B"。
接收郵件主機 Verify Signed Mail 有三個步驟
Preparing: DomainKey-enabled receiving mail server取出signature及From: domain,並利用From: Domain由DNS 取回public key。即右圖寄信流程中的步驟 “C"。
Verifying:Verify 由From: Domain取回的publickey和由privatekey產生的signature是否符合。 若不符則可能為偽造他人網域寄出的信件。
Deliverying:通過Verify的信件則依policy正常寄送進User Mailbox,未通過Verify的信件則被丟棄/註記或保存下來。即右圖寄信流程中的步驟 “D"。
接下來為 DKIM 實作 ( OS : Fedora Core 5 )
要實作DKIM,需要的套件如下:
- sendmail V8.13.0 or later
- openssl
- dk-milter-0.6.0
(1)首先確認 sendmail 版本及是否支援MILTER?
# sendmail -d0 </dev/null
Version 8.13.8
Compiled with: DNSMAP HESIOD HES_GETMAILHOST LDAPMAP LOGMAP_REGEX MATCHGECOS MILTER MIME7TO8 MIME8TO7 NAMED_BIND NETINET NETINET6 NETUNIX NEWDB NIS PIPELINING SASLv2 SCANF SOCKETMAP STARTTLS TCPWRAPPERS USERDB USE_LDAP_INIT
如果上列不含MILTER , 則需安裝 “sendmail-devel”
安裝 MILTER 的目的是要讓 sendmail 可以加載其他的 Mail Filter ,
而dk-filter也是一種 Mail Filter
(2)Install dk-milter
2.1 download source in http://sourceforge.net/projects/domainkeys/
2.2 Unpack the tarball
2.3 Change to the release directory (dk-milter-<version>)
2.4 # cp devtools/Site/site.config.m4.sample devtools/Site/site.config.m4
2.5 edit devtools/Site/site.config.m4
define(`bld_USE_ARLIB', `true')
APPENDDEF(`conf_libar_ENVDEF', `-DAR_RES_MANUAL')
APPENDDEF(`confINCDIRS', `-I/usr/include/openssl -I/usr/include')
APPENDDEF(`confLIBDIRS', `-L/usr/lib/openssl -L/usr/lib -L/lib')
APPENDDEF(`confENVDEF', `- D_FFR_ANTICIPATE_SENDMAIL_MUNGE ')
APPENDDEF(`bld_dk_filter_INCDIRS', `-I/usr/include/libmilter')
APPENDDEF(`bld_dk_filter_LIBDIRS', `-L/usr/lib')
2.6 # sh Build
2.7 # sh Build install
(3) 解釋一下 dk-filter 的參數
dk-filter: usage: dk-filter -p socketfile [options]
socketfile example => inet:8891@localhost
-a peerlist file containing list of hosts to ignore
-A auto-restart
-b modes select operating modes ( s : sign / v : verify , 預設 sv)
-c canon canonicalization to use when signing ( 預設 : simple )
-C config configuration info
* Result : badsignature(bad) , dnserror(dns) , internal(int) , nosignature(no) ,
signature-missing(miss)
* Actions : accept(a) , discard(d) , tempfail(t) , reject(r)
-d domlist domains to sign ( 你要 signed 的 @domain )
-D also sign subdomains
-f don't fork-and-exit
-h append identifying header
-H sign with explicit header lists
-i ilist file containing list of internal (signing) hosts
-I elist file containing list of external domain clients
-l log activity to system log
-m mtalist MTA daemon names for which to sign (此項沒有預設值,務必要設對)
(DaemonPortOptions=Name in sendmail.cf)
-M macrolist MTA macros which enable signing
-o hdrlist list of headers to omit from signing
-P pidfile file to which to write pid
-R generate verification failure reports
-s keyfile location of secret key file (指定 private key 位置)
-S selector selector to use when signing (指定 selector)
-u userid change to specified userid
-V print version number and terminate
(4)設定 Sendmail
4.1. Add a line like this example to your sendmail.mc using your desired socket specification:
INPUT_MAIL_FILTER(`dk-filter', `S=inet:8891@localhost')
4.2. Rebuild sendmail.cf in your way
m4 sendmail.mc > sendmail.cf
(5)產生 Public Key / Private key
5.1. 選擇你的 selector named : 我的 selector name => mail
5.2. create public / private key
dk-filter 提供 script : gentxt.csh 來產生 public key 及 private key
script 所在 : dk-milter-0.6.0/dk-filter/gentxt.csh
使用方法 : gentxt.csh selector domain
# gentxt.csh mail gogo.net.tw
=> 執行後會帶出該設在 DNS TXT的dns record (如下) 並產生 mail.public / mail.private
mail._domainkey IN TXT "g=; k=rsa; t=y; p="xxxxxxxxxxxxxx"
=> 設定上面的 DNS TXT Record , 使之生效
=> 將private key ( mail.private )置於你想要存放的路徑下
我存放在 : /var/db/domainkeys/mail.private
=> 查詢 DNS TXT Record , 看是否生效
$ dig +short txt mail._domainkey.gogo.net.tw
"g=\; k=rsa\; t=y\; p=xxxxxxxxxxxxxxx"
(6)Start dk-filter
# /usr/bin/dk-filter -H -l -p inet:8891@localhost -c simple
-d gogo.net.tw -b s
-s /var/db/domainkeys/mail.private -S mail -m MTA
上面的設定表示dk-filter只替 From Domain: gogo.net.tw signed , 而非這個 domain 要透過此Server寄信 , 則不會 Signed
(7)Restart sendmail
# /etc/init.d/sendmail restart
(8)測試寄信
from : samson@gogo.net.tw to : samsonyhj@yahoo.com.tw
DomainKey-Signature : 此header是由寄信主機 Signed
Authentication-Results : domainkeys=pass(ok) : 此為接收主機設上 ,表示驗證通過
寄件者 : 比對通過後於頁面顯示"網域認證鑰匙確認這信件寄出自Domain"