對這文章發表回應
發表限制: 非會員 可以發表
拾、寄信認證與安全連線
這裡所談的寄信認證就是指 SMTP AUTH,RedHat 所支援的 Cyrus SASL 機制可以透過三種方式進行 SMTP AUTH:
- pwcheck:直接使用 /etc/shadow 進行帳號認證
- pam:透過 PAM 模組可以使用 kerbros、LDAP、NIS、Samba、Radius......等認證機制
- sasldb:使用 SASL 使用者資料庫進行認證
這三種方法中,以第一種方法最方便,因為我們不需要額外維護一個使用者設定檔(這意味著必須重設所有使用者的密碼),也不需要去設定複雜的 PAM 組態。
使用前兩種方法認證必須具備 root 身分才行,但是 postfix 預設是以 $mail_owner來執行,所以只剩下第三種方法能利用。在這裡我們必須思考一個問題,postfix 之所以不用 root 身分執行是為了避免漏洞被駭客利用,但 postfix本身已經提供 chroot 牢籠了,也就是說即使被駭客駭掉,也僅僅只能改變 /var/spool/postfix 內的檔案,頂多就是被利用來轉信而已,這樣還需要迴避使用 root 嗎?有關這個問題的答案,由於筆者才疏學淺,不敢給什麼建議!
先來談談第三種認證方式如何使用?
- 首先替所有使用者建立 SASL 密碼:saslpasswd -u realm -c user
- 所有帳號建好後,將 sasldb 拷貝到 chroot 牢籠中,以免 postfix 讀不到:
cp /etc/sasldb /var/spool/postfix/etc/sasldb - 接著修改該使用者資料庫的擁有人和權限:
chgrp postfix /var/spool/postfix/etc/sasldb
chmod g+r /var/spool/postfix/etc/sasldb
這種做法必須付出龐大的管理成本(例如:加入或移除使用者時),如果把 postfix 改成以 root 身分執行,這些問題就迎刃而解了。要讓 postfix 以 root 身分執行,請修改 master.cf:
smtp inet n n n ...........後面欄位不用修改
接著修改 /usr/lib/sasl/smtpd.conf 的內容,將 sasldb 改成 pam,如下:
pwcheck_method: pam
有關 pam 的設定方法,在這裡不討論請自行參考系統文件,跟 SMTP AUTH 有關的設定放在 /etc/pam.d/smtp ,預設值是使用 Linux 系統認證,事實上 sendmail 就是使用這個方法。
啟用 SMTP AUTH
postfix 預設不啟用寄信認證機制,要讓 postfix 啟用 SMTP AUTH,請在 main.cf 中加入:
smtpd_sasl_auth_enable = yes
注意:如果你是使用 sasldb 帳號而非 Linux 帳號,請加入底下參數,此參數用來定義帳號的領域( realm),請與你設定的 sasl 使用者匹配(saslpasswd -u realm -c user): smtpd_sasl_local_domain = $myhostname |
啟用認證功能後,加入底下的過濾規則,將使得通過認證的使用者可以隨意寄信,而不會被過濾規則阻擋,同時其它未使用認證的使用者也能夠繼續寄信(但必須通過過濾):
smtpd_sender_restrictions = permit_sasl_authenticated ......原來設定的參數加在後面......
如果只想讓通過認證的人才能寄信,未通過認證者無法寄信,請設置底下的參數:
smtpd_client_restrictions = permit_sasl_authenticated
在 postfix 中設置此選項會有一些後遺症,假設你的伺服器是對外服務的,也就是說前端並沒有一台 mail gateway 作為白手套,這樣你的郵件伺服器將無法與其他伺服器交換郵件,這是因為這些伺服器並不知道要用什麼帳號密碼來登入你的郵件主機。
如果前端有一台 mail gateway 幫我們收信,然後再轉信給我們的主機,這個時候我們的伺服器一樣會要求 mail gateway 登入,我們可以在 mail gateway 上面設置底下參數,讓它能登入轉信:
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/saslpass
smtp_sasl_security_options = noanonymous,noplaintext
第一個參數很容易與 smtpd_sasl_auth_enable 混淆,這個參數是用來告訴 postfix連上別人的郵件主機時,要不要進行登入。第三個參數則與 smtpd_sasl_security_options 相仿,用來定義當入時所使用的密碼機制,請詳見後文的介紹!
這三個參數設置好後,還必須在 mail gateway 上建立 /etc/postfix/saslpass 帳號密碼對照表(底下範例所用的帳號必須先在自己的郵件主機上建立好):
mail.syups.tp.edu.tw mailhub:password
密碼機制
Cyrus SASL 可以使用多種密碼機制,從最簡單的 PLAIN(純文字密碼)、LOGIN(POP3 密碼,編成 base64)...... 到安全的DIGEST-MD5、CRAM-MD5,後兩者必須結合 SSL/TLS 安全連線才能使用。postfix 使用何種密碼認證是由 smtpd_sasl_security_options 參數來決定:
noplaintext | 關閉純文字密碼認證功能(包含:PLAIN 和 LOGIN) |
noactive | 防止以暴力法破解密碼 |
nodictionary | 防止以字典法破解密碼 |
noanonymous | 禁止匿名登入 |
mutual_auth | 只允許使用 SASL 2.0 認證方式 |
postfix 預設禁止匿名登入,但是允許使用純文字密碼,當然我們知道使用 PLAIN 和 LOGIN 一樣都不安全,因為密碼很容易被監聽封包的程式盜取。因此我們建議使用 SSL/TLS 安全連線來進行登入,底下參數將同時允許安全連線及一般連線:
smtp_sasl_security_options = noanonymous
smtpd_use_tls = yes
如果想禁止使用純文字方式登入,請將上面的參數改成像這樣,如果 openSSL 還沒安裝設定好,請不要啟用這個功能:
smtpd_tls_auth_only = yes
啟用安全連線
在 postfix 中啟用安全連線機制,你必須先安裝好 openSSL 套件,postfix 的 smtpd 模組在進行安全連線時會呼叫 Postfix/TLS 這個模組來管理安全通道,這就相當於 sendmail 中的 MSA。要啟用 MSA,請修改 master.cf:
smtps inet n - y - - smtpd -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes
submission inet n - y - - smtpd -o smtpd_enforce_tls=yes -o smtpd_sasl_auth_enable=yes
另外在 MSA 進行連線時,需要使用亂數產生一次性密碼,該亂數可藉由系統亂數裝置 /dev/urandom 產生,如果你的系統找不到此裝置,請設定底下的模組程式來代替:
tlsmgr fifo - - y 300 1 tlsmgr
安裝憑證
postfix 安全連線必須要有金鑰才能運作,因此利用 openSSL 產生認證所需的金鑰和憑證(放在同一個檔案裡):
cd /etc/postfix
openssl req -new -x509 -nodes -out cert.pem -keyout key.pem -days 3650
chmod 600 *.pem
現在必備的憑證檔案都有了,我們可以設定 mian.cf 讓 postfix 讀取憑證:
smtpd_tls_cert_file = /etc/postfix/cert.pem
smtpd_tls_key_file = /etc/postfix/key.pem
連線測試
我們設定好相關參數後,可以將 postfix 重新啟動並使用 telnet 進行底下連線測試:
[root@linux postfix]# telnet 172.16.11.1 25
Trying 172.16.11.1...
Connected to 172.16.11.1.
Escape character is '^]'.
220 linux.syups.tp.edu.tw ESMTP Postfix
ehlo test.com //由於是從主控台連線,並不會過濾 HELO 命令字串
250-linux.syups.tp.edu.tw
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS //系統支援安全連線
250-AUTH PLAIN LOGIN //系統支援寄信認證功能
250-XVERP
250 8BITMIME
當 main.cf 啟用 smtpd_tls_auth_only = yes 參數時,進行底下測試:
auth plain
//測試能否以純文字方式登入
538 Encryption required for requested authentication mechanism
starttls //測試能否開啟 SSL/TLS 連線
220 Ready to start TLS
quit