Intro
Postfix為目前主要Linux底層送信軟體,如mail
, sendmail (PHP mail底層)
也都是基於Postfix發信。 本篇為純送信Mail Server指南,OS環境為Ubuntu 16.04。
安裝
$ sudo apt install postfix
設定 (Interactive)
$ sudo dpkg-reconfigure postfix
或者直接對應設定檔:/etc/postfix/main.cf
基本設定完後,就已經完成基本寄信Relay Server,預設無驗證僅採用mynetworks
allowed host。
驗證
Postfix需搭配SASL驗證(對應OS系統使用者帳密),預設使用Cyrus SASL、可選用Dovecot SASL,雖然本篇是純粹寄信(SMTP)不做收信(POP3/IMAP)理當用Dovecot有點多餘,但Dovecot SASL整合個人覺得較方便。
Dovecot SASL 整合
1. 安裝Dovecot Core:
$ sudo apt install dovecot-core
2. 設定Postfix指定SASL使用Dovecot SASL /etc/postfix/main.cf
加入:
# Dovecot SASL
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_local_domain =
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = yes
smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination
3. 設定Dovecot本身,/etc/dovecot/conf.d/10-master.conf
開啟註解:
# Postfix smtp-auth
unix_listener /var/spool/postfix/private/auth {
mode = 0666
}
或者 mode = 0660 設 user & group = postfix
4. 設定Dovecot Auth Mechanism /etc/dovecot/conf.d/10-auth.conf
:
auth_mechanisms = plain login
5. 兩者皆做重啟後即可依照系統使用者帳密做SMTP Relay:
sudo systemctl restart dovecot.service
sudo systemctl restart postfix.service
維護
Version
Interface有點弱,只能:
$ postconf -d | grep mail_version
Log
/var/log/mail.log
檢查Mail Queue
$ mailq
OR:
$ postqueue -p
執行Mail Queue
$ postqueue -f
OR
$ postfix flush
基本上被對方卡住的就是繼續卡,無效用。
刪除Mail Queue
$ postsuper -d ALL
郵件差異刪除
$ postsuper -d ALL deferred
進階設定
SMTP port change
情境如GCE要連過來relay的client,設定上增加或修改 /etc/postfix/master.cf
再重啟服務:
2525 inet n - n - - smtpd
第一個參數為port,原設定皆常數化,可自訂port
mydestination 驗證檢查
只要寄件者Domain包含在mydestination
都會允許不過SMTP驗證,要特別注意。/etc/postfix/main.cf
:
mydestination = $myhostname, smtp, localhost.localdomain, localhost
TLS設定或關閉
TLS預設設定非常鬆散,一般Client根本會雙向驗證失敗無法走SSL/TLS,如要關閉,/etc/postfix/main.cf
:
smtpd_use_tls=no
關閉是為了防止Client自動偵測STARTTLS支援進而使用TLS連線
如要完整安裝TLS,除了憑證Key與Cert,另外還得增加CA以確保Client最大支援度,/etc/postfix/main.cf
:
smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
smtpd_tls_CAfile = /etc/ssl/certs/CA.pem
以上憑證還得搭配匹配的domain連入才達成完整的TLS傳輸。
若想並存TLS協定,例如25 port不認證、587 port走STARTTLS,則反註解/etc/postfix/master.cf
:
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
SSL(465)模式設定
承上,別於STARTTLS(587),若想支援舊標準SSL/TLS(465)認證,可以額外開啟465 port設定,反註解/etc/postfix/master.cf
:
smtps inet n - y - - smtpd
-o syslog_name=postfix/smtps
-o smtpd_tls_wrappermode=yes
-o smtpd_sasl_auth_enable=yes
但與STARTTLS一樣就是需要憑證完整性,否則一般Client在建SSL Socket時一樣會失敗。
寄信問題
Return-Path 更換
寄件者若不設定 Return-Path 的情況下,送出郵件的 Return-Path 預設即會使用系統用戶名加上Hostname:linux-user@myhostname
。
此情況下若寄件人為 service@myhostname 而因由linux-user執行發信而 Return-Path 為 linux-user@myhostname,恐會造成收信伺服器驗證問題。
PHP 解決方法
$headers = 'From: webmaster@example.com' . "\r\n" .
'Reply-To: webmaster@example.com' . "\r\n" .
'Return-Path: webmaster@example.com' . "\r\n" .
設定Header也可能最後送出時被Postfix Override而失效,已下強制方法測試有效:
mail('nobody@example.com', 'the subject', 'the message', $headers,
'-f webmaster@example.com');
Reference: PHP Mail() additional_parameters Return-Path問題詳細測試文:Setting Return-Path in PHP mail()
送信阻擋不順疑難排除
IPv6 ReverseDNS:
如果機器IPv6開啟但沒有作ReverseDNS,像GMail就可能因此阻擋退信。
以Ubuntu(16.04)為例:
sudo vim /etc/sysctl.conf
// 底部加入以下設定值
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
重啟套用設定
sudo sysctl -p
檢查是否生效,沒出現文字就是已經關了 ipv6 了。
ip a | grep inet6
AWS EC2 送信過慢問題:
AWS EC2有對SMTP服務(似乎是封包)進行節流阻擋,目前可以透過特殊表單申請開通即可!
GCP目前全阻擋,無法使用SMTP網路服務,僅提供465/587對gmail server。