在CentOS7上搭建屬於自己的“完美”郵件系統

連結:https://www.cnblogs.com/pgyLang/p/16113102.html

一、前言

為什麼要自己搭建郵件系統?

• 自從小學上資訊科技課接觸到電子郵件開始,我就對 @ 後面那幾個字母充滿了疑惑,為什麼 @ 後面的幾個字母一定要是 qq 、gmail 呢?難道不能自定義嗎?直到初三我弄懂了域名這個概念之後,這個謎團才被解開:我們用的是別人的伺服器來使用電子郵件服務。自己有域名當然也可以搭建一個啊!由於當時還基本上沒有云主機這種東西,而且家裡也不讓我整天開著電腦(電信有公網 IP ),所以該計劃暫時擱置。直到 2015 年,用 163 郵箱的 Apple ID 大規模被盜(很慶幸我逃過了一劫),我這才明白了自己有個郵箱伺服器那是多麼重要!恰好高考完了,可以折騰一番了。當時用的是傻瓜式的 macOS Server ,啥原理都不懂,點幾下就搭建成功了,就這樣湊合著用了一年,系統非常穩定,除了停電以及升級系統之外沒有重啟過(這裡贊一下 macOS Server )。macOS Server 最大的缺點就是可以自己定製的功能太少了!現在熟悉了 Linux 的基本操作和伺服器的基礎知識,是時候該在 Linux 平臺上搭建一個了!

• 其實,Linux 上也有傻瓜式郵件系統,iRedMail 就是其中之一。不過我玩 Linux 的目的就是為了學習伺服器以及網路知識,還是自己搭建一個才能學到東西。

郵件系統所涉及的模組較多,而且軟體又是不斷更新的,不同 Linux 發行版的系統環境和預設配置檔案也可能不相同,想只看一篇教程然後一次完美的機率太低了。我自己折騰了一個星期,中途也遇到過各種各樣的錯誤,不過好在最後都解決了。所以說,想要自己親手搭建一個完美的郵件系統,耐心是必不可少的。
我把我搭建的整個過程整理一下,步驟儘量精簡,然後寫下了這一篇文章,主要目的是想給大家分享下我的學習經驗,讓新手少走一點彎路,也能給自己增加點印象。所有的步驟(除了域名引數)我在寫完之後都有重灌系統然後全部重新走一遍驗證一次。如果想提高一次成功的機率,建議使用全新安裝的系統,然後嚴格按照我的步驟要求來做。如有錯誤,請及時留言提出,謝謝!

二、所需軟體 & 環境

  • 作業系統:CentOS 7.9 最小安裝 (已關閉 SELinux 和防火牆)
  • 應用軟體:Postfix 2.10.1 、Dovecot 2.2.10 、MariaDB 5.5.52 、OpenDKIM 2.11.0 、Nginx 1.10.2 、PHP 5.4.16 、Roundcube WebMail 1.3.0
  • 域名(主機名):example.com
  • 公網 IP:1.1.1.1
  • 二級域名mail(這裡就是 mail.example.com)的數字證書(推薦免費的 Let’s Encrypt)

說明

1、下文的 MySQL 均代表 MariaDB;

2、Nginx 和 PHP 不做詳細配置,只確保 Webmail 可以正常使用。

三、原理 & 關係圖

下面兩張圖足以說明一切:

說明

• SMTP 是 Postfix 發件的模組,SMTPD 是 Postfix 收件的模組,請注意區分。

四、安裝軟體

執行以下命令:

yum -y update && \
yum -y install epel-release && \
yum -y update && \
yum -y install dovecot dovecot-mysql mariadb-server nginx opendkim php-fpm php-mbstring php-mysql php-xml postfix pypolicyd-spf tar wget

若出現金鑰警告,按 y 回車即可。

五、配置 MySQL

5.1 初始化 MySQL

5.1.1 啟動服務

執行以下命令:

systemctl start mariadb

5.1.2 進行安全設定

執行以下命令:

mysql_secure_installation

然後根據提示操作:

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQL
SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!
In order to log into MySQL to secure it, we'll need the current
password for the root user. If you've just installed MySQL, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.
Enter current password for root (enter for none): # 回車即可
OK, successfully used password, moving on...
Setting the root password ensures that nobody can log into the MySQL
root user without the proper authorisation.
Set root password? [Y/n] y # 使用密碼驗證
New password: # 設定 root 密碼
Re-enter new password:
Password updated successfully!
Reloading privilege tables..
... Success!
# 後面的問題全部按 y 回車,這裡省略。

