個人電子郵箱服務器的搭建:Postfix+Dovecot+Sqlite+PostfixAdmin+RoundCube

個人電子郵箱服務器的搭建:Postfix+Dovecot+Sqlite+PostfixAdmin+RoundCube

一、前言

個人網站上的Http服務已經搭建了不少,準備在其上整一個高大上的:電子郵箱服務(俗稱伊妹兒)。

整個服務還是基於arm的盒子之上。

Host環境:Ubuntu 18.04.5 (PC)

編譯工具鏈:arm-himix200-linux(解包自arm-himix200-linux.tgz,據說來自Hi3516dv300SDK),海思提供的arm編譯工具鏈

環境變量:執行命令:export PATH=/opt/hisi-linux/x86-arm/arm-himix200-linux/bin:$PATH

二、Postfix/Dovecot軟件包的編譯

Postfix版本:3.7.2

Dovecot版本:2.3.19.1

cyrus-sasl版本:2.1.28

雖然希望基於Host的PC環境交叉編譯出三個軟件包出來,但Postfix及Dovecot其實並沒有考慮交叉編譯情況,手工來調整、修改的工作量太大(主要也是懶得再去花幾天時間來搞)。所以,除cyrus-sasl庫外,Postfix與Dovecot均是在ARM的盒子上編譯出來的。

2.1 編譯cyrus-sasl

編譯命令如下:

env LD_LIBARAY_PATH=${LD_LIBRARY_PATH}:/data/app/lib PATH=$PATH:/data/app/bin PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/data/app/lib/pkgconfig ./configure --host=arm-linux CC=/opt/hisi-linux/arm-himix200-linux/bin/arm-himix200-linux-gcc --prefix=/data/app \
      --disable-krb4 \
      --disable-macos-framework \
      --disable-otp \
      --disable-passdss \
      --disable-srp \
      --disable-srp-setpass \
      --disable-static \
      --enable-alwaystrue \
      --enable-anon \
      --enable-auth-sasldb \
      --enable-checkapop \
      --enable-cram \
      --enable-digest \
      --enable-plain \
      --enable-shared \
      --enable-sql \
      --with-devrandom=/dev/urandom \
      --with-configdir=/data/app/etc/sasl2:/data/app/etc/sasl:/data/app/usr/lib/sasl2 \
      --with-sqlite3=/data/app/lib  \
	  --without-pgsql  \
	  --without-mysql  \
	  LDFLAGS="-L/data/app/lib -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4" CFLAGS="-I/data/app/include  -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4"

這兒將軟件包編譯後,安裝到/data/app目錄,同時指定了LDFLAGS與CFLAGS,以適應ubuntu下armhf規範的運行要求。

編譯完成後,使用make DESTDIR=xxx/bin install命令安裝到特定目錄待打包。

進入特定目錄,可使用如下腳本命令打包。

