2009年4月14日 星期二

FreeBSD設定SASL for Sendmail

最近想要開放Mobile User可以使用SMTP AUTH的機制來寄信, 所以四處研究了一下, 發覺要做的設定很少, 筆記如下:

1. 在FreeBSD 7.0, 使用ports安裝sendmail-sasl

2. 修改/usr/local/etc/rc.d/saslauthd
將saslauthd改名成saslauthd.sh(或複製)
# cp /usr/local/etc/rc.d/saslauthd /usr/local/etc/rc.d/saslauthd.sh
# vi /usr/local/etc/rc.d/saslauthd.sh
找到 saslauthd_enable=${saslauthd_enable:-"NO"} 這一行, 將"NO"改成"YES"
這時候要決定使用使用什麼方法來驗證使用者:
a. 使用這台FreeBSD的帳號密碼, 那麼現有的設定就可以了
b. 使用另一台主機的帳號密碼, 那麼要將下一行 saslauthd_flags=${saslauthd_flags:-"-a pam"}做一點修改(下一段再談)

3. 調整Sendmail的設定檔, 預設就有幾個驗證機制可以使用(DIGEST-MD5, CRAM-MD5), 但是因為現有Client端軟體, 如Outlook, 只支援LOGIN等驗證機制, 所以Sendmail要調整一下:
a. 增加驗證機制 define(`confAUTH_MECHANISMS',`CRAM-MD5 DIGEST-MD5 LOGIN PLAIN')
b. 設定若通過驗證, 則代轉信(relay) TRUST_AUTH_MECH(`CRAM-MD5 DIGEST-MD5 LOGIN PLAIN')
# cd /usr/local/share/sendmail/cf/cf
# vi sendmail.mc
如上所提, 加入那兩行
# ./Build sendmail.cf
# ./Build install-cf

4. 重開Sendmail, 就可以了
# cd /usr/local/etc/rc.d
# ./sendmail.sh restart

------------------------------------
以上為設定步驟, 下面我們討論相關的問題:

1. SASL與驗證機制
SASL支援的驗證技術很多, 包括KERBEROS_V4, GSSAPI, S/KEY, EXTERNAL, ANONYMOUS, PLAIN, LOGIN, CRAM-MD5, DIGEST-MD5。其中KERBEROS_V4, GSSAPI(Kerberos 5)需要另外設定其服務, 而CRAM-MD5, DIGEST-MD5只要SASL裝好就可以使用了, 不用另外再安裝設定; 而且其強度很好(強驗證, 即安全性高, 不會被攔截密碼), 所以有很多文章都會討論這兩個協定的用法。而LOGIN, PLAIN因為是明文傳送密碼, 大都不建議使用, 可偏偏許多國人常用的Client軟體, 如Outlook, Outlook Express等只支援這些明文傳送協定, 所以一般我們還是要打開它。

在我們使用ports安裝sendmail-sasl後, 其實就已經裝好SASL了, 可以驗證如下:
# /usr/local/sbin/sendmail -bt -d0.1
Version 8.14.3
Compiled with: DNSMAP LOG MAP_REGEX MATCHGECOS MILTER MIME7TO8 MIME8TO7
NAMED_BIND NETINET NETINET6 NETUNIX NEWDB NIS PIPELINING SASLv2
SCANF STARTTLS TCPWRAPPERS USERDB XDEBUG
....
可以看到, 我們安裝的sendmail, 已經有SASLv2的功能! 另外也可以
# telnet localhost smtp
Escape character is '^]'.
220 fb7.princo.com.tw ESMTP Sendmail 8.14.3/8.14.3; Tue, 14 Apr 2009 00:49:42 +0800 (CST)
ehlo localhost
250-fb7.princo.com.tw Hello localhost [127.0.0.1], pleased to meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-8BITMIME
250-SIZE
250-DSN
250-ETRN
250-AUTH CRAM-MD5 DIGEST-MD5 LOGIN PLAIN
250-STARTTLS
250-DELIVERBY
250 HELP


看到250-AUTH那行, 就知道SASL基本上已安裝正常! 我注意到在安裝好sendmail-sasl後, 不需要另外進行任何設定, 就會看到 250-AUTH CRAM-MD5 DIGEST-MD5, 表示這兩個驗證已經可以使用了。

要使用這兩個MD5驗證, 在我們的主機上要先建立帳號密碼:
# saslpasswd2 -c -u abc.com test
其中-c表示建立帳號(create), -u表示SASL的領域(realm), 最後一個參數為帳號; 接著系統會問你密碼兩次。這樣就會在某個檔案(/etc/sasldb? 但我沒找到!)加入一筆記錄! 可以使用
# sasldblistusers2
列出所有加入的帳號資訊。
這樣當Client端軟體, 連線上來, 就可以使用這兩個方法, 只要給對了帳號密碼的資訊, 就通過驗證了。不過, 有支援這兩個方法的Client端軟體都是比較不為國人所使用的! 可以參看以下連結頁面:
http://www.melnikov.ca/mel/devel/SASL_ClientRef.html
如果要測試的話, 也可以使用sendmail當client端來試: 找另一台主機(有安裝sendmail), 將其/etc/mail/access檔, 加入AuthInfo: 標籤:
# cd /etc/mail
# cat >> access
AuthInfo:mail.abc.com "U:test" "I:test" "P:password" "R:abc.com" "M:DIGEST-MD5"
# makemap hash access < access # chmod 600 access access.db # sendmail -Am -v -t To: test@abc.com From: test@client.abc.com Subject: Test Please ignore.
....
這裡, 我們在access檔案裡加入AuthInfo: 標籤, 其中AuthInfo:後面接著是要連線過去的主機, U:及I:用來指出帳號, P:用來指出密碼, R:用來指出領域(SASL realm)。這樣, 此台主機的sendmail在寄信給mail.abc.com這台主機時, 就會使用M:所指示的驗證機制及指定的帳號密碼來進行驗證。

使用這兩個MD5方法雖然簡單, 安全; 但因為有很多大眾使用的Client軟體不支援, 所以我們還是會打開PLAIN及LOGIN這兩個不安全的驗證機制。

當我們使用明文傳送密碼的機制時, SASL就不再去其資料庫檔案(/etc/sasldb?)查看帳號密碼, 我想因為其資料庫檔案是以MD5 hash格式存放其密碼, 而明文密碼無法與其比對! (其實還是可以吧...); 總之, SASL會去找一個設定檔, 叫做Sendmail.conf來看看要如何進行帳號密碼的比對。
# cat /usr/local/lib/sasl2/Sendmail.conf (注意S為大寫)
pwcheck_method:pam
這個檔案有三個指令可以使用:
1. srvtab
用在 Kerberos 4, 指到包含service key的檔案, 必須是完整路徑
2. auto_transition
SASL會自動替使用明文的使用者在sasldb中建立帳號資訊
3. pwcheck_method
用來指示SASL該用什麼技術來進行驗證, 可以有許多選項: passwd, shadow, pam, sasldb,...

在FreeBSD中, 預設是使用saslauthd, 可以把它想成是一個代理程式, 用來執行帳號密碼的驗證工作。可以使用man saslauthd來看其說明文件。所以當/usr/local/lib/sasl2/Sendmail.conf檔指定pwcheck_method: saslauthd時, 就必須確定saslauthd是正常的運作! 此時我們可以回到設定步驟2, 我們在/usr/local/etc/rc.d/saslauthd.sh設定檔中, 設定saslauthd的啟動相關參數:
# cat /usr/local/etc/rc.d/saslauthd.sh
...
saslauthd_enable=${saslauthd_enable:-"YES"} # Enable saslauthd
saslauthd_flags=${saslauthd_flags:-"-a pam"} # Flags to saslauthd program
...

雖然設定檔中的註解, 叫我們去/etc/rc.conf等設定檔更改, 但網路上的文章, 大都在此檔直接修改設定。改完後必須啟動它:
# cd /usr/local/etc/rc.d
# ./saslauthd.sh start
記得檢查一下, 是否成功啟動了:
# ps aux | grep saslauthd
# netstat -an | grep saslauthd
都會出現一或數筆對應的記錄, 則應該已成功啟動了。
saslauthd的參數可以有許多變化, 最重要的是-a及-O, 其他部份, 請看man saslauthd的文件說明!

-a 用來指定驗證機制, 可以是下列幾種: dce, getpwent, kerberos4, kerberos5, pam, rimap, shadow, sasldb, ldap, sia。我只試過pam, rimap這兩個方法: pam就是FreeBSD主機的登入帳號密碼了, 這也是預設的值; rimap很有趣, 它會利用imap的協定, 去遠端主機用明文驗證取得的帳號密碼登入, 再回報登入成功與否。所以我們當我們要求使用者在寄信的時候使用SMTP AUTH時, 使用者要輸入的帳號密碼, 如果就是SMTP主機的FreeBSD登入帳號密碼時, 使用預設的pam, 就可以了。但如果是另一台主機的帳號密碼時, 若該主機有IMAP服務的話, 可以使用-a rimap -O imapServer的參數來設定saslauthd。

2. AUTH=參數的控制
不管驗證成功與否, 只要開啟AUTH功能, Sendmail都會在MAIL From:那行加入AUTH=...的文字, 這樣一來令人混淆, 二來也有許多軟體會檢查AUTH=字串以供判斷是否為垃圾信等機制的用途, 所以最好修改一下設定, 使其在驗證成功時, 才加上AUTH=。

修改sendmail.mc, 加入:
define(`confAUTH_OPTIONS',`A')
# cd /usr/local/share/sendmail/cf/cf
# vi sendmail.mc
(加入以上define...)
# ./Build sendmail.cf
# ./Build install-cf
# cd /usr/local/etc/rc.d
# ./sendmail.sh restart
張貼留言