5.2 郵件系統資料庫的建立

注意

• SQL 語句後面要加上分號才能執行。

5.2.1 進入 MySQL 命令列介面

執行以下命令:

mysql -u root -p

然後輸入剛才設定的資料庫 Root 密碼然後按回車。
出現 MariaDB [(none)]> 指示符就說明進入了。

5.2.2 建立一個使用者用於讀取郵件系統資料庫

執行以下 SQL 語句:

CREATE USER 'mail_sys'@'localhost' IDENTIFIED BY 'mail_sys';

5.2.3 建立郵件系統資料庫

執行以下 SQL 語句:

CREATE DATABASE mail_sys;

說明

• 這裡的“郵件系統資料庫”並不儲存郵件,只用作域名、使用者、別名的驗證。郵件預設是儲存在 

/var/spool/mail 裡面的。

5.2.4 為使用者授予讀取許可權

執行以下 SQL 語句:

GRANT SELECT ON mail_sys.* TO 'mail_sys'@'localhost' IDENTIFIED BY 'mail_sys';

5.2.5 重新整理許可權

執行以下 SQL 語句:

FLUSH PRIVILEGES;

5.2.6 進入郵件系統資料庫

執行以下 SQL 語句:

USE mail_sys;

5.2.7 建立域名錶

執行以下 SQL 語句:

