2026年openSUSE15.6:postfix-dovecot-mariadb-搭建邮件服务器-最新指南

openSUSE15.6: postfix-dovecot-mariadb-搭建邮件服务器

标题是“指南”,纯粹是为了SEO,博主水平有限,不足之处,希望网友们批评指正。

背景

我在AWS购买一台配置为2C2G的lightsail轻型VPS云主机,由于工作繁忙,一直闲置。
恰逢26年春节假期,一下子有了大量空闲时间,本着物尽其用的原则,决定搭建邮件服务器。
这事儿如果成了,以后就拥有独家域名的邮箱,自己用起来随心所欲,还能分享给亲戚朋友,岂不美哉?

但说起来容易,做起来煞费周折。

一个原因是docker技术的普及,很多邮件方案均已打包成镜像,使用起来简单、方便。
另外一个原因,postfix系列软件安装、配置繁琐,还涉及域名解析及邮件服务专用的潜规则,对于普通人,有一定难度。

现在大部分云计算厂商封禁25端口,历尽千辛,服务搭建完成后,你大概率会卡在这一步。
博主的解决方案是,使用”AWS Simple Email Service(SES)”邮件代理,只需要在postfix添加配置即可。

在搭建过程中,大量依赖deepseekchatGPT, 感谢强大的人工智能技术~!

当然,如果把VPS当作玩具,折腾起来乐在其中,是不错的消磨时间的方式。

邮件服务搭建方案

Postfix是什么?

Postfix是 MTA(Mail Transfer Agent),负责发信和收信传输。

它干的事:

  • 接收外部服务器发来的邮件
  • 把邮件转发到目标服务器
  • 发送你服务器用户发出的邮件
  • 跟别的邮件服务器SMTP通信

它只负责“传输”。

Dovecot是什么?

Dovecot是MDA+IMAP/POP3 Server , 负责“存储”和“让用户读取”。

它干的事:

  • 管理邮箱目录(Maildir)
  • 提供IMAP/POP3给客户端
  • 负责用户认证
  • 可提供SASL认证给Postfix使用

它只负责“用户访问”。

完整邮件流程(从外部发到你)

假设别人给你发邮件
1
Gmail -> 你的服务器

流程:

  1. 对方SMTP连接到你的服务器25端口
  2. Postfix接收邮件
  3. Postfix把邮件投递到本地邮箱目录
  4. Dovecot读取该目录
  5. Outlook/手机等使用IMAP协议连接Dovecot读取邮件

流程图:

1
2
3
4
5
6
7
8
9
外部服务器
↓ 25
Postfix

Maildir

Dovecot
↑ 993
Outlook
从你发邮件到外部
1
Outlook -> 你的服务器 -> Gmail

流程:

  1. Outlook连接587端口
  2. Dovecot提供SASL认证
  3. Postfix验证用户名和密码
  4. Postfix把邮件发给目标MX

流程图:

1
2
3
4
5
6
7
Outlook
↓ 587
Dovecot → mariadb
↓ ↑验证密码
Postfix
↓ 25
目标服务器
二者如何配合?

核心协作点在:

SASL认证

Postfix自己不掌管密码。

它通常使用:

1
2
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth

代表

Postfix把认证交给Dovecot

所以:

  • Dovecot = 账户系统
  • Postfix = 传输系统

邮件存储目录

默认情况下,Postfix投递到

1
/home/user/Maildir/

Dovecot读取同一个目录,二者共享存储。

必须开放的端口
  • 25 - SMTP收信(服务器与服务器之间通信) - 必须
  • 587 - SMTP提交(客户端提交邮件,必须开启认证) - 建议
  • 993 - IMAPS(客户端收邮件,加密) - 必须
可选端口
  • 465 - SMTPS(旧标准)
  • 110 - POP3
  • 995 - POP3S
  • 142 - IMAP明文
生产级端口策略
1
2
3
4
5
# 仅开放以下,其他全部关闭。

25
587
993

软件版本

  • postfix-3.8.4-150600.3.3.1.x86_64
  • dovecot23-2.3.15-150200.65.1.x86_64
  • mariadb-10.11.15-150600.4.17.1.x86_64

使用zypper命令安装,上面是主要组件的版本号,其他组件不再展示。

搭建过程

准备工作

  • 一台具有IPv4地址的vps云主机(至少1C1G,性能够用)
  • 一个拥有完全解析权限的国际域名。
    以上,建议均在国外运营商购买,国内要求域名备案等,相对繁琐。
  • deepseek/chatGPT,提供专家咨询。
  • 一个自行注册、可以登录的gmail邮箱,后期用作收件测试和排障。