exec_line() { sudo rm ../../../01.bin/$1.bin.tar.gz ../../../01.bin/$1.strip.bin.tar.gz; sudo tar czf ../../../01.bin/$1.bin.tar.gz ./*; arm-himix200-linux-strip data/app/bin/* data/app/sbin/* data/app/lib/*.so* data/app/lib/sasl2/*.so*; tar czf ../../../01.bin/$1.strip.bin.tar.gz ./*; }; exec_line `basename \`dirname $PWD\` `

2.2 編譯Postfix

由於是在ARM盒子上編譯的PostFix,一應的編譯依賴就比較好處理(通過apt去安裝即可)。

編譯命令如下:

make makefiles shared=yes dynamicmaps=yes \
command_directory=/data/app/bin \
config_directory=/data/app/etc/postfix \
daemon_directory=/data/app/libexec/postfix \
mailq_path=/data/app/bin/mailq \
meta_directory=/data/app/etc/postfix \
newaliases_path=/data/app/bin/newaliases \
sendmail_path=/data/app/bin/sendmail \
shlib_directory=/data/app/lib \
manpage_directory=/data/app/share/man \
mail_spool_directory=/data/mail/data \
OPT=" -O2 " DEBUG="" \
'CCARGS=-DNO_DB -DDEF_CONFIG_DIR=\"/data/app/etc/postfix\" -DUSE_SASL_AUTH -DUSE_CYRUS_SASL -I/data/app/include/sasl -DUSE_TLS -I/data/app/include/openssl/ -DHAS_PCRE=2 -DHAS_SQLITE  -I/data/app/include -DHAS_MYSQL -I/data/app/include/mysql/' 'AUXLIBS=-L/data/app/lib -L/data/app/lib/sasl2 -lsasl2  -lssl -lcrypto -L/data/app/lib -lpcre -L/data/app/lib -lsqlite3 -lpthread -L/data/app/lib -lmysqlclient -lz -lm ' 'AUXLIBS_MYSQL=-L/data/app/lib -lmysqlclient -lz -lm ' 'AUXLIBS_SQLITE=-L/data/app/lib -lsqlite3 -lpthread' 'AUXLIBS_PCRE=-L/data/app/lib -lpcre'
make

這兒有幾個要注意的點,OPT=-o2,即指定O2級別的優化,DEBUG如果不指定爲空,此版本的Postfix會自帶-g參數進行編譯(即會帶調試符號)。CCARGS與AUXLIBS從諸多參考、說明文檔中也能見到,但3.0版本後的Postfix,還必須指定諸如AUXLIBS_MYSQL、AUXLIBS_SQLITE、AUXLIBS_PCRE這樣的變量,這些宏定義在Postfix以dynamicmaps方式編譯時是必須的。例如,編譯後的postfix-mysql.so之類的動態庫,如果未指定AUXLIBS_MYSQL,會出現加載時報相應so加載不成功(沒有在鏈接so時指定mysqlclient依賴庫,此so會找不到依賴的某些mysql函數)。

上一步生成的Makefile,再使用make命令,即會開始整個編譯工作。

編譯後,應使用如下命令,將編譯好的軟件安裝到特定目錄待打包。

sh postfix-install -non-interactive install_root="/xxxx/postfix-3.7.2/dest"

在dest目錄下,可使用如下腳本命令打包。

exec_line() { sudo rm ../../../01.bin/$1.bin.tar.gz ../../../01.bin/$1.strip.bin.tar.gz; sudo tar czf ../../../01.bin/$1.bin.tar.gz ./*; strip data/app/bin/* data/app/sbin/* data/app/libexec/postfix/* data/app/lib/*.so* ; tar czf ../../../01.bin/$1.strip.bin.tar.gz ./*; }; exec_line `basename \`dirname $PWD\` `

2.3 編譯Dovecot

Dovecot的編譯系統是依賴於autoconf/automake的,相對好配置。

可使用如下編譯命令:

env LD_LIBARAY_PATH=${LD_LIBRARY_PATH}:/data/app/lib PATH=$PATH:/data/app/bin systemdsystemunitdir=/usr/lib/systemd/system ZSTD_CFLAGS=-I/data/app/include ZSTD_LIBS="-L/data/app/lib -lzstd -lpthread" ./configure --prefix=/data/app CFLAGS=-I/data/app/include LDFLAGS=-L/data/app/lib --with-moduledir=/data/app/lib/dovecot/modules --with-ssldir=/data/app/etc/ssl --with-rundir=/run/dovecot --disable-static --with-sqlite --with-mysql --with-zstd
make

這兒強制指定了systemdsystemunitdir目錄、moduledir、ssl目錄等,同時禁用靜態庫,鏈接mysql/sqlite/zstd。

autoconf/automake系統的軟件安裝,使用make DESTDIR=XXX/bin install安裝即可安裝到特定目錄待打包。

在bin目錄下,可使用如下腳本命令打包。

exec_line() { sudo rm ../../../01.bin/$1.bin.tar.gz ../../../01.bin/$1.strip.bin.tar.gz; sudo tar czf ../../../01.bin/$1.bin.tar.gz ./*; strip data/app/bin/* data/app/sbin/* data/app/libexec/dovecot/* data/app/lib/*.so* data/app/lib/dovecot/*.so*  data/app/lib/dovecot/modules/*.so* data/app/lib/dovecot/modules/auth/*.so* data/app/lib/dovecot/modules/doveadm/*.so* data/app/lib/dovecot/modules/old-stats/*.so* ; tar czf ../../../01.bin/$1.strip.bin.tar.gz ./*; }; exec_line `basename \`dirname $PWD\` `

2.4 安裝Postfix及Dovecot

軟件包編譯好後,即可以拷貝、並安裝至相應目錄。mail服務的特性,會對軟件執行環境、軟件權限有較多檢查,這兒可以參考ArchLinux的Postfix、Dovecot的包配置,參考其中的xxx.sysusers、xxx.tmpfiles。

對Postfix而言,參考postfix.sysusers,生成/usr/lib/sysusers.d/postfix.conf

g postdrop 75 -
u postfix 73 - /var/spool/postfix

參考postfix.sysusers,生成/usr/lib/tmpfiles.d/postfix.conf

z /data/app/bin/postdrop 2755 root postdrop
z /data/app/bin/postqueue 2755 root postdrop
z /var/lib/postfix 700 postfix root
z /var/spool/postfix/active 700 postfix root
z /var/spool/postfix/bounce 700 postfix root
z /var/spool/postfix/corrupt 700 postfix root
z /var/spool/postfix/defer 700 postfix root
z /var/spool/postfix/deferred 700 postfix root
z /var/spool/postfix/flush 700 postfix root
z /var/spool/postfix/hold 700 postfix root
z /var/spool/postfix/incoming 700 postfix root
z /var/spool/postfix/maildrop 730 postfix postdrop
z /var/spool/postfix/private 700 postfix root
z /var/spool/postfix/public 710 postfix postdrop
z /var/spool/postfix/saved 700 postfix root
z /var/spool/postfix/trace 700 postfix root

對Dovecot而言,參考dovecot.sysusers,生成/usr/lib/sysusers.d/dovecot.conf

u dovenull 74 "Dovecot user for completely untrustworthy processes" -
u dovecot  76 "Dovecot user" -

參考dovecot.sysusers,生成/usr/lib/tmpfiles.d/dovecot.conf

d /run/dovecot 0755 root dovecot -

如上四個文件生成後,可以執行sudo systemd-sysusers創建用戶、組,sudo systemd-tmpfiles --create調整文件、目錄權限歸屬等。

(似乎有遺漏,還需要執行如下命令調整權限,否則在啓動Postfix服務時,會有告警提示)

sudo chgrp postdrop /data/app/bin/postdrop
sudo chgrp postdrop /data/app/bin/postqueue
sudo chmod g+s /data/app/bin/postqueue
sudo chmod g+s /data/app/bin/postdrop

如果shlib_directory目錄的權限不正確(group或all)的有寫權限,會有警告,使用如下命令修改

sudo chmod -R g=rx /data/app/lib
sudo chmod -R o=rx /data/app/lib

即使如此,postfix-script依然存在告警提示,這就要參考Debian的bugfix來修復了(鏈接https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=832576):

--- postfix-script.origin       2022-08-26 10:48:35.513746421 +0800
+++ postfix-script      2022-08-26 11:02:43.751868100 +0800
@@ -314,9 +314,17 @@
        find $todo ! -user root \
            -exec $WARN not owned by root: {} \;

-       find $todo \( -perm -020 -o -perm -002 \) \
+       # Handle symlinks separately
+       find -L $todo \( -perm -020 -o -perm -002 \) \
            -exec $WARN group or other writable: {} \;

+       #find $todo -type l | while read f; do
+           # makedefs out known to be a symlink and OK
+       #    if [ "$f" != "/data/app/etc/postfix/./makedefs.out" ]; then
+       #       readlink "$f" | grep -q / && $WARN symlink leaves directory: "$f";
+       #    fi
+       #done;
+
        # Check Postfix mail_owner-owned directory tree owner/permissions.

        find $data_directory/. ! -user $mail_owner \

三、配置

Postfix號稱配置簡單,那是相對於SendMail而言,實際上的配置也是複雜、麻煩得要死,而且這個服務特別的靈活,靈活就意味着麻煩多多。

Dovecot的配置則相對好一些,文檔也清晰些,從代碼的examples裏面將配置都拷貝過來,修改幾個點,就完成了。

包含PostFixAdmin、RoundCube這些東西,整個服務器的配置、搭建,花了一週左右纔算完成,期間花費很多時間去查找資料、理解配置項的理由、背景等等。

搜索了很多資料,鏈接如下:

https://www.myfreax.com/install-and-configure-postfix-and-dovecot/
https://www.cnblogs.com/apexchu/p/4271264.html
https://www.cnblogs.com/renweihang/p/7988591.html
https://www.jianshu.com/p/ffe2182c12f3
https://www.liaoxuefeng.com/article/895886450140288

3.1 配置的前言

很多資料裏面講述了MTA/MDA/MUA等等的概念,不在這兒贅述了。

簡單來說,Dovecot實現了pop3及imap協議(包含帶ssl加密的)。因此配置好後,即可登陸上去,查看其他人發送給你的郵件了。

而Postfix,主要實現SMTP(及帶s)協議,只有通過這個協議,用戶才能將手裏的郵件發送出去(具體而言,用戶使用郵件客戶端編寫好郵件後,通過SMTP協議發送到PostFix服務器上,PostFix根據配置路由一下發送出去。至於是發送到中轉服務,或者直接發送到目標郵箱服務器,根據配置而定)。

PostFixAdmin能夠簡化一些PostFix的配置辦法,主要是簡化PostFix配置虛擬域方式下,如何添加域名、添加域名下的用戶、認證用戶、用戶別名等等。

RoundCube這個就是一個WebMail的PHP實現,提供的是基於Web瀏覽器下訪問郵件服務器,接收、發送郵件等功能,底層還是基於PostFix/Dovecot提供的SMTP/POP3/IMAP協議(類似實現有RainLoop與alps,後者基於go語言)。

3.2 操作系統配置

採用虛擬域、用戶方式來配置郵箱服務器的信息,依然還是需要一個系統用戶的,因此,執行如下配置命令

sudo mkdir -p /YYYY
sudo groupadd -g 5000 vmail
sudo useradd -u 5000 -g vmail -s /usr/bin/nologin -d /YYYY -m vmail
sudo chown -R vmail:vmail /YYYY

添加一個vmail用戶,其UID/GID均爲5000,不允許登陸,並配置其用戶HOME路徑爲YYYY,此路徑也用來存儲所有虛擬域、虛擬用戶的郵件。

3.3 Dovecot的配置

先從簡單的入手,配置好Dovecot。

Dovecot的軟件包中,提供了一個示例配置,路徑是:doc/example-config/目錄

3.3.1 Dovecot主配置

主配置文件位於/data/app/etc/dovecot/dovecot.conf。

這兒定義了啓動哪些服務,監聽端口,並引入哪些配置文件。

配置很簡單,如下

protocols = pop3 imap lmtp
listen = *, ::
mail_max_userip_connections = 50
 !include conf.d/*.conf

 !include_try local.conf

這兒配置會啓動pop3/imap/lmtp三個服務,監聽所有端口,並引入conf.d目錄下所有的conf文件。

conf.d下面有很多文件,諸如:

10-auth.conf      10-mail.conf     10-ssl.conf        20-imap.conf  20-submission.conf  90-quota.conf                auth-dict.conf.ext    auth-passwdfile.conf.ext  auth-system.conf.ext
10-director.conf  10-master.conf   15-lda.conf        20-lmtp.conf  90-acl.conf         auth-checkpassword.conf.ext  auth-ldap.conf.ext    auth-sql.conf.ext
10-logging.conf   10-metrics.conf  15-mailboxes.conf  20-pop3.conf  90-plugin.conf      auth-deny.conf.ext           auth-master.conf.ext  auth-static.conf.ext

3.3.1 Dovecot的10-auth.conf配置

此配置文件中,存放用戶認證相關的配置信息,默認是僅包含auth-system.conf.ext,即使用本地用戶認證的方式。

修改爲如下:

disable_plaintext_auth = yes
auth_mechanisms = plain login
#!include auth-system.conf.ext
!include auth-sql.conf.ext

這兒註釋掉了auth-system.conf.ext的引用,改爲引用auth-sql.conf.ext文件。即不使用本地用戶認證,而使用數據庫存儲的用戶信息進行認證。使用數據庫的存儲數據作爲用戶認證數據,就可以與PostFixAdmin生成的域、用戶數據信息同源了。

auth-sql.conf.ext文件就改動很少了,將幾個args指向的配置文件路徑修改爲實際路徑即可

-  args = /etc/dovecot/dovecot-sql.conf.ext
+  args = /data/app/etc/dovecot/dovecot-sql.conf.ext

dovecot-sql.conf.ext存儲了實際訪問SQL(小型的數據庫,用SQLITE也行了)數據庫的SQL語句,內容如下。

driver = sqlite
connect = /XXXX/authdb.db
user_query = \
     SELECT ('/YYYYY/' || maildir) AS home,     \
          ('maildir:/YYYYY/' || maildir) AS mail, \
          5000 AS uid, 5000 AS gid, ('*:bytes=' || quota) AS quota_rule \
     FROM mailbox WHERE username = '%u' AND active = '1'

password_query = SELECT username AS user, password FROM mailbox \
  WHERE username = '%u' AND active = '1'

iterate_query = SELECT username AS user FROM mailbox

driver說明是使用的sqlite數據庫

connect指向實際的Sqlite數據庫文件名(也是PostFixAdmin配置的Sqlite數據庫文件位置)

user_query與password_query分別指明獲取用戶信息、認證用戶時的SQL語句(這兒是從MySQL的SQL語句參考修改而言,Sqlite中沒有concat函數,對應是 ||連接符)。

到這兒,10-auth.conf的功能基本完備了。

3.3.2 Dovecot的10-logging.conf配置

10-logging.conf主要配置Dovecot的日誌記錄,已經正常運行後,大多數的開關應該關閉。

配置信息如下:

# // 如果你不想使用 syslog,你可以讓 Dovecot 直接記錄到文件中
log_path = /var/log/dovecot.log
# If not set, use the value from log_path
info_log_path = /var/log/dovecot-info.log
# If not set, use the value from info_log_path
debug_log_path = /var/log/dovecot-debug.log

# // 啓用記錄所有失敗的身份驗證嘗試
 #auth_verbose = no
#auth_verbose = yes

# // auth_verbose_passwords=no|plain|sha1如果身份驗證失敗,此設置會記錄使用的密碼。如果您真的不需要知道密碼本身是什麼,但更想知道用戶是否只是每次都嘗試使用錯誤的密碼或者是暴力攻擊,您可以將其設置爲sha1且僅記錄密碼的 SHA1。這足以知道登錄嘗試之間的密碼是相同還是不同
 #auth_verbose_passwords = no
#auth_verbose_passwords = plain

# // 啓用所有身份驗證調試日誌記錄(也啓用auth_verbose)。密碼記錄爲<hidden>
 #auth_debug = no
#auth_debug = yes

# // 做所有事情auth_debug=yes,但它也消除了密碼隱藏(但前提是您不使用 PAM,因爲 PAM 錯誤不會寫入 Dovecot 自己的日誌)
 #auth_debug_passwords = no
#auth_debug_passwords = yes

3.3.3 Dovecot的10-mail.conf配置

10-mail.conf主要配置Dovecot存儲郵件的位置、相應的UID/GID等。

# See doc/wiki/Variables.txt for full list. Some examples:
#
#   mail_location = maildir:~/Maildir
#   mail_location = mbox:~/mail:INBOX=/var/mail/%u
#   mail_location = mbox:/var/mail/%d/%1n/%n:INDEX=/var/indexes/%d/%1n/%n
#
# <doc/wiki/MailLocation.txt>
#
mail_location = maildir:/YYYY/%d/%n

mail_uid = 5000
mail_gid = 5000

first_valid_uid = 5000
last_valid_uid = 5000

mail_privileged_group = vmail

mail_location指定用戶路徑,其中%d會被替換成郵箱地址上的相應域名,%n則會被替換成郵箱地址中去除域名後的用戶名(即分別是@前後兩部分)。

這兒,郵箱內文件格式指定爲maildir格式,也可以爲mbox等其他格式。

而mail_uid/mail_gid/first_valid_uid/last_valid_uid/mail_privileged_group這些信息就不需要介紹了。

3.3.4 Dovecot的10-master.conf配置

10-master.conf配置Dovecot啓動服務的用戶、創建的unix socket等,基本上就是權限與對外(其實就是對PostFix)交互接口的配置。

--- /ZZZZ/dovecot-2.3.19.1/doc/example-config/conf.d/10-master.conf	2022-06-14 14:55:03.000000000 +0800
+++ ./conf.d/10-master.conf	2022-08-25 10:42:59.933891605 +0800
@@ -52,8 +52,10 @@
 }
 
 service lmtp {
-  unix_listener lmtp {
-    #mode = 0666
+  unix_listener /var/spool/postfix/private/dovecot-lmtp {
+    mode = 0600
+    user = postfix
+    group = postfix
   }
 
   # Create inet listener only if you can't use the above UNIX socket
@@ -98,15 +100,17 @@
   # something else than 0666 and Dovecot lets the kernel enforce the
   # permissions (e.g. 0777 allows everyone full permissions).
   unix_listener auth-userdb {
-    #mode = 0666
-    #user = 
-    #group = 
+    mode = 0600
+    user = vmail
+    group = vmail
   }
 
   # Postfix smtp-auth
-  #unix_listener /var/spool/postfix/private/auth {
-  #  mode = 0666
-  #}
+  unix_listener /var/spool/postfix/private/auth {
+    mode = 0666
+    user = postfix
+    group = postfix
+  }
 
   # Auth process is run as this user.
   #user = $default_internal_user
@@ -117,14 +121,15 @@
   # /etc/shadow. If this isn't necessary, the user should be changed to
   # $default_internal_user.
   #user = root
+  user = vmail
 }
 
 service dict {
   # If dict proxy is used, mail processes should have access to its socket.
   # For example: mode=0660, group=vmail and global mail_access_groups=vmail
   unix_listener dict {
-    #mode = 0600
-    #user = 
-    #group = 
+    mode = 0660
+    user = vmail
+    group = vmail
   }
 }

參考網上的資料修改瞭如上一些內容,其中unix_listener lmtp,是LMTP協議參數配置(LMTP即本地郵件傳輸協議,一般用於本機或局域網內傳送電子郵件的方法,這兒就是PostFix傳輸郵件至Dovecot的途徑);而Postfix smtp-auth,則是提供給PostFix的SMTP認證的UNIX Socket(因此,能夠訪問的用戶、組爲postfix)。

3.3.5 Dovecot的10-ssl.conf配置

10-ssl.conf配置就是配置Dovecot支持SSL的能力了。

--- /BBBB/dovecot-2.3.19.1/doc/example-config/conf.d/10-ssl.conf	2022-06-14 14:55:03.000000000 +0800
+++ ./conf.d/10-ssl.conf	2022-08-26 14:31:21.965148857 +0800
@@ -2,15 +2,28 @@
 ## SSL settings
 ##
 
+# // https://doc.dovecot.org/configuration_manual/dovecot_ssl_configuration/#dovecot-ssl-configuration
+# // ssl=no: SSL/TLS 完全禁用。
+# // ssl=no: SSL/TLS 完全禁用。
+# // ssl=yesand disable_plaintext_auth=no: SSL/TLS 提供給客戶端,但客戶端不需要使用它。即使在連接上未啓用 SSL/TLS,客戶端也可以使用純文本身份驗證登錄。這是不安全的,因爲明文密碼暴露在互聯網上。
+# // ssl=yesand disable_plaintext_auth=yes: SSL/TLS 提供給客戶端,但客戶端不需要使用它。不允許客戶端使用明文身份驗證,除非先啓用 SSL/TLS。但是,如果啓用了非明文身份驗證機制,即使沒有 SSL/TLS,它們仍然是允許的。根據它們的安全程度,身份驗證要麼是完全安全的,要麼可能有一些方法使其受到攻擊。
+# // ssl=required:即使使用非明文身份驗證機制,也始終需要 SSL/TLS。任何在啓用 SSL/TLS 之前進行身份驗證的嘗試都將導致身份驗證失敗。請注意,此設置與 STARTTLS 命令無關 - 允許使用隱式 SSL/TLS 或 STARTTLS 命令。
+# // 如果您只啓用了純文本機制(例如) 和,和是完全等效的,因爲在任何一種情況下,除非首先啓用 SSL/TLS,否則身份驗證將失敗。auth_mechanisms = plain logindisable_plaintext_auth=yesssl=yesssl=required
+# // 兩者都有ssl=yes,ssl=required客戶端仍然有可能在啓用 SSL/TLS 之前嘗試進行明文身份驗證,這會將明文密碼暴露給互聯網。
+# // Dovecot 嘗試通過 LOGINDISABLED 功能向 IMAP 客戶端指示這一點,但許多客戶端仍然忽略它併發送密碼。不幸的是,Dovecot 無法阻止這種行爲。POP3 標準根本沒有同等的能力,因此 POP3 客戶端甚至無法知道服務器是否會接受明文身份驗證。
+# // ssl=required和的主要區別在於disable_plaintext_auth=yesif ssl=required,它保證整個連接不被竊聽(SSL/TLS 加密連接的其餘部分),而disable_plaintext_auth=yes只保證密碼不被竊聽(SASL 機制被加密,但沒有 SSL /TLS 必須使用)。現在你很可能應該在整個連接中使用 SSL/TLS,因爲 SSL/TLS 的成本足夠便宜。同時使用 SSL/TLS 和非明文身份驗證將是理想的情況,因爲它甚至可以保護明文密碼免受中間人攻擊。
+# // 對於來自 localhost 的連接,始終允許使用明文身份驗證(並且不需要 SSL),因爲無論如何它們都被認爲是安全的。這適用於本地和遠程 IP 地址相等的所有連接。此外,通過設置指定的 IP 範圍也login_trusted_networks被認爲是安全的。
+
 # SSL/TLS support: yes, no, required. <doc/wiki/SSL.txt>
 #ssl = yes
+ssl = yes
 
 # PEM encoded X.509 SSL/TLS certificate and private key. They're opened before
 # dropping root privileges, so keep the key file unreadable by anyone but
 # root. Included doc/mkcert.sh can be used to easily generate self-signed
 # certificate, just make sure to update the domains in dovecot-openssl.cnf
-ssl_cert = </etc/ssl/certs/dovecot.pem
-ssl_key = </etc/ssl/private/dovecot.pem
+ssl_cert = </AAAA/etc/ssl/private/vmail.crt
+ssl_key = </AAAA/etc/ssl/private/vmail.key
 
 # If key file is password protected, give the password here. Alternatively
 # give it when starting dovecot with -p parameter. Since this file is often
@@ -52,6 +65,7 @@
 # Or migrate from old ssl-parameters.dat file with the command dovecot
 # gives on startup when ssl_dh is unset.
 #ssl_dh = </etc/dovecot/dh.pem
+ssl_dh = </AAAA/etc/ssl/dhparam_2048.pem
 
 # Minimum SSL protocol version to use. Potentially recognized values are SSLv3,
 # TLSv1, TLSv1.1, TLSv1.2 and TLSv1.3, depending on the OpenSSL version used.
@@ -64,6 +78,7 @@
 #ssl_cipher_list = ALL:!kRSA:!SRP:!kDHd:!DSS:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK:!RC4:!ADH:!LOW@STRENGTH
 # To disable non-EC DH, use:
 #ssl_cipher_list = ALL:!DH:!kRSA:!SRP:!kDHd:!DSS:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK:!RC4:!ADH:!LOW@STRENGTH
+ssl_cipher_list = EECDH+AES:EDH+AES+aRSA
 
 # Colon separated list of elliptic curves to use. Empty value (the default)
 # means use the defaults from the SSL library. P-521:P-384:P-256 would be an
@@ -72,6 +87,7 @@
 
 # Prefer the server's order of ciphers over client's.
 #ssl_prefer_server_ciphers = no
+ssl_prefer_server_ciphers = yes

這兒,設置ssl爲yes,即打開ssl(同時pop3與imap,也就升級爲帶s版本的了,端口也從110、143升級爲995、993)。

ssl_cert、ssl_key與ssl_dh使用的信息,也是與域名網站的證書、私鑰、DHPARAM是一樣的(域名網站的證書,也應該支持mail.xxx,或pop3.xxx,或imap.xxx),需要注意的是,這些配置項,在文件名前必須帶<,意思是引入整個文件。

ssl_cipher_list配置SSL加密算法,這兒是隨便配置了一些。

ssl_prefer_server_ciphers爲yes,說明服務器加密算法將優於客戶端加密算法。

3.3.6 Dovecot的20-imap.conf配置

20-imap.conf配置沒有做修改。

3.3.7 Dovecot的20-lmtp.conf配置

--- /BBBB/dovecot-2.3.19.1/doc/example-config/conf.d/20-lmtp.conf	2022-06-14 14:55:03.000000000 +0800
+++ ./conf.d/20-lmtp.conf	2022-08-25 10:47:35.414844226 +0800
@@ -35,6 +35,8 @@
 #lmtp_client_workarounds =
 
 protocol lmtp {
+  postmaster_address = [email protected]
   # Space separated list of plugins to load (default is global mail_plugins).
   #mail_plugins = $mail_plugins
+  mail_plugins = $mail_plugins
 }

僅配置了postmaster_address。

至此,Dovecot的配置全部完成,可以直接以sudo systemctl start dovecot方式,啓動相應服務。

3.3.8 服務檢測

Dovecot啓動成功後,可以執行telnet命令,登陸相應服務端口,檢測服務是否正常,命令如下。

telnet pop3.xxx.cn 110
telnet imap.xxx.cn 143

3.4 PostFixAdmin的配置

在配置PostFix之前,先配置好PostFixAdmin,並進行一些域、用戶等的初始化,能夠更便於理解PostFix的配置。

PostFixAdmin需要運行在NGINX+PHP下,初始配置並不困難。

PostFixAdmin在NGINX下的配置沒有特殊之處

    location ^~ /webmailadmin {
        alias   /CCCC/postfixadmin/public/;

        # 日誌文件分開
        error_log     /var/log/nginx/webmailadmin.error.log;
        access_log    /var/log/nginx/webmailadmin.access.log;

        # set max upload size
        client_max_body_size 128M;
        fastcgi_buffers 64 4K;

        # Uncomment if your server is build with the ngx_pagespeed module
        # This module is currently not supported.
        #pagespeed off;

        location = /webmailadmin {
            #try_files $uri/ = 404;
            rewrite ^ /webmailadmin/index.php redirect;
        }
        location ~ ^\/webmailadmin\/.*\.php(\/.*)*$ {
            fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
            set $path_info $fastcgi_path_info;
            try_files $fastcgi_script_name = 404;
            include fastcgi_params;
            # 目錄限制控制
            fastcgi_param PHP_ADMIN_VALUE "open_basedir=/CCCC/postfixadmin:/YYYY:/ZZZZ:/tmp/:/proc/";
            fastcgi_param SCRIPT_FILENAME $request_filename;
            fastcgi_param PATH_INFO $path_info;
            fastcgi_param HTTPS on;
            # Avoid sending the security headers twice
            fastcgi_param modHeadersAvailable true;
            # Enable pretty urls
            fastcgi_param front_controller_active true;
            fastcgi_pass php-handler;
            fastcgi_intercept_errors on;
            fastcgi_request_buffering off;
        }
        location ~ ^\/webmailadmin\/(?:.+)*(\/|)$ {
            index index.php;
        }
        location ~ ^\/webmailadmin\/.+[^\/]\.(?:css|js|svg|gif|png)$ {
            try_files $uri /postfixadmin/index.php$request_uri;
            add_header Cache-Control "public, max-age=15778463";
            add_header Referrer-Policy "no-referrer" always;
            add_header X-Content-Type-Options "nosniff" always;
            add_header X-Download-Options "noopen" always;
            add_header X-Frame-Options "SAMEORIGIN" always;
            add_header X-Permitted-Cross-Domain-Policies "none" always;
            add_header X-Robots-Tag "none" always;
            add_header X-XSS-Protection "1; mode=block" always;

            # Optional: Don't log access to assets
            #access_log off;
        }
    }

需要注意一點,當前版本的PostFixAdmin,主體文件路徑是解壓的文件路徑下的public目錄(例/CCCC/postfixadmin/public),但配置PHP能夠訪問的文件路徑,則需要整個解壓的文件路徑(同時包含SQLITE數據庫文件路徑)。

由於在location中使用了alias,則SCRIPT_FILENAME應指向request_filename。

配置了NGINX文件後,還需要在/CCCC/postfixadmin目錄下創建templates_c目錄,並修改目錄歸屬用戶、組。

下一步,需要在PostFixAdmin目錄下生成一個config.local.php文件,以配置數據庫等信息。

<?php
$CONF['configured'] = true;
// correspond to dovecot maildir path /home/vmail/%d/%u
$CONF['domain_path'] = 'YES';
$CONF['domain_in_mailbox'] = 'NO';
$CONF['database_type'] = 'sqlite';
$CONF['database_name'] = '/YYYY/authdb.db';
$CONF['setup_password'] = '...........................';

$CONF['default_aliases'] = array (
    'abuse' => '[email protected]',
    'hostmaster' => '[email protected]',
    'postmaster' => '[email protected]',
    'webmaster' => '[email protected]'
);

然後,即可以登陸http://ZZZZZZZZ.cn/webmailadmin,創建SQLITE的相應表、並在PostFixAdmin裏添加域名、用戶名(這兒添加一個[email protected]

3.5 PostFix的配置

PostFix的配置項之多,簡直令人發麻,具體可以參考postconf.5.html、master.5.html、master.8.html等文檔(由PostFix軟件包提供了)。

主要來說,分成兩個文件,master.cf與main.cf。

master.cf文件是指示PostFix啓動哪些服務、監聽哪些端口等,其中可以配置服務啓動參數(優先級最高)。

main.cf則配置PostFix的所有參數信息(某一項未配置時,則會使用默認值)。

main.cf在配置虛擬域時,會引用幾個配置文件,具體示例類似於https://www.myfreax.com/install-and-configure-postfix-and-dovecot/中的配置說明。

3.5.1 PostFix的master.cf配置

--- /CCC/postfix-3.7.2/dest/data/app/etc/postfix/master.cf	2022-08-25 18:44:17.424783195 +0800
+++ ./master.cf	2022-08-27 13:27:29.958358702 +0800
@@ -14,9 +14,11 @@
 #smtpd     pass  -       -       n       -       -       smtpd
 #dnsblog   unix  -       -       n       -       0       dnsblog
 #tlsproxy  unix  -       -       n       -       0       tlsproxy
+smtps     inet  n       -       n       -       -       smtpd
+  -o smtpd_tls_wrappermode=yes
 # Choose one: enable submission for loopback clients only, or for any client.
 #127.0.0.1:submission inet n -   n       -       -       smtpd
-#submission inet n       -       n       -       -       smtpd
+submission inet n       -       n       -       -       smtpd
 #  -o syslog_name=postfix/submission
 #  -o smtpd_tls_security_level=encrypt
 #  -o smtpd_sasl_auth_enable=yes
@@ -26,7 +28,7 @@
 #     specify "smtpd_<xxx>_restrictions=$mua_<xxx>_restrictions"
 #     here, and specify mua_<xxx>_restrictions in main.cf (where
 #     "<xxx>" is "client", "helo", "sender", "relay", or "recipient").
-#  -o smtpd_client_restrictions=
+#  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
 #  -o smtpd_helo_restrictions=
 #  -o smtpd_sender_restrictions=
 #  -o smtpd_relay_restrictions=

master.cf並不需要修改太多,添加smtps,打開submission即可,參數信息集中在main.cf更容易管理。

3.5.2 PostFix虛擬用戶下的幾個配置文件

參考https://www.myfreax.com/install-and-configure-postfix-and-dovecot/中的虛擬用戶配置,生成了五個在SQLITE下的虛擬用戶配置。

virtual_alias_domain_catchall_maps.cf文件,

--- /CCC/postfix-3.7.2/dest/data/app/etc/postfix/virtual_alias_domain_catchall_maps.cf	1970-01-01 08:00:00.000000000 +0800
+++ ./virtual_alias_domain_catchall_maps.cf	2022-08-24 17:44:15.457787477 +0800
@@ -0,0 +1,4 @@
+dbpath=/XXXX/authdb.db
+#query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'
+query=SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = ('@' || alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'
+

virtual_alias_domain_mailbox_maps.cf文件,

--- /CCC/postfix-3.7.2/dest/data/app/etc/postfix/virtual_alias_domain_mailbox_maps.cf	1970-01-01 08:00:00.000000000 +0800
+++ ./virtual_alias_domain_mailbox_maps.cf	2022-08-24 17:50:22.332173785 +0800
@@ -0,0 +1,4 @@
+dbpath=/XXXX/authdb.db
+# query = SELECT maildir FROM mailbox,alias_domain WHERE alias_domain.alias_domain = '%d' and mailbox.username = CONCAT('%u', '@', alias_domain.target_domain) AND mailbox.active = 1 AND alias_domain.active='1'
+query=SELECT maildir FROM mailbox,alias_domain WHERE alias_domain.alias_domain = '%d' and mailbox.username = ('%u' || '@' || alias_domain.target_domain) AND mailbox.active = 1 AND alias_domain.active='1'
+

virtual_alias_domain_maps.cf文件,

--- /CCC/postfix-3.7.2/dest/data/app/etc/postfix/virtual_alias_domain_maps.cf	1970-01-01 08:00:00.000000000 +0800
+++ ./virtual_alias_domain_maps.cf	2022-08-24 17:45:36.239097657 +0800
@@ -0,0 +1,3 @@
+dbpath=/XXXX/authdb.db
+# query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('%u', '@', alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1'
+query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = ('%u' ||  '@' || alias_domain.target_domain) AND alias.active = 1 AND alias_domain.active='1' 

virtual_alias_maps.cf文件,

--- /CCC/postfix-3.7.2/dest/data/app/etc/postfix/virtual_alias_maps.cf	1970-01-01 08:00:00.000000000 +0800
+++ ./virtual_alias_maps.cf	2022-08-24 17:27:56.799255594 +0800
@@ -0,0 +1,3 @@
+dbpath=/XXXX/postfix.db
+#query=SELECT goto FROM alias WHERE address = '%s'
+query=SELECT goto FROM alias WHERE address='%s' AND active = '1'

virtual_mailbox_domains.cf文件,

--- /CCC/postfix-3.7.2/dest/data/app/etc/postfix/virtual_mailbox_domains.cf	1970-01-01 08:00:00.000000000 +0800
+++ ./virtual_mailbox_domains.cf	2022-08-24 17:29:30.320478863 +0800
@@ -0,0 +1,2 @@
+dbpath=/XXXX/authdb.db
+query=SELECT domain FROM domain WHERE domain='%s' AND active = '1'

virtual_mailbox_maps.cf文件,

--- /CCC/postfix-3.7.2/dest/data/app/etc/postfix/virtual_mailbox_maps.cf	1970-01-01 08:00:00.000000000 +0800
+++ ./virtual_mailbox_maps.cf	2022-08-24 17:32:14.415586351 +0800
@@ -0,0 +1,3 @@
+dbpath=/XXXX/authdb.db
+query = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1'

這些文件的主要修改參考https://www.myfreax.com/install-and-configure-postfix-and-dovecot/說明,將其中MySQL的語句,修改適配至Sqlite而已。

3.5.3 PostFix的main.cf配置

由於main.cf的配置項修改較多,就一個個分開說明(大量參數說明僅僅是拷貝機翻,能大致看懂即可):

1). myhostname

當前郵件系統在互聯網上的主機名,如果OS主機名就修改好了,這兒也可以不設置,但通常而言,設置比不設置更好。

 # from gethostname(). $myhostname is used as a default value for many
 # other configuration parameters.
 #
+# // 與其他SMTP服務器通信時,Postfix使用此主機名來標識自己。 但是,操作系統主機名可能會更改,因此,最好直接在配置文件中設置。
 #myhostname = host.domain.tld
 #myhostname = virtual.domain.tld
+myhostname = mail.XXXX.cn
2).mydomain

域名,缺省是使用myhostname減去前面那一塊,或者localdomain。

 # The mydomain parameter specifies the local internet domain name.
 # The default is to use $myhostname minus the first component.
 # $mydomain is used as a default value for many other configuration
 # parameters.
 #
+# 設置域名是XXXX.cn 
 #mydomain = domain.tld
+mydomain = XXXX.cn
3).myorigin

這個域名,是本地投遞顯示的來源處,或本地郵件投遞的派發地。缺省情況下,等於myhostname即可;如果在多個機器上運行一個域(多個MTA?),則應該修改爲mydomain,或者建立域名範圍的別名數據庫(針對每個用戶,建立用戶名到用戶@xxx的別名映射)。

 # For the sake of consistency between sender and recipient addresses,
 # myorigin also specifies the default domain name that is appended
 # to recipient addresses that have no @domain part.
-#
+# 
+# // myorigin參數指定默認域名,該默認域名將附加到沒有@domain部分的發件人和收件人地址。 需要將其值更改爲XXXX.cn,因此郵件服務器上的發件人將具有@XXXX.cn地址。
 #myorigin = $myhostname
-#myorigin = $mydomain
+myorigin = $mydomain
4).inet_interfaces

inet_interfaces定義網卡監聽地址,如果希望收到外部郵件,無疑要使用all。

 #
 # Note: you need to stop/start Postfix when this parameter changes.
 #
-#inet_interfaces = all
+#定義網卡監聽地址。可以指定要使用服務器的哪些IP地址對外提供電子郵件服務;也可以乾脆寫成all,代表所有IP地址都能提供電子郵件服務
+inet_interfaces = all
 #inet_interfaces = $myhostname
 #inet_interfaces = $myhostname, localhost
5).mydestination

mydestination定義郵件服務器上自身最終目的地的域列表。這個聽起來有點拗口,說白了就是別人給您發信,哪些信你是接受的。

默認postfix從mydestination和virtual_mailbox_domains兩個參數來確定postfix需要接收哪些域的郵件。如果接收的郵件域與mydestination匹配,則使用系統帳號處理郵件;如果接收的郵件域與virtual_mailbox_domains匹配則使用虛擬帳號處理郵件。

因此,在定義虛擬帳號來處理郵件時,應將mydomain從mydestination中刪除。

 # The mydestination parameter specifies the list of domains that this
 # machine considers itself the final destination for.
@@ -179,11 +186,17 @@
 # Continue long lines by starting the next line with whitespace.
 #
 # See also below, section "REJECTING MAIL FOR UNKNOWN LOCAL USERS".
-#
+# 
+# //mydestination參數指定服務器將其視爲自身最終目的地的域列表。這個聽起來有點拗口,說白了就是別人給您發信,哪些信你是接受的。比如[email protected]給您發一封信,收件人是[email protected],當你的smtp服務器接收到這封信的時候表示接受,對應的規則就是$mydomain。注意:此處如果設錯了,有可能出現一個問題:你可以給別人發信,但是別人給你發的信你會收不到。
 #mydestination = $myhostname, localhost.$mydomain, localhost
+#定義可接收郵件的主機名或域名列表
 #mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
 #mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain,
 #	mail.$mydomain, www.$mydomain, ftp.$mydomain
+# // 默認postfix從mydestination和virtual_mailbox_domains兩個參數來確定postfix需要接收哪些域的郵件。如果接收的郵件域與mydestination匹配,則使用系統帳號處理郵件;如果接收的郵件域與virtual_mailbox_domains匹配則使用虛擬帳號處理郵件。
+# // 此處mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain,($mydomain=test.edu.cn)且virtual_mailbox_domains指定的mysql數據庫中也存在test.edu.cn域,這樣[email protected]郵件就同時匹配兩種帳號,postfix不能判斷使用哪種帳號去處理這個郵件,所以就出現了上述這種錯誤。
+# //所以配置mydestination時,一定要考慮到不能與虛擬域有相同的域名。
+mydestination = $myhostname, localhost.$mydomain, localhost
6).mynetworks_style

mynetworks_style爲mynetworks參數定義生成默認值的方法。這是用於中繼訪問控制等的受信任網絡列表。

爲host時,僅信任本機;爲subnet時,信任子網的機器(在Linux上,僅在指定了ifconfig或ip命令的網口時正常工作);爲class時,則信任指定的A、B或C類網絡。

 # REJECTING MAIL FOR UNKNOWN LOCAL USERS
 #
@@ -270,7 +283,8 @@
 # 
 #mynetworks_style = class
 #mynetworks_style = subnet
-#mynetworks_style = host
+# // Postfix默認將子網內的機器設置爲可信任機器,如果只信任本機,就設置爲host:
+mynetworks_style = host
7).mynetworks

mynetworks生效時,則mynetworks_style不起作用。

在此限制範圍內的SMTP客戶端有更高的優先權。

 # Alternatively, you can specify the mynetworks list by hand, in
 # which case Postfix ignores the mynetworks_style setting.
@@ -284,6 +298,8 @@
 # (the value on the table right-hand side is not used).
 #
 #mynetworks = 168.100.3.0/28, 127.0.0.0/8
+# //263行,設置內網和本地IP  
+mynetworks = 192.168.1.0/24, 127.0.0.0/8
 #mynetworks = $config_directory/mynetworks
 #mynetworks = hash:/etc/postfix/network_table
8).alias_maps

alias_maps,這個應該是別名映射表。配置了虛擬賬號,就不需要配置這個參數了。

 #alias_maps = hash:/etc/aliases
 #alias_maps = hash:/etc/aliases, nis:mail.aliases
 #alias_maps = netinfo:/aliases
+# // 虛擬域,不配置本地別名投遞
+alias_maps = 
 
 # The alias_database parameter specifies the alias database(s) that
 # are built with "newaliases" or "sendmail -bi".  This is a separate
9).home_mailbox

home_mailbox定義郵件保存位置,也是本地帳號郵箱投遞體系的一個參數。

 # "Maildir/" for qmail-style delivery (the / is required).
 #
 #home_mailbox = Mailbox
-#home_mailbox = Maildir/
+# // Postfix設置Maildir格式的郵箱  用來定義郵件保存位置
+home_mailbox = Maildir/
  
 # The mail_spool_directory parameter specifies the directory where
 # UNIX-style mailboxes are kept. The default setting depends on the
10).smtpd_banner

smtpd_banner爲SMTP客戶端登陸上來時的歡迎提示信息。

 #
 #smtpd_banner = $myhostname ESMTP $mail_name
 #smtpd_banner = $myhostname ESMTP $mail_name ($mail_version)
+smtpd_banner = $myhostname ESMTP unknown
 
 # PARALLEL DELIVERY TO THE SAME DESTINATION
 #
11).relay_domains

relay_domains,該參數指定會將郵件中繼到哪些目標域(及其子域)。有關如何使用relay_domains值的詳細信息,請參閱 permit_auth_destination和reject_unauth_destination SMTP 收件人限制的描述。

與 $ relay_domains匹配的域使用 $ relay_transport郵件傳遞傳輸進行傳遞。 SMTP 服務器使用$relay_recipient_maps驗證收件人地址並拒絕不存在的收件人。另請參見ADDRESS_CLASS_README文件 中的中繼域地址類 。

注意:Postfix 不會自動轉發將此係統列爲主要或備用 MX 主機的域的郵件。請參閱 postconf(5)手冊頁 中的permit_mx_backup限制。

指定主機名或域名列表、“/file/name”模式或“ type:table ”查找表,以逗號和/或空格分隔。通過以空格開始下一行來繼續長行。“/file/name”模式被其內容替換;當(父)域作爲查找鍵出現時,匹配“ type:table ”查找表。指定“!pattern”以從列表中排除域。只有 Postfix 版本 2.4 和更高版本才支持 "!/file/name" 形式。

域名的模式匹配由parent_domain_matches_subdomains 參數值中是否存在“ relay_domains ”來控制。

+
+relay_domains = $mydestination
12).biff

是否使用本地biff服務。此服務向使用 UNIX 命令“ biff y” 請求新郵件通知的用戶發送“新郵件”通知

+# // 是否使用本地biff服務。此服務向使用 UNIX 命令“ biff y” 請求新郵件通知的用戶發送“新郵件”通知
+# // 出於兼容性原因,此功能默認啓用。在具有大量交互式用戶的系統上,biff服務可能會消耗性能。在main.cf中指定“ biff = no”以禁用
+biff = no
+
13).virtual_alias_maps

virtual_alias_maps、virtual_mailbox_domains及virtual_mailbox_maps這三個參數放在一起,參考https://www.myfreax.com/install-and-configure-postfix-and-dovecot/中的虛擬用戶配置,使用了3.5.2部分完成五個配置文件。

virtual_alias_maps,將特定郵件地址或域別名爲其他本地或遠程地址的可選查找表。表格格式和查找記錄在virtual(5)中。有關 Postfix 地址操作的概述,請參閱ADDRESS_REWRITING_README文檔。

指定零個或多個“type:name”查找表,以空格或逗號分隔。將按指定順序搜索表,直到找到匹配項。注意:這些查找是遞歸的。

+virtual_alias_maps = sqlite:/data/app/etc/postfix/virtual_alias_maps.cf,sqlite:/data/app/etc/postfix/virtual_alias_domain_maps.cf,sqlite:/data/app/etc/postfix/virtual_alias_domain_catchall_maps.cf
14).virtual_mailbox_domains

virtual_mailbox_domains,Postfix 是指定域列表的最終目的地;郵件通過 $ virtual_transport郵件傳遞傳輸傳遞。默認情況下,這是 Postfix virtual(8)傳遞代理。SMTP 服務器使用 $ virtual_mailbox_maps驗證收件人地址並拒絕不存在的收件人的郵件。另請參見ADDRESS_CLASS_README文件中的虛擬郵箱域類。

此參數需要與mydestination 配置參數 相同的語法。

+virtual_mailbox_domains = sqlite:/data/app/etc/postfix/virtual_mailbox_domains.cf
15).virtual_mailbox_maps

virtual_mailbox_maps,可選查找表,其中包含與 $ virtual_mailbox_domains 匹配的域中的所有有效地址。

指定零個或多個“type:name”查找表,以空格或逗號分隔。將按指定順序搜索表,直到找到匹配項。

在查找表中,指定“@domain.tld”的左側以匹配指定域中沒有特定“[email protected]”條目的任何用戶。

使用默認的“ virtual_mailbox_domains = $ virtual_mailbox_maps ”,查找表還需要具有“domain.tld”左側的條目以滿足 virtual_mailbox_domain 查找(右側是必需的,但不會使用)。

本文的其餘部分特定於virtual(8)交付代理。當使用不同的郵件遞送程序遞送郵件時,它不適用。

virtual(8)傳遞代理 使用此表來查找每個收件人的郵箱或 maildir 路徑名。如果查找結果以斜槓(“/”)結尾,則執行 maildir 樣式的傳遞,否則假定路徑指定了 UNIX 樣式的郵箱文件。請注意,$ virtual_mailbox_base無條件地添加到此路徑。

當收件人地址具有可選的地址擴展名 ([email protected]) 時,virtual(8)投遞代理首先查找完整地址,當查找失敗時,它會查找未擴展地址 ([email protected])。頂級域名)。

注意 1:出於安全原因,virtual(8)傳遞代理不允許在正則表達式查找表中用正則表達式替換 $1 等,因爲這會打開一個安全漏洞。

注意 2:出於安全原因,virtual(8)傳遞代理將默默地忽略使用proxymap(8)服務器的請求。相反,它將直接打開表。在 Postfix 版本 2.2 之前, virtual(8)傳遞代理將終止並出現致命錯誤。

+virtual_mailbox_maps = sqlite:/data/app/etc/postfix/virtual_mailbox_maps.cf,sqlite:/data/app/etc/postfix/virtual_alias_domain_mailbox_maps.cf
16).virtual_mailbox_base、virtual_mailbox_limit、virtual_minimum_uid

virtual_mailbox_base,virtual傳遞代理添加到所有路徑名的前綴,通常是去 $ virtual_mailbox_maps表查找。設置此變量是一種安全措施,可確保錯誤映射時不會在文件系統中亂扔郵箱。雖然virtual_mailbox_base可以設置爲“/”,但不建議使用此設置。

virtual_mailbox_limit,單個virtual郵箱或 maildir 文件 的最大字節大小,或零(無限制)

virtual_minimum_uid,virtual交付代理作爲 $ virtual_uid_maps表查找的結果接受 的最小用戶 ID 值。小於此值的返回值將被拒絕,並且消息將被延遲。

此參數僅用於於virtual付代理。當使用不同的郵件遞送程序遞送郵件時,它不適用。

+virtual_mailbox_base = /data/mail/data
+virtual_mailbox_limit = 512000000
+virtual_minimum_uid = 5000
17).virtual_transport

virtual_transport,最終傳遞到 $ virtual_mailbox_domains列出的域的默認郵件傳遞傳輸和下一跳目標。與transport互斥。

指定格式爲transport:nexthop的字符串,其中transport是在master.cf中 定義的郵件傳遞傳輸的名稱。: nexthop目的地是可選的;其語法記錄在相應交付代理的手冊頁中。

我們這兒定義Postfix以LMTP協議,傳遞至Dovecot存儲。

+# virtual_transport = virtual
+#Handing off local delivery to Dovecot's LMTP, and telling it where to store mail  
+virtual_transport = lmtp:unix:private/dovecot-lmtp
18).virtual_uid_maps

virtual_uid_maps,使用virtual(8) 傳遞代理在寫入收件人郵箱時使用 的每個收件人用戶 ID 查找表。

此參數特定於virtual(8)交付代理。當使用不同的郵件遞送程序遞送郵件時,它不適用。

指定零個或多個“type:name”查找表,以空格或逗號分隔。將按指定順序搜索表,直到找到匹配項。

在查找表中,指定“@domain.tld”的左側以匹配指定域中沒有特定“[email protected]”條目的任何用戶。

當收件人地址具有可選的地址擴展名 ([email protected]) 時,virtual(8)投遞代理首先查找完整地址,當查找失敗時,它會查找未擴展地址 ([email protected])。頂級域名)。

注意 1:出於安全原因,virtual(8)傳遞代理不允許在正則表達式查找表中用正則表達式替換 $1 等,因爲這會打開一個安全漏洞。

注意 2:出於安全原因,virtual(8)傳遞代理將默默地忽略使用proxymap(8)服務器的請求。相反,它將直接打開表。在 Postfix 版本 2.2 之前, virtual(8)傳遞代理將終止並出現致命錯誤。

+virtual_uid_maps = static:5000
19).virtual_gid_maps

具有每個收件人組 ID 的查找表以進行虛擬 (8)郵箱傳遞。

此參數特定於virtual(8)交付代理。當使用不同的郵件遞送程序遞送郵件時,它不適用。

指定零個或多個“type:name”查找表,以空格或逗號分隔。將按指定順序搜索表,直到找到匹配項。

在查找表中,指定“@domain.tld”的左側以匹配指定域中沒有特定“[email protected]”條目的任何用戶。

當收件人地址具有可選的地址擴展名 ([email protected]) 時,virtual(8)投遞代理首先查找完整地址,當查找失敗時,它會查找未擴展地址 ([email protected])。頂級域名)。

注意 1:出於安全原因,virtual(8)傳遞代理不允許在正則表達式查找表中用正則表達式替換 $1 等,因爲這會打開一個安全漏洞。

注意 2:出於安全原因,virtual(8)傳遞代理將默默地忽略使用proxymap(8)服務器的請求。相反,它將直接打開表。在 Postfix 版本 2.2 之前, virtual(8)傳遞代理將終止並出現致命錯誤。

+virtual_gid_maps = static:5000
+#local_transport = virtual
+#local_recipient_maps = $virtual_mailbox_maps
+#transport_maps = hash:/data/app/etc/postfix/transport
20).smtpd_sasl_auth_enable

smtpd_sasl_auth_enable,在 Postfix SMTP 服務器中啓用 SASL 身份驗證。默認情況下,Postfix SMTP 服務器不使用身份驗證。

如果遠程 SMTP 客戶端經過身份驗證,則permit_sasl_authenticated 訪問限制可用於允許中繼訪問,如下所示:

# 對於 Postfix 2.10 及更高版本,郵件中繼策略爲
# 最好在smtpd_relay_restrictions下指定。
smtpd_relay_restrictions =
     permit_mynetworks , permit_sasl_authenticated , ...
# 使用2.10之前的Postfix,中繼策略可以是
# 僅在smtpd_recipient_restrictions下指定。
smtpd_recipient_restrictions =
     permit_mynetworks,permit_sasl_authenticated,...

要拒絕來自未經身份驗證的客戶端的所有 SMTP 連接,請指定“ smtpd_delay_reject = yes”(這是默認值)並使用:

smtpd_client_restrictions = permit_sasl_authenticated,reject

有關 SASL 配置和操作的詳細信息,請參閱SASL_README文件。

+
+# // 啓用sasl服務,並配置一些屬性。它們的作用,大家參考文檔
+# //使用SMTP認證  
+smtpd_sasl_auth_enable = yes
21).smtpd_sasl_type

smtpd_sasl_type,Postfix SMTP 服務器應用於身份驗證的 SASL 插件類型。可用類型使用“ postconf -a ”命令列出。

通常編譯有cyrus與dovecot,這裏直接使用dovecot的sasl認證服務。

+# // #使用dovecot的sasl服務。默認使用cyrus,所以一定要配置這個選項
+smtpd_sasl_type = dovecot
22).smtpd_sasl_path

smtpd_sasl_path,調用sasl服務的路徑。支持文件句柄(適合在同一臺機器)和請求接口(適合不同機器)

+# // # Can be an absolute path, or relative to $queue_directory
+# smtpd_sasl_path = /var/run/dovecot/auth-client
+# // #調用sasl服務的路徑。支持文件句柄(適合在同一臺機器)和請求接口(適合不同機器)
+# // dovecot開啓sasl服務的在/etc/dovecot/conf.d/10-master.conf,裏面有明顯的註釋,去掉就可以
+smtpd_sasl_path = /var/spool/postfix/private/auth
23).smtpd_sasl_security_options

smtpd_sasl_security_options,SMTP服務的SASL安全選項(也依賴於smtpd_sasl_type)。

可指定如下0個或多個:

  • noplaintext

    禁止使用明文密碼的方法。

  • noactive

    禁止方法受到主動(非字典)攻擊。

  • nodictionary

    禁止方法受到被動(字典)攻擊。

  • noanonymous

    禁止允許匿名身份驗證的方法。

  • forward_secrecy

    只允許支持前向保密的方法(僅限 Dovecot)。

  • mutual_auth

    僅允許提供相互身份驗證的方法(不適用於 Cyrus SASL 版本 1)。

默認情況下,Postfix SMTP 服務器接受明文密碼,但不接受匿名登錄。

smtpd_sasl_tls_security_options,Postfix SMTP 服務器用於 TLS 加密的 SMTP 會話的 SASL 身份驗證安全選項。

+# //取消匿名登陸方式
+smtpd_sasl_security_options = noanonymous
+smtpd_sasl_tls_security_options = $smtpd_sasl_security_options
24).smtpd_tls_security_level

smtpd_tls_security_level,指定Postfix SMTP 服務器的 SMTP TLS 安全級別;當指定非空值時,這將覆蓋過時的參數 smtpd_use_tls和smtpd_enforce_tls。使用“ smtpd_tls_wrappermode = yes” 忽略此參數。

三個選擇其一:

none不會使用 TLS

may 可選TLS:向遠程 SMTP 客戶端宣佈 STARTTLS 支持,但不要求客戶端使用 TLS 加密。

encrypt

強制 TLS 加密:宣佈遠程 SMTP 客戶端支持 STARTTLS,並要求客戶端使用 TLS 加密。根據RFC 2487,這絕不能應用於公共引用的 SMTP 服務器。相反,此選項應僅在專用服務器上使用。

參數設置“ smtpd_tls_security_level = encrypt”意味着“ smtpd_tls_auth_only = yes”。

+
+smtpd_tls_security_level = may
25).smtpd_tls_auth_only

smtpd_tls_auth_only,當 TLS 加密在 Postfix SMTP 服務器中是可用時,不接受未加密連接上的 SASL 身份驗證。

打開此選項時,會導致RoundCube無法發送郵件,因此關閉此選項。

+# // RoundCube fail if smtpd_tls_auth_only = yes
+#smtpd_tls_auth_only = yes
26).smtpd_tls_received_header

smtpd_tls_received_header,請求 Postfix SMTP 服務器生成 Received消息頭,其中包括有關使用的協議和密碼的信息,以及遠程 SMTP 客戶端 CommonName 和客戶端證書頒發者 CommonName。默認情況下禁用此功能,因爲信息可能在通過其他郵件服務器的傳輸過程中被修改。只有最終目的地記錄的信息是可信的。

+smtpd_tls_received_header = yes
27).smtpd_tls_cert_file與smtpd_tls_key_file

smtpd_tls_cert_file,帶有 PEM 格式的 Postfix SMTP 服務器 RSA 證書的文件。該文件還可能包含 Postfix SMTP 服務器私有 RSA 密鑰。對於 Postfix ≥ 3.4,配置服務器密鑰和證書的首選方法是通過“ smtpd_tls_chain_files ”參數。

沒有由“信譽良好的”CA 簽署的證書的公共 Internet MX 主機必鬚生成並準備向大多數客戶提供自簽署或私有 CA 簽署的證書。客戶端將無法對服務器進行身份驗證,但除非它運行 Postfix 2.3 或類似軟件,否則它仍會堅持使用服務器證書。

對於不是公共 Internet MX 主機的服務器,Postfix 支持沒有證書的配置。這需要僅使用典型 SMTP 客戶端不支持的匿名 TLS 密碼。由於某些客戶端在 TLS 握手失敗後可能不會回退到純文本,因此無證書的 Postfix SMTP 服務器將無法接收來自某些啓用 TLS 的客戶端的電子郵件。爲避免意外配置無證書,Postfix 僅在管理員明確設置“ smtpd_tls_cert_file = none”時啓用無證書操作。這確保了新的 Postfix SMTP 服務器配置不會在沒有證書的情況下意外啓用 TLS。

請注意,服務器證書在 TLS 1.3 中不是可選的。要在沒有證書的情況下運行,您必須通過在“ smtpd_tls_protocols ”中包含“!TLSv1.3 ”以及可能在“ smtpd_tls_mandatory_protocols ”中包含“! TLSv1.3 ”來禁用TLS 1.3 協議。相反,只配置證書鏈更簡單。不推薦無證書操作。

支持 RSA 和 DSA 證書。當這兩種類型都存在時,使用的密碼確定將向客戶端提供哪個證書。對於沒有特殊密碼選擇的 Netscape 和 OpenSSL 客戶端,首選 RSA 證書。

要使遠程 SMTP 客戶端能夠驗證 Postfix SMTP 服務器證書,頒發 CA 證書必須對客戶端可用。您應該在服務器證書文件中包含所需的證書,首先是服務器證書,然後是頒發 CA(自下而上的順序)。

示例:“server.example.com”的證書由“中間 CA”頒發,該 CA 本身具有“根 CA”證書。使用“cat server_cert.pem intermediate_CA.pem root_CA.pem > server.pem”創建 server.pem 文件。

如果您還想驗證這些 CA 頒發的客戶端證書,您可以將 CA 證書添加到smtpd_tls_CAfile,在這種情況下,不必將它們放在smtpd_tls_cert_filesmtpd_tls_dcert_file(已過時)或smtpd_tls_eccert_file中。

此處提供的證書必須可用作 SSL 服務器證書,因此必須通過“openssl verify - purpose sslserver ...”測試。

smtpd_tls_key_file,帶有 PEM 格式的 Postfix SMTP 服務器 RSA 私鑰的文件。該文件可以與 $ smtpd_tls_cert_file指定的 Postfix SMTP 服務器 RSA 證書文件結合使用。對於 Postfix ≥ 3.4,配置服務器密鑰和證書的首選方法是通過“ smtpd_tls_chain_files ”參數。

私鑰必須可以在沒有密碼的情況下訪問,即它不能被加密。文件權限應授予對系統超級用戶帳戶(“root”)的只讀訪問權限,而不授予其他任何人訪問權限。

+# // 設置SMTP使用SSL加密的證書與私鑰
+smtpd_tls_cert_file = /XXXX/etc/ssl/private/vmail.crt
+smtpd_tls_key_file = /XXXX/etc/ssl/private/vmail.key
28).smtpd_sasl_local_domain

smtpd_sasl_local_domain,Postfix SMTP 服務器的本地 SASL 身份驗證的域名。

+smtpd_sasl_local_domain = $mydomain
29).smtpd_tls_loglevel

smtpd_tls_loglevel,啓用 TLS 活動的附加 Postfix SMTP 服務器日誌記錄。每個日誌記錄級別自動包括以較低日誌記錄級別記錄的信息。

  • 0 禁用記錄 TLS 活動。
  • 1 僅記錄 TLS 握手完成的摘要消息 — 如果不需要客戶端證書驗證,則不記錄客戶端證書信任鏈驗證錯誤。使用 Postfix 2.8 及更早版本,記錄摘要消息、對等證書摘要信息並無條件記錄信任鏈驗證錯誤。
  • 2 還在 TLS 協商期間記錄級別。
  • 3 同時記錄 TLS 協商過程的十六進制和 ASCII 轉儲。
  • 4 還記錄 STARTTLS 後完整傳輸的十六進制和 ASCII 轉儲。

除非出現問題,否則不要使用“ smtpd_tls_loglevel = 2”或更高版本。強烈建議不要使用 loglevel 4。

+smtpd_tls_loglevel = 1
30).smtpd_recipient_restrictions

smtpd_recipient_restrictions、smtpd_relay_restrictions與smtpd_sender_restrictions,限定PostFix對於郵件接收、發送及回覆的規則限制,Postfix的反垃圾郵件的功能主要集中在這幾個參數上。因此,這幾個參數的配置,也是很靈活、內容很多。

Postfix SMTP 服務器在客戶端 執行RCPT TO 命令的上下文中應用的可選限制. 可參閱SMTPD_ACCESS_README的“延遲評估 SMTP 訪問限制列表”部分。.

With Postfix versions before 2.10, the rules for relay permission and spam blocking were combined under smtpd_recipient_restrictions, resulting in error-prone configuration. As of Postfix 2.10, relay permission rules are preferably implemented with smtpd_relay_restrictions, so that a permissive spam blocking policy under smtpd_recipient_restrictions will no longer result in a permissive mail relay policy.

For backwards compatibility, sites that migrate from Postfix versions before 2.10 can set smtpd_relay_restrictions to the empty value, and use smtpd_recipient_restrictions exactly as before.

重要信息:smtpd_relay_restrictionssmtpd_recipient_restrictions參數必須至少指定以下限制之一。否則 Postfix 將拒絕接收郵件:

reject, reject_unauth_destination
defer, defer_if_permit, defer_unauth_destination

指定限制列表,以逗號和/或空格分隔。通過以空格開始下一行來繼續長行。限制按指定的順序應用;首先匹配OK的限制獲勝。

以下限制特定於使用 RCPT TO 命令接收的收件人地址。

  • check_recipient_access *type:table*

    在指定的access(5)數據庫中搜索已解析的 RCPT TO 地址、域、父域或 localpart@,並執行相應的操作。

  • check_recipient_a_access *type:table*

    在指定的access(5)數據庫中搜索 RCPT TO 域的 IP 地址,並執行相應的操作。注意:出於安全原因,不允許出現“OK”的結果。相反,使用 DUNNO 從拒絕名單中排除特定主機。此功能在 Postfix 3.0 及更高版本中可用。

  • check_recipient_mx_access *type:table*

    在指定的access(5)數據庫中搜索 RCPT TO 域的 MX 主機,並執行相應的操作。如果沒有找到 MX 記錄,則查找 A 或 AAAA 記錄,就像 Postfix SMTP 客戶端那樣。注意:出於安全原因,不允許出現“OK”的結果。相反,使用 DUNNO 從拒絕名單中排除特定主機。此功能在 Postfix 2.1 及更高版本中可用。

  • check_recipient_ns_access *type:table*

    在指定的access(5)數據庫中搜索 RCPT TO 域的 DNS 服務器,並執行相應的操作。注意:出於安全原因,不允許出現“OK”的結果。相反,使用 DUNNO 從拒絕名單中排除特定主機。此功能在 Postfix 2.1 及更高版本中可用。

  • permit_auth_destination

    當下列情況之一爲真時,允許該請求:

  • permit_mx_backup

    當本地郵件系統是 RCPT TO 域的備份 MX 時,或者當域是授權目的地時,允許請求(參見permit_auth_destination的定義)。

  • reject_non_fqdn_recipient

    當 RCPT TO 地址指定的域不是完全限定的域形式時,拒絕請求,如 RFC 所要求的。
    non_fqdn_reject_code 參數指定拒絕請求的響應代碼(默認值:504)

  • reject_rhsbl_recipient *rbl_domain=d.d.d.d*

    當 RCPT TO 域與rbl_domain下的 A 記錄“ dddd ”一起列出時拒絕請求(僅限 Postfix 版本 2.1 和更高版本)。每個“ d ”是一個數字,或者是“[]”內的一個模式,它包含一個或多個“;”分隔的數字或數字..數字範圍(Postfix 2.8 及更高版本)。如果未指定“ =dddd ”,則當 RCPT TO 域與rbl_domain下的任何 A 記錄一起列出時,拒絕請求。maps_rbl_reject_code 參數指定拒絕請求的響應代碼(默認值:554);default_rbl_reply參數指定默認的服務器回覆;和rbl_reply_maps
    參數指定具有由rbl_domain索引的服務器回覆的表。此功能在 Postfix 2.0 及更高版本中可用

  • reject_unauth_destination

    除非滿足以下條件之一,否則拒絕請求:

  • defer_unauth_destination

    拒絕與reject_unauth_destination相同的請求,並帶有非永久性錯誤代碼。此功能在 Postfix 2.10 及更高版本中可用。

  • reject_unknown_recipient_domain

    當 Postfix 不是收件人域的最終目的地,並且 RCPT TO 域具有 1) 沒有 DNS MX 和 DNS A 記錄或 2) 格式錯誤的 MX 記錄,例如具有零長度 MX 主機名的記錄(Postfix 2.3 及更高版本)。
    使用unknown_address_reject_code參數(默認值:450)、unknown_address_tempfail_action(默認值: defer_if_permit)或 556(nullmx,Postfix 3.0 及更高版本)指定回覆。詳見各參數說明

  • reject_unlisted_recipient (with Postfix version 2.0: check_recipient_maps)

    如果 RCPT TO 地址未列在其域類的有效收件人列表中,則拒絕該請求。有關詳細信息,請參閱 smtpd_reject_unlisted_recipient參數說明。此功能在 Postfix 2.1 及更高版本中可用.

  • reject_unverified_recipient

    當已知發往 RCPT TO 地址的郵件被退回或無法到達收件人地址目的地時,拒絕該請求。地址驗證信息由verify(8)服務器管理;有關詳細信息,請參閱ADDRESS_VERIFICATION_README文件。
    unverified_recipient_reject_code 參數指定當地址被退回時的數字響應代碼(默認值:450,當您確信這樣做是安全的時將其更改爲 550)
    unverified_recipient_defer_code參數指定地址探測由於臨時問題而失敗時的數字響應代碼(默認值:450)unverified_recipient_tempfail_action
    _ 參數指定由於臨時問題導致地址探測失敗後的操作(默認值: defer_if_permit)。對於具有“ enable_original_recipient = no”(後綴≤3.2)
    的別名地址,此功能會中斷。 此功能在 Postfix 2.1 及更高版本中可用

在此上下文中有效的其他限制:

在這兒允許接收由本地網絡發送過來的郵件,同時允許SASL認證通過的,並拒絕無認證的目標。

+# //設定郵件中有關收件人部分的限制
+smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination

可以參考https://www.cnblogs.com/AloneSword/p/3222912.html給出的一個限制,如下:

#1、postfix配置說明(強烈建議參看“postfix權威指南 第十一章 反垃圾郵件”)
#fqdn格式:完全限定域名格式,即用點分隔開的包括域名和主機名的主機全名
# smtpd related config
smtpd_recipient_restrictions =
        permit_mynetworks,        #檢測客戶端是否來自mynetworks或者mynetworks_style的網絡,是的話返回OK,否則返回DUNNO狀態碼。
        permit_sasl_authenticated,    #檢測用戶認證是否通過的,認證通過的返回狀態OK,否則返回DUNNO狀態碼。
        reject_non_fqdn_hostname,    #HELO/EHLO時:客戶端提供的主機名不是RFC要求的完整形式(FQND),返回REJECT,否則返回DUNNO狀態碼。 
        reject_non_fqdn_sender,        #MAIL FROM時:客戶端提供的主機名不是RFC要求的完整形式(FQND),返回REJECT,否則返回DUNNO狀態碼。
        reject_non_fqdn_recipient,    #RCPT TO時:客戶端提供的主機名不是RFC要求的完整形式(FQND),返回REJECT,否則返回DUNNO狀態碼。
        reject_unauth_destination,    #RCPT TO時:收件人不在postfix管轄的區域(由mydestination定義),返回REJECT,否則返回DUNNO狀態碼。
        reject_unauth_pipelining,    #禁止非授權客戶端使用pipelining
        reject_invalid_hostname        #HELO/EHLO時:客戶端提供的主機名不是有效的主機名時,返回REJECT,否則返回DUNNO狀態碼。
31).smtpd_relay_restrictions

smtpd_relay_restrictions,轉發郵件時的限制規則。

在smtpd_recipient_restrictions之前,Postfix SMTP 服務器在 RCPT TO 命令的上下文中應用的郵件中繼控制的訪問限制 。

轉發權限規則最好使用smtpd_relay_restrictions來實現。

爲了向後兼容,從 2.10 之前的 Postfix 版本遷移的站點可以將smtpd_relay_restrictions設置爲空值,並像以前一樣使用smtpd_recipient_restrictions 。

默認情況下,Postfix SMTP 服務器接受:

重要信息:smtpd_relay_restrictionssmtpd_recipient_restrictions參數必須至少指定以下限制之一。否則 Postfix 將拒絕接收郵件:

reject, reject_unauth_destination
defer, defer_if_permit, defer_unauth_destination

指定限制列表,以逗號和/或空格分隔。通過以空格開始下一行來繼續長行。smtpd_recipient_restrictions下記錄的限制相同 。

在這兒允許接收由本地網絡發送過來的郵件,同時允許SASL認證通過的,並拒絕無認證的目標。

+# //設定郵件中有關收件人部分的限制
+smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
32).smtpd_sender_restrictions

smtpd_sender_restrictions,Postfix SMTP 服務器在客戶端 MAIL FROM 命令的上下文中應用的可選限制。

默認是允許一切。

指定限制列表,以逗號和/或空格分隔。通過以空格開始下一行來繼續長行。限制按指定的順序應用;首先匹配OK的限制。

以下限制特定於使用 MAIL FROM 命令接收的發件人地址。

  • check_sender_access *type:table*

    在指定的access(5)數據庫中搜索 MAIL FROM 地址、域、父域或 localpart@,並執行相應的操作。

  • check_sender_a_access *type:table*

    在指定的access(5)數據庫中搜索 MAIL FROM 域的 IP 地址,並執行相應的操作。注意:出於安全原因,不允許出現“OK”的結果。相反,使用 DUNNO 從拒絕名單中排除特定主機。此功能在 Postfix 3.0 及更高版本中可用。

  • check_sender_mx_access *type:table*

    在指定的access(5)數據庫中搜索 MAIL FROM 域的 MX 主機,並執行相應的操作。如果沒有找到 MX 記錄,則查找 A 或 AAAA 記錄,就像 Postfix SMTP 客戶端那樣。注意:出於安全原因,不允許出現“OK”的結果。相反,使用 DUNNO 從拒絕名單中排除特定主機。此功能在 Postfix 2.1 及更高版本中可用。

  • check_sender_ns_access *type:table*

    在指定的access(5)數據庫中搜索 MAIL FROM 域的 DNS 服務器,並執行相應的操作。注意:出於安全原因,不允許出現“OK”的結果。相反,使用 DUNNO 從拒絕名單中排除特定主機。此功能在 Postfix 2.1 及更高版本中可用。

  • reject_authenticated_sender_login_mismatch

    僅對經過身份驗證的客戶端強制執行reject_sender_login_mismatch限制。此功能在 Postfix 2.1 及更高版本中可用。

  • reject_known_sender_login_mismatch

    僅將reject_sender_login_mismatch限制應用於 $ smtpd_sender_login_maps中已知的 MAIL FROM 地址。此功能在 Postfix 版本 2.11 及更高版本中可用。

  • reject_non_fqdn_sender

    當 MAIL FROM 地址指定的域不是 RFC 要求的完全限定域形式時,拒絕請求。
    non_fqdn_reject_code 參數指定拒絕請求的響應代碼(默認值:504)。

  • reject_rhsbl_sender *rbl_domain=d.d.d.d*

    當 MAIL FROM 域與rbl_domain下的 A 記錄“ dddd ”一起列出時拒絕請求(僅限 Postfix 版本 2.1 和更高版本)。每個“ d ”是一個數字,或者是“[]”內的一個模式,它包含一個或多個“;”分隔的數字或數字..數字範圍(Postfix 2.8 及更高版本)。如果未指定“ =dddd ”,則當 MAIL FROM 域與rbl_domain下的任何 A 記錄一起列出時,拒絕請求。maps_rbl_reject_code參數指定拒絕請求的響應代碼(默認值:554); default_rbl_reply參數指定默認的服務器回覆;和rbl_reply_maps
    參數指定具有由rbl_domain索引的服務器回覆的表。此功能在 Postfix 2.0 及更高版本中可用.

  • reject_sender_login_mismatch

    當 $ smtpd_sender_login_maps爲 MAIL FROM 地址指定所有者,但客戶端未(SASL)以該 MAIL FROM 地址所有者身份登錄時拒絕請求;或者當客戶端(SASL)登錄時,但客戶端登錄名不擁有根據 $ smtpd_sender_login_maps的 MAIL FROM 地址.

  • reject_unauthenticated_sender_login_mismatch

    僅對未經身份驗證的客戶端強制執行reject_sender_login_mismatch限制。此功能在 Postfix 2.1 及更高版本中可用。

  • reject_unknown_sender_domain

    當 Postfix 不是發件人地址的最終目的地且 MAIL FROM 域具有 1) 沒有 DNS MX 和 DNS A 記錄,或 2) 格式錯誤的 MX 記錄(例如具有零長度 MX 主機名的記錄)時拒絕請求(後綴版本 2.3 及更高版本)。
    回覆由unknown_address_reject_code參數(默認值:450)、unknown_address_tempfail_action(默認值: defer_if_permit)或 550(nullmx,Postfix 3.0 及更高版本)指定。詳見各參數說明.

  • reject_unlisted_sender

    如果 MAIL FROM 地址未列在其域類的有效收件人列表中,則拒絕該請求。有關詳細信息,請參閱 smtpd_reject_unlisted_sender參數說明。此功能在 Postfix 2.1 及更高版本中可用。

  • reject_unverified_sender

    當已知發往 MAIL FROM 地址的郵件被退回或無法到達發件人地址目的地時,拒絕該請求。地址驗證信息由verify(8)服務器管理;有關詳細信息,請參閱ADDRESS_VERIFICATION_README文件。
    unverified_sender_reject_code 參數指定已知地址退回時的數字響應代碼(默認值:450,當您確信這樣做是安全的時更改爲 550)。
    unverified_sender_defer_code指定地址探測由於臨時問題而失敗時的數字響應代碼(默認值:450) unverified_sender_tempfail_action
    _參數指定由於臨時問題導致地址探測失敗後的操作(默認值:defer_if_permit)。 對於具有“ enable_original_recipient = no”(後綴≤3.2)
    的別名地址,此功能會中斷。此功能在 Postfix 2.1 及更高版本中可用。

在此上下文中有效的其他限制:

在這兒允許接收由本地網絡發送過來的郵件,拒絕聲稱是XXXX.cn的(保證XXXX.cn僅允許本地網絡發出郵件),允許其他。

+# //設定郵件中有關收件人部分的限制
+smtpd_sender_restrictions = permit_mynetworks, reject_rhsbl_sender rbl_domain=XXXXX.cn, permit

也可以參考其他給出的:

# SMTP sender login matching config
smtpd_sender_restrictions =
        permit_mynetworks,        #檢測客戶端是否來自mynetworks或者mynetworks_style的網絡,是的話返回OK,否則返回DUNNO狀態碼。
        reject_sender_login_mismatch,    #拒絕發送者在$smtpd_sender_owner_maps中所匹配的用戶名和sasl登錄名不一致的連接。
        reject_authenticated_sender_login_mismatch,    #拒絕認證成功的發送者在$smtpd_sender_owner_maps中所匹配的用戶名和sasl登錄名不一致的連接。
        reject_unauthenticated_sender_login_mismatch    #拒絕認證失敗的發送者在$smtpd_sender_owner_maps中所匹配的用戶名和sasl登錄名不一致的連接。

一個大佬給出的說明:

+# //參考 https://www.liaoxuefeng.com/article/895886450140288
+# //我們需要對郵件的發送進行控制:
+# //對於外域到本域的郵件,必須接收,否則,收不到任何來自外部的郵件;
+# //對於本域到外域的郵件,只允許從本機發出,否則,其他人通過僞造本域地址就可以向# //外域發信;
+# //對於外域到外域的郵件,直接拒絕,否則我們的郵件服務器就是Open Relay,將被視爲# //垃圾郵件服務器。
+# //先設置發件人的規則:
+# //smtpd_sender_restrictions = permit_mynetworks, check_sender_access hash:/etc/postfix/sender_access, permit
+# //以上規則先判斷是否是本域地址,如果是,允許,然後再從sender_access文件裏檢查發件人是否存在,拒絕存在的發件人,最後允許其他發件人。
+# //然後設置收件人規則:
+# // smtpd_recipient_restrictions = permit_mynetworks, check_recipient_access hash:/etc/postfix/recipient_access, reject
+# // 以上規則先判斷是否是本域地址,如果是,允許,然後再從recipient_access文件裏檢查收件人是否存在,允許存在的收件人,最後拒絕其他收件人。
+# ///etc/postfix/sender_access的內容:
+# //example.com REJECT
+# //目的是防止其他用戶從外部以[email protected]身份發送郵件,但登錄到本機再發送則不# //受影響,因爲第一條規則permit_mynetworks允許本機登錄用戶發送郵件。
+# ///etc/postfix/recipient_access的內容:
+# // [email protected] OK
+# //[email protected] OK
+# // 因此,外域只能發送給以上兩個Email地址,其他任何地址都將被拒絕。但本機到本機發送不受影響。
+# //最後用postmap生成hash格式的文件:
+# postmap sender_access
+# postmap recipient_access

至此,PostFix的配置基本調整完成,通過systemctl來啓動PostFix即可,驗證PostFix服務是否正常的辦法類似Dovecot,使用telnet,更改對應端口即可。

3.6 配置RoundCube

RoundCube配置比較類似PostFixAdmin。不過,需要注意,RoundCube使用的數據庫,應該也PostFix/Dovecot使用的數據庫不相同,防止額外影響。

首先配置Nginx

    location ^~ /webmail {
        alias   /DDDD/roundcubemail/;

        # 日誌文件分開
        error_log     /var/log/nginx/webmail.error.log;
        access_log    /var/log/nginx/webmail.access.log;
        index         index.php index.html index.htm;

        try_files $uri $uri/ = 404;

        # Favicon
        location ~ ^/webmail/favicon.ico$ {
                alias /DDDD/roundcubemail/skins/classic/images;
                log_not_found off;
                access_log off;
                expires max;
        }
        # Robots file
        location ~ ^/webmail/robots.txt {
                allow all;
                log_not_found off;
                access_log off;
        }
        # Deny Protected directories
        location ~ ^/webmail/(config|temp|logs)/ {
                 deny all;
        }
        location ~ ^/webmail/(README|INSTALL|LICENSE|CHANGELOG|UPGRADING)$ {
                deny all;
        }
        location ~ ^/webmail/(bin|SQL)/ {
                deny all;
        }
        # Hide .md files
        location ~ ^/webmail/(.+\.md)$ {
                deny all;
        }
        # Hide all dot files
        location ~ ^/webmail/\. {
                deny all;
                access_log off;
                log_not_found off;
        }
        # Roundcube fastcgi config
        location ~ /webmail(/.*\.php)$ {
                fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
                set $path_info $fastcgi_path_info;
                try_files $fastcgi_script_name = 404;
                include fastcgi_params;
                # fastcgi_split_path_info ^/webmail/(.+\.php)(/.*)$;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $request_filename;
                fastcgi_param PATH_INFO $fastcgi_path_info;
                fastcgi_param PHP_ADMIN_VALUE "open_basedir=/tmp/:/var/cache/roundcubemail:/data/mail:/CCC/roundcubemail:/CCCC/etc/roundcubemail:/var/log/roundcubemail";
                fastcgi_param HTTPS on;
                # Avoid sending the security headers twice
                fastcgi_param modHeadersAvailable true;
                fastcgi_param front_controller_active true;
                fastcgi_pass php-handler;
                fastcgi_intercept_errors on;
                fastcgi_request_buffering off;
        }
    }

然後,配置RoundCube的config目錄下config.inc.php文件,這個文件從config.inc.php.sample拷貝過來,進行修改

<?php

/* Local configuration for Roundcube Webmail */

// ----------------------------------
// SQL DATABASE
// ----------------------------------
// Database connection string (DSN) for read+write operations
// Format (compatible with PEAR MDB2): db_provider://user:password@host/database
// Currently supported db_providers: mysql, pgsql, sqlite, mssql, sqlsrv, oracle
// For examples see http://pear.php.net/manual/en/package.database.mdb2.intro-dsn.php
// Note: for SQLite use absolute path (Linux): 'sqlite:////full/path/to/sqlite.db?mode=0646'
//       or (Windows): 'sqlite:///C:/full/path/to/sqlite.db'
// Note: Various drivers support various additional arguments for connection,
//       for Mysql: key, cipher, cert, capath, ca, verify_server_cert,
//       for Postgres: application_name, sslmode, sslcert, sslkey, sslrootcert, sslcrl, sslcompression, service.
//       e.g. 'mysql://roundcube:@localhost/roundcubemail?verify_server_cert=false'
$config['db_dsnw'] = 'sqlite:////DDDDDDDDDDDDDDDDDDDDD/roundcubemail.db?mode=0646';

// IMAP host chosen to perform the log-in.
// See defaults.inc.php for the option description.
$config['imap_host'] = 'localhost:143';

// provide an URL where a user can get support for this Roundcube installation
// PLEASE DO NOT LINK TO THE ROUNDCUBE.NET WEBSITE HERE!
$config['support_url'] = '';

// This key is used to encrypt the users imap password which is stored
// in the session record. For the default cipher method it must be
// exactly 24 characters long.
// YOUR KEY MUST BE DIFFERENT THAN THE SAMPLE VALUE FOR SECURITY REASONS
$config['des_key'] = '.................................';

// Automatically add this domain to user names for login
// Only for IMAP servers that require full e-mail addresses for login
// Specify an array with 'host' => 'domain' values to support multiple hosts
// Supported replacement variables:
// %h - user's IMAP hostname
// %n - hostname ($_SERVER['SERVER_NAME'])
// %t - hostname without the first part
// %d - domain (http hostname $_SERVER['HTTP_HOST'] without the first part)
// %z - IMAP domain (IMAP hostname without the first part)
// For example %n = mail.domain.tld, %t = domain.tld
$config['username_domain'] = 'XXXXXXXXXX.cn';

// This domain will be used to form e-mail addresses of new users
// Specify an array with 'host' => 'domain' values to support multiple hosts
// Supported replacement variables:
// %h - user's IMAP hostname
// %n - http hostname ($_SERVER['SERVER_NAME'])
// %d - domain (http hostname without the first part)
// %z - IMAP domain (IMAP hostname without the first part)
// For example %n = mail.domain.tld, %t = domain.tld
$config['mail_domain'] = '%t';

// Absolute path to a local mime.types mapping table file.
// This is used to derive mime-types from the filename extension or vice versa.
// Such a file is usually part of the apache webserver. If you don't find a file named mime.types on your system,
// download it from http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
$config['mime_types'] = '/data/roundcubemail/config/mime.types';

// List of active plugins (in plugins/ directory)
$config['plugins'] = ['archive', 'zipdownload'];

#$config['smtp_host'] = 'localhost:25';
$config['smtp_port'] = 587;
$config['smtp_auth_type'] = 'LOGIN';

#$config['debug_level'] = 1;
#$config['smtp_debug'] = true;

再在瀏覽器端訪問XXXXXXXXXX.cn/webmail/installer,就可以檢查RoundCube配置是否正確了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章