[Postfix] SMTP Mail Server 架設教學指南 – Postfix with Ubuntu

Intro

本篇為純送信Mail Server指南,OS環境為Ubuntu 16.04。

Postfix – Ubuntu (Dovecot SASL)

快速安裝檔


安裝

$ 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。


References

Leave a Reply

Your email address will not be published. Required fields are marked *