操作系统(openSUSE Leap 15.6)

为什么使用openSUSE ?

博主具备5年以上”SUSE Linux Enterprise Server (SLES)”生产一线使用经验,不论硬件服务器(戴尔)系统安装,还是应用搭建维护,都非常熟悉。
个人认为,SuSE系统是除Redhat系列外,最稳定、易用的发行版,非常省心。

Server就绪后,第一步,应该执行系统级安全加固和配置优化,可以问deepseek,此处略过。

系统更新

1
2
3
4
5
6
# 更新系统
sudo zypper refresh
sudo zypper update

# 重启(必须)
sudo reboot

软件安装

安装基础组件

1
2
3
4
5
6
7
8
9
10
# 安装主要组件和中间依赖
zypper install postfix postfix-mysql mariadb-server mariadb dovecot dovecot-mysql cyrus-sasl cyrus-sasl-plain

# 如果不想安装冗余,可以添加 "--no-recommends" 参数。
zypper install --no-recommends postfix postfix-mysql mariadb-server mariadb dovecot dovecot-mysql cyrus-sasl cyrus-sasl-plain

# 设置开机自启动
systemctl enable --now mariadb
systemctl enable --now postfix
systemctl enable --now dovecot

基础软件安装好后,会同时向系统添加用户和用户组,检查/etc/passwd和/etc/group,发现新增”opendkim”, “unbound”, “maildrop”, “vmail”, “postfix”, “dovecot”等,后续安装会涉及,最好检查一下。

配置Mysql

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 配置mysql数据库
# 执行后,按照提示,一步一步操作。
# 删除匿名账户和测试数据库,为root设置密码,同时禁用root远程登录。
mysql_secure_installation

-- 创建数据库
CREATE DATABASE mailserver;
USE mailserver;