CREATE TABLE `domains` ( `id` int(20) NOT NULL auto_increment, `name` varchar(100) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

5.2.8 建立使用者表

執行以下 SQL 語句:

CREATE TABLE `users` ( `id` int(20) NOT NULL auto_increment, `domain_id` int(20) NOT NULL, `password` varchar(200) NOT NULL, `email` varchar(200) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`), FOREIGN KEY (domain_id) REFERENCES domains(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

5.2.9 建立別名表

執行以下 SQL 語句:

CREATE TABLE `aliases` ( `id` int(20) NOT NULL auto_increment, `domain_id` int(20) NOT NULL, `source` varchar(200) NOT NULL, `destination` varchar(200) NOT NULL, PRIMARY KEY (`id`), FOREIGN KEY (domain_id) REFERENCES domains(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

5.3 往郵件系統資料庫裡新增或刪除域名、使用者、別名

說明

1、為了方便以後新增或刪除,下面我把 SQL 語句(命令)的格式寫出來;

2、索引號從 1 開始依次遞增,需手動指定;

3、由於密碼需要使用 SQL 語句進行 SHA512 運算來儲存雜湊值,因此圖形化資料庫管理工具可能無法實現;

4、當新增多行資料時,非末行的行分隔符為逗號,直到末行才使用分號。

5.3.1 新增或刪除域名

新增域名

INSERT INTO `mail_sys`.`domains` (`id` ,`name`)
VALUES ('<域名索引號>', '<域名>');

例如:

MariaDB [mail_sys]> INSERT INTO `mail_sys`.`domains` (`id` ,`name`)
-> VALUES ('1', 'example.com');

刪除域名

DELETE FROM `mail_sys`.`domains` WHERE `id`='<域名索引號>';

5.3.2 新增或刪除使用者

新增使用者

INSERT INTO `mail_sys`.`users`
(`id`, `domain_id`, `password` , `email`) VALUES
('<使用者索引號>', '<域名索引號>', ENCRYPT('<密碼>', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), '<郵箱地址>'),
('<使用者索引號>', '<域名索引號>', ENCRYPT('<密碼>', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), '<郵箱地址>'),
('<使用者索引號>', '<域名索引號>', ENCRYPT('<密碼>', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), '<郵箱地址>');

例如:

MariaDB [mail_sys]> INSERT INTO `mail_sys`.`users`
-> (`id`, `domain_id`, `password` , `email`) VALUES
-> ('1', '1', ENCRYPT('12345678', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), '[email protected]'),
-> ('2', '1', ENCRYPT('password', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), '[email protected]'),
-> ('3', '1', ENCRYPT('11111111', CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))), '[email protected]');
#以後再繼續新增使用者名稱的時候,使用者索引就應該從4開始,下同。

刪除使用者

DELETE FROM `mail_sys`.`users` WHERE `id`='<使用者索引號>';

5.3.3 新增或刪除別名(可選)

說明

• 別名的意思就比如說:設定 

[email protected] 的別名是 [email protected] ,那麼其他人往 [email protected] 裡傳送郵件時,郵件就會到 [email protected] 的郵箱裡去。

新增別名

INSERT INTO `mail_sys`.`aliases`
(`id`, `domain_id`, `source`, `destination`) VALUES
('<別名索引號>', '<域名索引號>', '<別名地址>', '<目的地址>'),
('<別名索引號>', '<域名索引號>', '<別名地址>', '<目的地址>'),
('<別名索引號>', '<域名索引號>', '<別名地址>', '<目的地址>');

例如:

MariaDB [mail_sys]> INSERT INTO `mail_sys`.`aliases`
-> (`id`, `domain_id`, `source`, `destination`) VALUES

刪除別名

DELETE FROM `mail_sys`.`aliases` WHERE `id`='<別名索引號>';

5.4 檢查資料庫

5.4.1 檢查域名錶

執行以下 SQL 語句:

SELECT * FROM mail_sys.domains;

若出現以下格式的輸出結果,說明設定正確。

+----+-------------+
| id | name |
+----+-------------+
| 1 | example.com |
+----+-------------+
1 row in set (0.00 sec)

5.4.2 檢查使用者表

執行以下 SQL 語句:

SELECT * FROM mail_sys.users;

若出現以下格式的輸出結果,說明設定正確。

+----+-----------+------------------------------------------------------------------------------------------------------------+-------------------+
| id | domain_id | password | email |
+----+-----------+------------------------------------------------------------------------------------------------------------+-------------------+
| 1 | 1 | $6$afbdd821f68a3f27$QH9yDKslGZMNZjzvBBvMtYXzzclbnNgb1AhmB7lqu6fj6PU04QTgCTvcvPwqsAaW6mJt9kcKPicN0VCQGalg5/ | [email protected] |
| 2 | 1 | $6$a4f819161bd19901$oeDntXEyiY6RiM369ugKZrMfsK6yeV3CG/fhFF4ruPJImLCyzi2hR/PX8f2nBDBRWiMvWv7zWiNv5yEruRsW// | [email protected] |
| 3 | 1 | $6$2a85aaab0ec76f64$KRQ2H8Zgn0YjTzDDnfwqim3mZynZ05iPMZ1GQPw7GNuJApcXuLi5LOmR9yDC6Jh2eAKbhuG4lgHG.I5FdIrf4. | [email protected] |
+----+-----------+------------------------------------------------------------------------------------------------------------+-------------------+
3 rows in set (0.00 sec)

5.4.3 檢查別名表(可選)

執行以下 SQL 語句:

SELECT * FROM mail_sys.aliases;

若出現以下格式的輸出結果,說明設定正確。

+----+-----------+--------------------+-------------------+
| id | domain_id | source | destination |
+----+-----------+--------------------+-------------------+
+----+-----------+--------------------+-------------------+
3 rows in set (0.00 sec)

資料庫設定完成。按 Ctrl + D 退出 MySQL 命令列介面。

六、設定郵件系統專用使用者

說明

1、所有的郵件使用者都對映到系統的同一個真實的使用者上;

2、不建議直接使用系統自帶的 

mail 賬戶。

6.1 建立郵件系統專用組

執行以下命令:

groupadd -g 2000 mail_sys

6.2 建立郵件系統專用使用者

執行以下命令:

useradd -g mail_sys -u 2000 mail_sys -d /var/spool/mail -s /sbin/nologin

6.3 修改郵件目錄所有者

執行以下命令:

chown -R mail_sys:mail_sys /var/spool/mail

七、配置 Postfix

7.1 備份原版配置檔案

執行以下命令:

cp -r /etc/postfix /etc/postfix.bak

7.2 修改 main.cf

說明

• 該檔案配置 Postfix 的全域性引數。

執行以下命令:

cat > /etc/postfix/main.cf << EOF

請按實際情況以及註釋提示修改以下內容,完成後去除 # 號和後面的註釋,然後貼上到命令列視窗中按回車即可。

mydomain = example.com # 您的域名,需要修改
myhostname = mail.example.com # 您的域名前面加上 mail. 需要修改
mydestination = localhost
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mynetworks = 127.0.0.0/8
mailbox_size_limit = 0
recipient_delimiter = +
inet_protocols = all
inet_interfaces = all
smtp_address_preference = ipv4
smtpd_banner = ESMTP
biff = no
append_dot_mydomain = no
readme_directory = no
virtual_transport = lmtp:unix:private/dovecot-lmtp
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
virtual_mailbox_domains = mysql:/etc/postfix/mysql_mailbox_domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql_mailbox_maps.cf
virtual_alias_maps = mysql:/etc/postfix/mysql_alias_maps.cf
smtpd_sender_login_maps = mysql:/etc/postfix/mysql_mailbox_maps.cf, mysql:/etc/postfix/mysql_alias_maps.cf
disable_vrfy_command = yes
strict_rfc821_envelopes = yes
smtpd_sender_restrictions = reject_non_fqdn_sender, reject_unknown_sender_domain, reject_sender_login_mismatch
smtpd_recipient_restrictions = reject_non_fqdn_recipient, reject_unknown_recipient_domain, permit_sasl_authenticated, reject_unauth_destination, check_policy_service unix:private/policyd-spf
virtual_uid_maps = static:2000
virtual_gid_maps = static:2000
message_size_limit = 102400000
smtpd_tls_security_level = may
smtp_tls_security_level = may
smtpd_tls_cert_file=/etc/pki/tls/certs/cert.pem # mail.example.com 證書檔案位置,需要修改
smtpd_tls_key_file=/etc/pki/tls/private/key.pem # mail.example.com 證書私鑰檔案位置,需要修改
smtpd_tls_session_cache_database = btree:\${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:\${data_directory}/smtp_scache
smtpd_tls_protocols = TLSv1.2, TLSv1.1, !TLSv1, !SSLv2, !SSLv3
smtp_tls_protocols = TLSv1.2, TLSv1.1, !TLSv1, !SSLv2, !SSLv3
smtp_tls_ciphers = high
smtpd_tls_ciphers = high
smtpd_tls_mandatory_protocols = TLSv1.2, TLSv1.1, !TLSv1, !SSLv2, !SSLv3
smtp_tls_mandatory_protocols = TLSv1.2, TLSv1.1, !TLSv1, !SSLv2, !SSLv3
smtp_tls_mandatory_ciphers = high
smtpd_tls_mandatory_ciphers = high
smtpd_tls_mandatory_exclude_ciphers = MD5, DES, ADH, RC4, PSD, SRP, 3DES, eNULL, aNULL
smtpd_tls_exclude_ciphers = MD5, DES, ADH, RC4, PSD, SRP, 3DES, eNULL, aNULL
smtp_tls_mandatory_exclude_ciphers = MD5, DES, ADH, RC4, PSD, SRP, 3DES, eNULL, aNULL
smtp_tls_exclude_ciphers = MD5, DES, ADH, RC4, PSD, SRP, 3DES, eNULL, aNULL
tls_preempt_cipherlist = yes
smtpd_tls_received_header = yes
policyd-spf_time_limit = 3600
EOF

7.3 修改 master.cf

說明

• 該檔案配置 Postfix 中各模組的引數。

執行以下命令:

cat > /etc/postfix/master.cf << EOF

以下內容直接貼上到命令列視窗中按回車即可。

smtp inet n - n - - smtpd
submission inet n - n - - smtpd
-o smtpd_tls_security_level=encrypt
smtps inet n - n - - smtpd
-o smtpd_tls_wrappermode=yes
pickup unix n - n 60 1 pickup
cleanup unix n - n - 0 cleanup
qmgr unix n - n 300 1 qmgr
tlsmgr unix - - n 1000? 1 tlsmgr
rewrite unix - - n - - trivial-rewrite
bounce unix - - n - 0 bounce
defer unix - - n - 0 bounce
trace unix - - n - 0 bounce
verify unix - - n - 1 verify
flush unix n - n 1000? 0 flush
proxymap unix - - n - - proxymap
proxywrite unix - - n - 1 proxymap
smtp unix - - n - - smtp
relay unix - - n - - smtp
-o smtp_helo_timeout=120 -o smtp_connect_timeout=120
showq unix n - n - - showq
error unix - - n - - error
retry unix - - n - - error
discard unix - - n - - discard
local unix - n n - - local
virtual unix - n n - - virtual
lmtp unix - - n - - lmtp
anvil unix - - n - 1 anvil
scache unix - - n - 1 scache
policyd-spf unix - n n - 0 spawn
user=mail_sys argv=/usr/libexec/postfix/policyd-spf
EOF

7.4 與 MySQL 對接

7.4.1 指定域名資料表

執行以下命令:

cat > /etc/postfix/mysql_mailbox_domains.cf << EOF

以下內容直接貼上到命令列視窗中按回車即可。

user = mail_sys
password = mail_sys
hosts = localhost
dbname = mail_sys
query = SELECT 1 FROM domains WHERE name='%s'
EOF

7.4.2 指定使用者資料表

執行以下命令:

cat > /etc/postfix/mysql_mailbox_maps.cf << EOF

以下內容直接貼上到命令列視窗中按回車即可。

user = mail_sys
password = mail_sys
hosts = localhost
dbname = mail_sys
query = SELECT email FROM users WHERE email='%s'
EOF

7.4.3 指定別名資料表

執行以下命令:

cat > /etc/postfix/mysql_alias_maps.cf << EOF

以下內容直接貼上到命令列視窗中按回車即可。

user = mail_sys
password = mail_sys
hosts = localhost
dbname = mail_sys
query = SELECT destination FROM aliases WHERE source='%s'
EOF

7.5 測試資料庫讀取

7.5.1 啟動 Postfix 服務

執行以下命令:

systemctl start postfix

7.5.2 測試域名資料表的讀取

下面的 example.com 請替換為自己設定的域名。
執行以下命令:

postmap -q example.com mysql:/etc/postfix/mysql_mailbox_domains.cf

若返回 1,則說明設定正確。

7.5.3 測試使用者資料表的讀取

下面的 [email protected] 請替換為自己設定的使用者名稱的其中一個。
執行以下命令:

postmap -q [email protected] mysql:/etc/postfix/mysql_mailbox_maps.cf

若返回使用者名稱,則說明設定正確。

7.5.4 測試別名資料表的讀取(可選)

下面的 [email protected] 請替換為自己設定的別名其中一個。
執行以下命令:

postmap -q [email protected] mysql:/etc/postfix/mysql_alias_maps.cf

若返回別名所對應的真實使用者名稱,則說明設定正確。

7.5.5 停止 Postfix 服務

等全部配置完成後再啟動。
執行以下命令:

systemctl stop postfix

八、配置 Dovecot

8.1 備份原版配置檔案

執行以下命令:

cp -r /etc/dovecot /etc/dovecot.bak

8.2 修改 dovecot.conf

說明

• 該檔案配置 Dovecot 的全域性引數。

執行以下命令:

cat > /etc/dovecot/dovecot.conf << EOF

以下內容直接貼上到命令列視窗中按回車即可。

protocols = imap lmtp
dict {
}
!include conf.d/*.conf
!include_try local.conf
EOF

8.3 修改 conf.d/10-mail.conf

說明

• 該檔案配置郵箱檔案儲存的位置和名稱空間。

執行以下命令:

cat > /etc/dovecot/conf.d/10-mail.conf << EOF

以下內容直接貼上到命令列視窗中按回車即可。

namespace inbox {
inbox = yes
}
first_valid_uid = 1000
mbox_write_locks = fcntl
mail_location = maildir:/var/spool/mail/%d/%n
mail_privileged_group = mail
EOF

8.4 修改 conf.d/15-mailboxes.conf

說明

• 該檔案配置郵箱內部的目錄結構。

執行以下命令:

cat > /etc/dovecot/conf.d/15-mailboxes.conf << EOF

以下內容直接貼上到命令列視窗中按回車即可。

namespace inbox {
mailbox Drafts {
auto = create
special_use = \Drafts
}
mailbox Trash {
auto = create
special_use = \Trash
}
mailbox Sent {
auto = create
special_use = \Sent
}
}
EOF

8.5 修改 conf.d/10-auth.conf

說明

• 該檔案配置使用者身份認證流程。

執行以下命令:

cat > /etc/dovecot/conf.d/10-auth.conf << EOF

以下內容直接貼上到命令列視窗中按回車即可。

auth_mechanisms = plain login
!include auth-sql.conf.ext
EOF

8.6 修改 conf.d/auth-sql.conf.ext

說明

• 該檔案配置資料庫認證的引數。

執行以下命令:

cat > /etc/dovecot/conf.d/auth-sql.conf.ext << EOF

以下內容直接貼上到命令列視窗中按回車即可。

passdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
driver = static
args = uid=mail_sys gid=mail_sys home=/var/spool/mail/%d/%n
}
EOF

8.7 修改 dovecot-sql.conf.ext

說明

• 該檔案配置驗證使用者名稱密碼所用的資料表以及認證方法。

執行以下命令:

cat > /etc/dovecot/dovecot-sql.conf.ext << EOF

以下內容直接貼上到命令列視窗中按回車即可。

driver = mysql
connect = host=localhost dbname=mail_sys user=mail_sys password=mail_sys
default_pass_scheme = SHA512-CRYPT
password_query = SELECT email as user, password FROM users WHERE email='%u';
EOF

8.8 修改 conf.d/10-ssl.conf

說明

• 該檔案配置 SSL 加密引數。

執行以下命令:

cat > /etc/dovecot/conf.d/10-ssl.conf << EOF

請按實際情況以及註釋提示修改以下內容,完成後去除 # 號和後面的註釋,然後貼上到命令列視窗中按回車即可。

ssl = required
ssl_cert = </etc/pki/tls/certs/cert.pem # mail.example.com 證書檔案位置,需要修改
ssl_key = </etc/pki/tls/private/key.pem # mail.example.com 證書私鑰檔案位置,需要修改
ssl_protocols = TLSv1.2 TLSv1.1 !TLSv1 !SSLv2 !SSLv3
ssl_cipher_list = ALL:!MD5:!DES:!ADH:!RC4:!PSD:!SRP:!3DES:!eNULL:!aNULL
EOF

8.9 修改 conf.d/10-master.conf

說明

• 該檔案配置 Dovecot 中各服務的主要引數。

執行以下命令:

cat > /etc/dovecot/conf.d/10-master.conf << EOF

以下內容直接貼上到命令列視窗中按回車即可。

service imap-login {
inet_listener imap {
port = 143
}
inet_listener imaps {
port = 993
ssl = yes
}
}
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600
user = postfix
group = postfix
}
}
service imap {
}
service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0666
user = postfix
group = postfix
}
unix_listener auth-userdb {
mode = 0600
user = mail_sys
}
user = dovecot
}
service auth-worker {
user = mail_sys
}
EOF

8.10 修改 conf.d/15-lda.conf

說明

1、該檔案配置特定域的 postmaster 郵箱;

2、我自己沒有修改這個配置檔案。但是根據部分網友反饋,如果不設定 postmaster 郵箱的話會導致收不到郵件,所以還是加上去吧。

執行以下命令:

cat > /etc/dovecot/conf.d/15-lda.conf << EOF

以下內容直接貼上到命令列視窗中按回車即可。

postmaster_address = postmaster@%d
protocol lda {
}
EOF

九、配置 OpenDKIM

9.1 修改 OpenDKIM 配置檔案

執行以下命令:

cat > /etc/opendkim.conf << EOF

請按實際情況以及註釋提示修改以下內容,完成後去除 # 號和後面的註釋,然後貼上到命令列視窗中按回車即可。

Syslog yes
UMask 002
OversignHeaders From
Socket inet:[email protected]
Domain example.com # 您的域名,需要修改
KeyFile /etc/opendkim/keys/mail.private
Selector mail
RequireSafeKeys no
EOF

9.2 生成私鑰

下面的 example.com 請替換成您的域名。
執行以下命令:

opendkim-genkey -D /etc/opendkim/keys/ -d example.com -s mail && \
chown -R opendkim:opendkim /etc/opendkim/keys/

9.3 配置 Postfix 的 main.cf

配置發件增加 DKIM 簽名。
執行以下命令:

cat >> /etc/postfix/main.cf << EOF

以下內容直接貼上到命令列視窗中按回車即可。

milter_protocol = 2
milter_default_action = accept
smtpd_milters = inet:127.0.0.1:8891
non_smtpd_milters = inet:127.0.0.1:8891
EOF

9.4 啟動所有服務

執行以下命令:

systemctl start postfix dovecot opendkim

如需開機啟動,請執行以下命令:

systemctl enable postfix dovecot opendkim mariadb

十、配置域名記錄

以下專案需要在域名服務商或雲主機服務商的控制面板中設定。下文的域名服務商以 DNSPOD 為例,其他域名服務商或雲主機服務商請自行參閱相關說明文件。

10.1 A 記錄的設定

在域名控制面板中新增一條記錄,主機記錄填 @ ,記錄型別選 A 記錄值填 1.1.1.1 ,其他保持預設,儲存即可。

10.2 MX 記錄的設定

在域名控制面板中新增一條記錄,主機記錄填 @ ,記錄型別選 MX ,記錄值填 mail.example.com

,其他保持預設;

再新增一條記錄,主機記錄填 

mail ,記錄型別選 A ,記錄值填 1.1.1.1,其他保持預設,儲存即可。

10.3 SPF 記錄的設定

在域名控制面板中新增一條記錄,主機記錄填 @ ,記錄型別選 TXT ,記錄值填 v=spf1 mx -all,其他保持預設,儲存即可。

10.4 DMARC 記錄的設定

在域名控制面板中新增一條記錄,主機記錄填 _dmarc ,記錄型別選 TXT ,記錄值填 v=DMARC1; p=reject,其他保持預設,儲存即可。

10.5 DKIM 記錄的設定

(以我的金鑰檔案為例)
執行以下命令:

cat /etc/opendkim/keys/mail.txt

會出現以下結果:

mail._domainkey IN TXT ( "v=DKIM1; k=rsa; "
"p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDU5nkxbS36hOa2FCJqotvahTbxb83CvLt5XqV4WAPzJQmfaA1eHyvOz9XiZgE8vWRgP2jJFlL+J4yEroB3YV/8EBjAM8lFTi31DVgRsoHMwH6f3GuLAfcuVofymDfRxHxPzIlm7rgzfWwrGcPrIzt64NLuZG4yusTWp8MTfWZxvQIDAQAB" ) ; ----- DKIM key default for example.com

把括號內的值複製出來,去掉所有引號並整理成一行,形如:

v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDU5nkxbS36hOa2FCJqotvahTbxb83CvLt5XqV4WAPzJQmfaA1eHyvOz9XiZgE8vWRgP2jJFlL+J4yEroB3YV/8EBjAM8lFTi31DVgRsoHMwH6f3GuLAfcuVofymDfRxHxPzIlm7rgzfWwrGcPrIzt64NLuZG4yusTWp8MTfWZxvQIDAQAB

在域名控制面板中新增一條記錄,主機記錄填 mail._domainkey ,記錄型別選 TXT ,記錄值填 v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDU5nkxbS36hOa2FCJqotvahTbxb83CvLt5XqV4WAPzJQmfaA1eHyvOz9XiZgE8vWRgP2jJFlL+J4yEroB3YV/8EBjAM8lFTi31DVgRsoHMwH6f3GuLAfcuVofymDfRxHxPzIlm7rgzfWwrGcPrIzt64NLuZG4yusTWp8MTfWZxvQIDAQAB ,其他保持預設,儲存即可。
上述五個步驟完成後域名控制面板的效果如下圖:

10.6 IP 反向解析

這個……普通家庭寬頻使用者就別想了,企業寬頻和國內雲主機使用者需要網站透過備案才能設定。如果用國外雲主機的話,有些可以支援(我使用的 Vultr 支援)。將伺服器的 IP 地址反向解析(PTR 記錄)到 MX 域名(這裡就是 mail.example.com)可以大幅降低外發郵件被拒收的機率。

十一、配置 Web 郵箱

11.1 下載並安裝 Roundcube

11.1.1 下載

執行以下命令:

wget https://github.com/roundcube/roundcubemail/releases/download/1.3.0/roundcubemail-1.3.0-complete.tar.gz

11.1.2 解壓 & 安裝

執行以下命令:

tar -xf roundcubemail-1.3.0-complete.tar.gz && \
mv roundcubemail-1.3.0 /usr/share/roundcube && \
chown -R apache:apache /usr/share/roundcube

11.2 配置 Nginx 、PHP

11.2.1 配置 Nginx

執行以下命令:

vi /etc/nginx/conf.d/mail.conf

請按實際情況以及註釋提示修改以下內容,在命令列視窗按下 i ,將內容直接貼上到命令列視窗中,再按下 ESC ,最後輸入 :wq 按回車。

server {
listen 80;
server_name mail.example.com; # 您的域名前面加上 mail. 需要修改
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name mail.example.com; # 您的域名前面加上 mail. 需要修改
ssl_certificate "/etc/pki/tls/certs/cert.pem"; # mail.example.com 證書檔案位置,需要修改
ssl_certificate_key "/etc/pki/tls/private/key.pem"; # mail.example.com 證書私鑰檔案位置,需要修改
add_header Strict-Transport-Security "max-age=15552000; includeSubDomains";
location / {
root /usr/share/roundcube;
index index.php;
}
location ~ .php$ {
root /usr/share/roundcube;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}

11.2.2 配置 PHP

設定時區
執行以下命令:

echo "date.timezone = Asia/Shanghai" >> /etc/php.ini

建立會話資料夾
執行以下命令:

mkdir /var/lib/php/session && \
chown apache:apache /var/lib/php/session

11.3 配置資料庫

11.3.1 進入 MySQL 命令列介面

執行以下命令:

mysql -u root -p

然後輸入 5.1.2 設定的資料庫 Root 密碼然後按回車。
出現 MariaDB [(none)]> 指示符就說明進入了。

11.3.2 建立一個使用者用於讀寫 Roundcube 資料庫

執行以下 SQL 語句:

CREATE USER 'roundcube'@'localhost' IDENTIFIED BY 'roundcube';

11.3.3 建立 Roundcube 資料庫

執行以下 SQL 語句:

CREATE DATABASE roundcube;

11.3.4 為使用者授予讀寫許可權

執行以下 SQL 語句:

GRANT ALL ON roundcube.* TO 'roundcube'@'localhost' IDENTIFIED BY 'roundcube';

11.3.5 重新整理許可權

執行以下 SQL 語句:

FLUSH PRIVILEGES;

資料庫設定完成。按 Ctrl + D 退出 MySQL 命令列介面。

11.4 啟動服務

執行以下命令:

systemctl start nginx php-fpm

如需開機啟動,請執行以下命令:

systemctl enable nginx php-fpm

11.5 配置 Roundcube

開啟瀏覽器,輸入 https://mail.example.com/installer/?_step=1 ,回車開啟。然後按圖片提示進行配置。

配置完成後,關閉瀏覽器頁面。執行以下命令來使安裝程式不可用:

chmod -R 000 /usr/share/roundcube/installer/

11.6 登入

開啟瀏覽器,輸入 https://mail.example.com ,然後輸入您的使用者名稱密碼登入。

登入之後,預設只會有一個收件箱,我們再設定一下就完美了!

最終效果如下圖:

十二、收發件測試

12.1 收件測試

非常簡單,從 QQ 或者 Gmail 給自己的郵箱發一封郵件,如果可以收到,說明外網已經可以連通這臺伺服器了。

12.2 發件測試

開啟瀏覽器,輸入 http://www.mail-tester.com ,回車開啟。發一封郵件到它指定的郵箱裡。然後過一分鐘左右檢視下結果,重點檢查 SPF 記錄、DMARC 記錄和 DKIM 簽名是不是有效的。如果都是有效的,那恭喜您!您的郵件系統已經搭建完了!至於這個得分,由於受 IP 地址可能被拉黑的影響,因此各人的分數有可能不同。如果有 8 分以上的話發出去的郵件基本上就不會被拒收了。如果很不幸 IP 地址被拉黑了,建議換一個 IP 地址。

十三、防火牆的設定(可選)

如果伺服器需要部署防火牆,請放行 TCP 25TCP 465TCP 587 以及 TCP 993 這四個埠的傳入連結。
以 iptables 為例,配置命令為:

iptables -A INPUT -p tcp -m multiport --dports 25,465,587,993 -j ACCEPT

然後根據需要自行儲存防火牆的配置。

十四、不完美的地方 & 總結

  • 之所以標題上的完美打了個雙引號,原因之一是本來我計劃配置垃圾郵件過濾功能的,但是不知道是不是我設定錯誤還是網路問題,很多非垃圾郵件都被拒收了,在網上搜索了兩天還是無解,所以暫時放棄。(PS :幾個月前我用過一次 iRedMail ,裡面的垃圾郵件過濾模組也同樣導致很多非垃圾郵件被拒收,所以我感覺網路問題大一些。)
  • 此外,這個郵件系統並沒有實現使用 Web 介面管理郵件系統(如增減使用者)的功能,由於我搭建的郵件系統只有我一個人在用,所以也就不折騰啦。
  • 最後非常感謝能夠耐心讀完這篇文章的人,希望您有所收穫!
END
官方站點:www.linuxprobe.com
Linux命令大全:www.linuxcool.com
劉遄老師QQ:5604215
Linux技術交流群:2636170
(新群,火熱加群中……)
想要學習Linux系統的讀者可以點選"閱讀原文"按鈕來了解書籍《Linux就該這麼學》,同時也非常適合專業的運維人員閱讀,成為輔助您工作的高價值工具書!


相關文章