-- 创建虚拟域表
CREATE TABLE virtual_domains (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL UNIQUE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 创建虚拟用户表
CREATE TABLE virtual_users (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
domain_id INT NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE,
password VARCHAR(106) NOT NULL, -- 存储加密后的密码
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 创建别名表
CREATE TABLE virtual_aliases (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
domain_id INT NOT NULL,
source VARCHAR(100) NOT NULL,
destination VARCHAR(100) NOT NULL,
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 创建数据库用户并授权
CREATE USER 'mailuser'@'localhost' IDENTIFIED BY 'your_password';
-- 注意,这里是赋查询权限,下一步添加用户时,要使用root登录,操作这张表。
GRANT SELECT ON mailserver.* TO 'mailuser'@'localhost';
FLUSH PRIVILEGES;

Let’s Encrypt证书

安装过程中,Let’s Encrypt 的服务器访问到当前服务器上的临时验证文件
所以需要:

  • 开放80端口
  • 安装nginx
  • 配置域名解析,为申请证书的域名,创建一个A记录解析,指向当前服务器的IP

安装证书申请工具

1
2
3
4
5
#安装 Certbot 和 Nginx 插件(Nginx用于验证域名所有权)
sudo zypper install nginx certbot python3-certbot-nginx

#运行 Certbot 获取证书(替换为你的真实域名)
sudo certbot certonly --nginx -d mail.example.com

使用独立目录存放证书

1
2
3
4
5
6
7
8
9
#使用独立目录存放证书
sudo mkdir /etc/postfix/certs
sudo cp /etc/letsencrypt/live/mail.wisepkg.com/fullchain.pem /etc/postfix/certs/
sudo cp /etc/letsencrypt/live/mail.wisepkg.com/privkey.pem /etc/postfix/certs/

#设置权限
sudo chown root:postfix /etc/postfix/certs/privkey.pem
sudo chmod 640 /etc/postfix/certs/privkey.pem
sudo chmod 644 /etc/postfix/certs/fullchain.pem

配置定时任务

1
2
3
4
# 编辑root用户的crontab
sudo crontab -e
# 添加以下行(假设Certbot的续期路径正确)
0 0,12 * * * certbot renew --deploy-hook "cp /etc/letsencrypt/live/mail.wisepkg.com/*.pem /etc/postfix/certs/ && systemctl reload postfix"

配置postfix

文件备份

1
cp /etc/postfix/main.cf /etc/postfix/main.cf.backup

注意: /etc/postfix/main.cf.default, 这是配置模板,如果必须的参数在main.cf没有找到,会从该模板文件读取。

main.cf(适用于使用AWS SES服务做发送代理)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
############################
# 基础身份,保留原配置
############################

compatibility_level = 3.8
queue_directory = /var/spool/postfix
command_directory = /usr/sbin
daemon_directory = /usr/lib/postfix/bin/
data_directory = /var/lib/postfix
mail_owner = postfix
sendmail_path = /usr/sbin/sendmail
newaliases_path = /usr/bin/newaliases
mailq_path = /usr/bin/mailq
setgid_group = maildrop
html_directory = /usr/share/doc/packages/postfix-doc/html
manpage_directory = /usr/share/man
sample_directory = /usr/share/doc/packages/postfix-doc/samples
readme_directory = /usr/share/doc/packages/postfix-doc/README_FILES
biff = no

# 替换为你的域名
myhostname = mail.example.com
mydomain = example.com
myorigin = $mydomain

inet_interfaces = all
inet_protocols = ipv4

mydestination = $myhostname, localhost.$mydomain, localhost

mynetworks = 127.0.0.0/8 [::1]/128

unknown_local_recipient_reject_code = 550
recipient_delimiter = +

############################
# SMTP 安全限制
############################

smtpd_banner = $myhostname ESMTP
default_destination_concurrency_limit = 20
smtpd_recipient_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_unauth_destination

smtpd_sender_restrictions =
reject_non_fqdn_sender
reject_unknown_sender_domain

smtpd_relay_restrictions =
permit_mynetworks
permit_sasl_authenticated
reject_unauth_destination

smtpd_helo_required = yes
disable_vrfy_command = yes
smtpd_forbid_bare_newline = yes
smtpd_forbid_bare_newline_exclusions = $mynetworks

############################
# SASL (Dovecot)
############################

smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_tls_security_options = noanonymous

############################
# TLS - 服务端
############################

smtpd_use_tls = yes
smtpd_tls_cert_file = /etc/postfix/certs/fullchain.pem
smtpd_tls_key_file = /etc/postfix/certs/privkey.pem

smtpd_tls_security_level = may
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1

smtpd_tls_ciphers = medium
smtpd_tls_mandatory_ciphers = medium
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache

############################
# TLS - 客户端 (发往 SES)
############################

smtp_tls_security_level = encrypt
smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_ciphers = medium
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtp_tls_note_starttls_offer = yes

############################
# SES Relay 配置
# AWS封禁25端口,使用AWS SES邮件投递代理服务
############################

relayhost = [email-smtp.ap-southeast-1.amazonaws.com]:587

smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = texthash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_sasl_mechanism_filter = plain,login

############################
# 虚拟邮箱 + LMTP
############################

virtual_mailbox_domains = mysql:/etc/postfix/mysql-virtual-mailbox-domains.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql-virtual-mailbox-maps.cf
virtual_alias_maps =
mysql:/etc/postfix/mysql-virtual-alias-maps.cf,
mysql:/etc/postfix/mysql-virtual-email2email.cf

virtual_mailbox_base = /var/mail/vhosts
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
virtual_minimum_uid = 1000
virtual_mailbox_limit = 1073741824

virtual_transport = lmtp:unix:private/dovecot-lmtp

############################
# 邮件大小限制
############################

message_size_limit = 20971520
mailbox_size_limit = 0

############################
# 别名
############################

alias_maps = lmdb:/etc/aliases
alias_database = lmdb:/etc/aliases

############################
# 打印日志
############################
smtpd_tls_loglevel = 2

############################
# 其他继续保留
############################
delay_warning_time = 1h
masquerade_classes = envelope_sender, header_sender, header_recipient
masquerade_exceptions = root
canonical_maps = lmdb:/etc/postfix/canonical
relocated_maps = lmdb:/etc/postfix/relocated
sender_canonical_maps = lmdb:/etc/postfix/sender_canonical
transport_maps = lmdb:/etc/postfix/transport
mail_spool_directory = /var/mail
message_strip_characters = \0

master.cf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
smtp      inet  n       -       n       -       -       smtpd
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
-o smtpd_tls_auth_only=yes
-o smtpd_reject_unlisted_recipient=no
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
-o milter_macro_daemon_name=ORIGINATING
-o smtpd_client_connection_count_limit=10
-o smtpd_client_connection_rate_limit=20

pickup fifo n - n 60 1 pickup
cleanup unix n - n - 0 cleanup
qmgr fifo n - n 300 1 qmgr
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 syslog_name=postfix/$service_name
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
tlsmgr unix - - n 1000? 1 tlsmgr
postlog unix-dgram n - n - 1 postlogd
dovecot unix - n n - - pipe
flags=DRhu user=vmail:vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${recipient}

重启postfix服务

1
systemctl restart postfix

检查postfix配置

1
postfix check

查看所有配置项

1
postconf -n

验证25端口证书读取

1
2
3
4
5
# 服务端
openssl s_client -connect localhost:25 -starttls smtp -showcerts

# 客户端
openssl s_client -connect mail.example.com:587 -starttls smtp

查看postfix日志

1
journalctl -u postfix -f

上面的main.cf是使用了AWS Simple Email Service邮件代理,在开放25端口的场景下,让chatGPT重新整理了一份配置。
当然,这种场景下,DNS涉及A记录/PTR/SPF/DKIM/DMARC的配置也会发生改变。

main.cf(仅供参考)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# 基础身份
myhostname = mail.yourdomain.com
mydomain = yourdomain.com
myorigin = $mydomain

inet_interfaces = all
inet_protocols = ipv4

# 域设置
mydestination = $myhostname, localhost.$mydomain, localhost
virtual_mailbox_domains = yourdomain.com
virtual_transport = lmtp:unix:private/dovecot-lmtp

# 网络信任
mynetworks = 127.0.0.0/8

# 严格禁止开放中继
smtpd_relay_restrictions =
permit_sasl_authenticated,
permit_mynetworks,
reject_unauth_destination

# 基础反垃圾
smtpd_helo_required = yes
disable_vrfy_command = yes
smtpd_delay_reject = yes

smtpd_helo_restrictions =
reject_invalid_helo_hostname,
reject_non_fqdn_helo_hostname

smtpd_sender_restrictions =
reject_non_fqdn_sender,
reject_unknown_sender_domain

smtpd_recipient_restrictions =
reject_non_fqdn_recipient,
reject_unknown_recipient_domain

# TLS 服务端
smtpd_tls_cert_file = /etc/letsencrypt/live/mail.yourdomain.com/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/mail.yourdomain.com/privkey.pem
smtpd_tls_security_level = may
smtpd_tls_auth_only = yes

smtpd_tls_protocols = !SSLv2,!SSLv3,!TLSv1,!TLSv1.1
smtpd_tls_mandatory_protocols = !SSLv2,!SSLv3,!TLSv1,!TLSv1.1

smtpd_tls_ciphers = high
smtpd_tls_mandatory_ciphers = high

# TLS 客户端(直投必须验证)
smtp_tls_security_level = verify
smtp_tls_protocols = !SSLv2,!SSLv3,!TLSv1,!TLSv1.1
smtp_tls_loglevel = 1

# SASL 认证(交给 dovecot)
smtpd_sasl_auth_enable = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
broken_sasl_auth_clients = yes

# 邮箱目录
virtual_mailbox_base = /var/mail/vhosts
virtual_minimum_uid = 1000

# 限制并发(防止被利用发垃圾)
default_process_limit = 100
smtpd_client_connection_count_limit = 20
smtpd_client_connection_rate_limit = 30

# 日志
maillog_file = /var/log/mail.log

创建postfix依赖文件

/etc/postfix/mysql-virtual-mailbox-domains.cf (查询域名)

1
2
3
4
5
user = mailuser
password = your_password
hosts = localhost
dbname = mailserver
query = SELECT 1 FROM virtual_domains WHERE name='%s'

/etc/postfix/mysql-virtual-mailbox-maps.cf (查询用户邮箱)

1
2
3
4
5
user = mailuser
password = your_password
hosts = localhost
dbname = mailserver
query = SELECT 1 FROM virtual_users WHERE email='%s'

/etc/postfix/mysql-virtual-alias-maps.cf (查询别名)

1
2
3
4
5
user = mailuser
password = your_password
hosts = localhost
dbname = mailserver
query = SELECT destination FROM virtual_aliases WHERE source='%s'

重要:将上述文件中的 your_password 替换为你为数据库 mailuser 设置的密码。

设置文件权限

1
2
3
# 这些文件包含数据库密码,必须确保安全。
chmod 640 /etc/postfix/mysql-virtual-*.cf
chgrp postfix /etc/postfix/mysql-virtual-*.cf

配置dovecot

/etc/dovecot/dovecot.conf (主配置文件)

1
2
3
protocols = imap pop3
listen = *
!include conf.d/*.conf

/etc/dovecot/conf.d/10-auth.conf (认证和数据库配置)

1
2
3
4
5
# 禁用系统用户登录,启用SQL认证
disable_plaintext_auth = yes
auth_mechanisms = plain login
!include auth-sql.conf.ext
# 注释掉系统用户认证行: #!include auth-system.conf.ext

/etc/dovecot/conf.d/auth-sql.conf.ext (SQL数据库配置)

1
2
3
4
5
6
7
8
passdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf.ext
}
userdb {
driver = static
args = uid=vmail gid=vmail home=/var/mail/vhosts/%d/%n
}

/etc/dovecot/dovecot-sql.conf.ext (SQL连接配置文件)

1
2
3
4
5
6
driver = mysql
connect = host=localhost dbname=mailserver user=mailuser password=your_password
default_pass_scheme = SHA512-CRYPT
password_query = SELECT email as user, password FROM virtual_users WHERE email='%u';
## 迭代次数(使用doveadm默认值)
iterate_query = SELECT email AS user FROM virtual_users

/etc/dovecot/conf.d/10-mail.conf (邮件位置)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

## 邮件存储位置(Maildir格式)
# %d - 域名
# %n - 用户名
mail_location = maildir:/var/mail/vhosts/%d/%n

## 邮件目录权限
mail_privileged_group = mail

## 邮箱格式
maildir_stat_dirs = yes
maildir_copy_with_hardlinks = yes

## 收件箱命名空间
namespace inbox {
inbox = yes
type = private
separator = /
prefix =
hidden = no
list = yes
subscriptions = yes

# 各种系统文件夹
mailbox Drafts {
special_use = \Drafts
auto = subscribe
}
mailbox Junk {
special_use = \Junk
auto = subscribe
}
mailbox Trash {
special_use = \Trash
auto = subscribe
}
mailbox Sent {
special_use = \Sent
auto = subscribe
}
}

mail_plugin_dir = /usr/lib64/dovecot/modules
protocol !indexer-worker {
}

/etc/dovecot/conf.d/10-master.conf (主服务配置)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
## 主服务配置
service imap-login {
inet_listener imap {
port = 143
}
inet_listener imaps {
port = 993
ssl = yes
}
}

service pop3-login {
inet_listener pop3 {
port = 110
}
inet_listener pop3s {
port = 995
ssl = yes
}
}

service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
mode = 0600
user = postfix
group = postfix
}
}

## Postfix SASL认证关键配置
service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0660
user = postfix
group = postfix
}

unix_listener auth-userdb {
mode = 0600
user = vmail
}
}

service auth-worker {
user = vmail
}

/etc/dovecot/conf.d/10-ssl.conf (SSL配置)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
## SSL强制启用
ssl = required
#
### 证书路径(请替换example.com)
ssl_cert = </etc/postfix/certs/fullchain.pem
ssl_key = </etc/postfix/certs/privkey.pem
#
### 协议版本(Dovecot 2.3.15支持TLSv1.3[citation:3])
ssl_min_protocol = TLSv1.2
ssl_cipher_list = PROFILE=SYSTEM
ssl_prefer_server_ciphers = yes

#
### Diffie-Hellman参数(安全性增强)
ssl_dh = </etc/dovecot/dh.pem

/etc/dovecot/conf.d/20-lmtp.conf (LMTP配置)

1
2
3
4
5
## LMTP服务(接收Postfix投递)
protocol lmtp {
mail_plugins = $mail_plugins sieve
postmaster_address = postmaster@example.com
}

/etc/dovecot/conf.d/15-lda.conf (LDA配置)

1
2
3
4
5
6
7
## 本地投递代理
protocol lda {
mail_plugins = $mail_plugins sieve
postmaster_address = postmaster@example.com
deliver_log_format = msgid=%m: %$
rejection_reason = Your message to <%t> was automatically rejected:%n%r
}

生成 Diffie-Hellman 参数(SSL强化)

1
2
3
4
5
6
7
8
9
10
11
12
13
#方案一:
openssl dhparam -out /etc/dovecot/dh.pem 4096
chmod 600 /etc/dovecot/dh.pem

#方案二:
# 速度快,几秒到几分钟即可完成(推荐)
openssl dhparam -dsaparam -out /etc/dovecot/dh.pem 4096

#文件属主设为 root:dovecot(或 root:root)
chown root:dovecot /etc/dovecot/dh.pem

#权限设置为 640(root可读写,dovecot组可读)
chmod 640 /etc/dovecot/dh.pem

创建虚拟用户

1
2
## 检查是否已创建(之前Postfix步骤应该已创建)
id vmail || groupadd -g 5000 vmail && useradd -g vmail -u 5000 vmail -d /var/mail/vhosts -m

设置权限

1
2
3
## 确保邮件存储目录权限正确
chown -R vmail:vmail /var/mail/vhosts
chmod 755 /var/mail/vhosts

创建邮件存储目录

1
2
3
4
# 域名目录(如果手动创建)同样设置
sudo mkdir -p /var/mail/vhosts/example.com
sudo chown vmail:vmail /var/mail/vhosts/example.com
sudo chmod 755 /var/mail/vhosts/example.com

注意:你只需要创建到域名级别的目录(/var/mail/vhosts/wisepkg.com/),用户级目录 Dovecot 会自动创建。

创建用户

创建用户密码

1
2
3
4
# 假设密码是 Password123
sudo doveadm pw -s SHA512-CRYPT -p 'Password123'
# 输出
{SHA512-CRYPT}$6$CaxxQ4e6VgnZiX0C$rClI9yGQIidEt92nsB3ZTpTt80O.V6U4cO0gTyJUYtSGBnzyaMt5.if3ecu9Bq4be0Sw69Eu9xAVZOetd5cPV.

向数据库中新增用户 (root登录)

1
INSERT INTO virtual_users (domain_id, email, password) VALUES ('1', 'chao.dong@wisepkg.com', '{SHA512-CRYPT}$6$CaxxQ4e6VgnZiX0C$rClI9yGQIidEt92nsB3ZTpTt80O.V6U4cO0gTyJUYtSGBnzyaMt5.if3ecu9Bq4be0Sw69Eu9xAVZOetd5cPV.')

dovecot验证用户密码

1
2
3
doveadm auth test user@wisepkg.com '用户密码'
# 成功会显示
doveadm auth test user@wisepkg.com '用户密码'

添加用户完成,即可使用邮件客户端连接测试。

Debug记录

证书权限

1
2
3
4
5
sudo -u postfix cat /etc/letsencrypt/live/example.wisepkg.com/privkey.pem

报错: Permission denied

说明需要将证书文件拷贝出来,单独存放,别忘了修改main.cf中的证书位置。

SSL连接587端口报错 (该问题由chatGPT协助解决)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
openssl s_client -connect localhost:587 -starttls smtp -showcerts 
CONNECTED(00000003) 807B37821C7F0000:error:0A00010B:
SSL routines:ssl3_get_record:wrong version number:ssl/record/ssl3_record.c:355:
--- no peer certificate available
--- No client certificate CA names sent
--- SSL handshake has read 240 bytes and written 328 bytes Verification: OK
--- New, (NONE), Cipher is (NONE) This TLS version forbids renegotiation.
Compression: NONE Expansion: NONE No ALPN negotiated Early data was not sent Verify return code: 0 (ok) ---

# 这个报错排查了好久,最后查看postfix日志,才定位根因。

sudo journalctl -u postfix -n 50 --no-pager

...
warning: connect to private/tlsmgr: No such file or directory
warning: problem talking to server private/tlsmgr
warning: no entropy for TLS key generation: disabling TLS support
...

表明:

🔴 Postfix 的 TLS 管理进程 tlsmgr 没有运行
👉 所以 TLS 被禁用
👉 STARTTLS 被 advertise
👉 但 TLS 实际不可用
👉 OpenSSL 报 wrong version number

解决方案:

# postfix配置文件master.cf添加一行:

tlsmgr unix - - n 1000? 1 tlsmgr

# 完整示例:

anvil unix - - n - 1 anvil
scache unix - - n - 1 scache
tlsmgr unix - - n 1000? 1 tlsmgr

# 修改完重启postfix , 重新测试,问题解决。

本文作者:智慧锦囊

本文链接:https://dongchao935.github.io/2026%E5%B9%B4openSUSE15-6-postfix-dovecot-mariadb-%E6%90%AD%E5%BB%BA%E9%82%AE%E4%BB%B6%E6%9C%8D%E5%8A%A1%E5%99%A8-%E6%9C%80%E6%96%B0%E6%8C%87%E5%8D%97/

版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!

ESC 关闭 | 导航 | Enter 打开
输入关键词开始搜索