22 - 邮件服务基础(Postfix + Dovecot)
前提条件
- 已完成 Web 服务(Apache2/Nginx)和数据库基础(MariaDB/PostgreSQL)配置
- 以 root 身份登录,或 ops 用户执行
sudo -i切换至 root 环境 - 系统运行在 Debian 12 Bookworm
- 防火墙已放行邮件相关端口(详见下表)
- 本章使用本地域名
linuxdc.local进行实验;生产环境需真实域名 + MX / SPF / DKIM 记录
全局参数
主机名 linuxdc,IP 192.168.1.100/24,SSH 端口 2222,运维用户 ops
邮件域名(实验):linuxdc.local,邮件主机名:mail.linuxdc.local
邮件相关端口说明
| 端口 | 协议 | 服务 | 说明 |
|---|---|---|---|
| 25 | TCP | SMTP | 服务器间邮件传递,不用于客户端发送 |
| 587 | TCP | Submission | 客户端认证后提交邮件(推荐) |
| 465 | TCP | SMTPS | SMTP over TLS(旧标准,部分客户端仍用) |
| 143 | TCP | IMAP | 客户端收信(明文,生产应禁用) |
| 993 | TCP | IMAPS | IMAP over TLS(推荐) |
| 110 | TCP | POP3 | 客户端收信(明文,生产应禁用) |
| 995 | TCP | POP3S | POP3 over TLS |
详细步骤
1. 安装 Postfix(SMTP)
apt update
apt install -y postfix
安装向导中选择:
- General type:
Internet Site - System mail name:
mail.linuxdc.local
安装完成后编辑主配置文件:
cp /etc/postfix/main.cf /etc/postfix/main.cf.bak-$(date +%F)
vim /etc/postfix/main.cf
关键配置项(修改或确认以下内容):
# 主机标识
myhostname = mail.linuxdc.local
mydomain = linuxdc.local
myorigin = $mydomain
# 监听接口(生产只需监听内网 IP)
inet_interfaces = all
inet_protocols = all
# 接受投递的目标域
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
# 允许转发的网段(只限本机和内网)
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 192.168.1.0/24
# Banner(不暴露软件版本)
smtpd_banner = $myhostname ESMTP
# TLS(使用系统自带自签名证书测试)
smtpd_tls_cert_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
smtpd_tls_key_file = /etc/ssl/private/ssl-cert-snakeoil.key
smtpd_use_tls = yes
smtpd_tls_security_level = may
smtp_tls_security_level = may
systemctl restart postfix
systemctl status postfix
检查点
systemctl status postfix 显示 active (running),ss -tuln | grep 25 显示 Postfix 正在监听。
2. 启用 Submission 端口(587,客户端认证发送)
编辑 Postfix 服务定义文件:
vim /etc/postfix/master.cf
找到以下行(默认被注释),取消注释并按如下修改:
submission inet n - y - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
-o smtpd_tls_auth_only=yes
-o smtpd_client_restrictions=permit_sasl_authenticated,reject
-o smtpd_relay_restrictions=permit_sasl_authenticated,reject
systemctl restart postfix
ss -tuln | grep 587
检查点
ss -tuln | grep 587 输出显示 Postfix 监听 587 端口。
3. 安装 Dovecot(IMAP / POP3)
apt install -y dovecot-core dovecot-imapd dovecot-pop3d
配置邮件存储位置:
vim /etc/dovecot/conf.d/10-mail.conf
mail_location = maildir:~/Maildir
配置认证:
vim /etc/dovecot/conf.d/10-auth.conf
# 实验环境暂允许明文认证(生产必须设为 yes 并强制 SSL)
disable_plaintext_auth = no
auth_mechanisms = plain login
配置 SSL:
vim /etc/dovecot/conf.d/10-ssl.conf
ssl = required
ssl_cert = </etc/ssl/certs/ssl-cert-snakeoil.pem
ssl_key = </etc/ssl/private/ssl-cert-snakeoil.key
生产环境建议
生产环境应将 disable_plaintext_auth = yes,强制所有认证通过 TLS 传输,并将证书替换为 Let's Encrypt 或商业 CA 签发的证书。
systemctl restart dovecot
systemctl enable dovecot
systemctl status dovecot
检查点
ss -tuln | grep -E '143|993|110|995' 显示 Dovecot 正在监听对应端口。
4. 创建测试用户并发送邮件
# 创建邮件测试用户(系统用户,Dovecot 使用系统认证)
adduser mailuser
安装邮件命令行工具并发送测试邮件:
apt install -y mailutils
echo "Test body from Postfix" | mail -s "Test Subject" mailuser@localhost
查收邮件:
su - mailuser
mail
# 输入邮件编号查看内容,q 退出
exit
也可直接查看 Maildir:
ls /home/mailuser/Maildir/new/
cat /home/mailuser/Maildir/new/<邮件文件名>
检查点
mailuser 的 Maildir/new/ 目录下出现新邮件文件,/var/log/mail.log 中有 status=sent 记录。
5. 防火墙放行
放行实验环境所需端口(内网限制访问):
# 仅允许内网访问邮件端口
nft add rule inet filter input ip saddr 192.168.1.0/24 tcp dport { 25, 587, 993, 995 } ct state new accept
nft list ruleset > /etc/nftables.conf
6. 邮件客户端配置参考
| 参数 | 收件(IMAP) | 发件(SMTP) |
|---|---|---|
| 服务器 | mail.linuxdc.local |
mail.linuxdc.local |
| 端口 | 993(SSL/TLS) |
587(STARTTLS) |
| 用户名 | mailuser |
mailuser |
| 认证 | 密码 | 密码 |
7. 生产加固要点
| 方向 | 措施 |
|---|---|
| 证书 | 替换自签名证书为 Let's Encrypt |
| 反垃圾 | 部署 SpamAssassin 或 Rspamd |
| 发信声誉 | 配置 SPF、DKIM、DMARC DNS 记录 |
| 暴力破解防护 | fail2ban 监控 /var/log/mail.log |
| 中继限制 | mynetworks 只保留必要 IP |
实践任务
- 安装 Postfix,完成
main.cf基础配置,确认服务正常启动 - 启用
submission端口 587,用ss -tuln确认监听 - 安装 Dovecot,配置
maildir存储,创建mailuser并发送测试邮件 - 查看
/var/log/mail.log,确认邮件投递有status=sent记录
自测问题
1. Postfix 的 mydestination 和 mynetworks 参数分别控制什么?
mydestination 定义 Postfix 接受作为最终投递目标的域名列表。收到的邮件若目标域在此列表中,Postfix 将其投递到本地邮箱;否则尝试转发。典型值包括主机名、localhost 和本机域名。mynetworks 定义被信任的客户端网段,这些网段的主机无需认证即可通过 Postfix 转发邮件。配置不当(如 mynetworks = 0.0.0.0/0)会将服务器变成开放中继,成为垃圾邮件发送平台。
2. Dovecot 中 mail_location = maildir:~/Maildir 的含义是什么?
使用 Maildir 格式将邮件存储在每个用户主目录下的 Maildir/ 子目录中。Maildir 格式每封邮件存为独立文件(存放在 new/、cur/、tmp/ 三个子目录),与旧式 mbox(所有邮件合并为单文件)相比,Maildir 支持多进程并发读写不会损坏数据,单封邮件损坏不影响其他邮件,删除操作直接删文件效率高。~/Maildir 表示路径相对于当前登录用户的家目录。
3. 为什么生产环境推荐使用 587 端口而非 25 端口发送邮件?
25 端口(SMTP)是服务器间邮件传递使用的标准端口,大多数 ISP 和云服务商(AWS、阿里云等)默认封锁出方向 25 端口,以防止用户发送垃圾邮件。此外,25 端口设计上允许无认证接收,若配置不当容易成为开放中继。587 端口(Submission)专为邮件客户端提交邮件设计,强制要求 SASL 认证(smtpd_sasl_auth_enable=yes)和 TLS 加密,确保只有合法用户才能通过该端口发送邮件,更符合现代邮件安全要求。
4. 如何让 Postfix 只接受本地或信任网段的邮件中继?
在 main.cf 中精确配置 mynetworks,只列入本机和受信任网段:
mynetworks = 127.0.0.0/8 [::1]/128 192.168.1.0/24
同时在 smtpd_relay_restrictions 中明确拒绝未授权中继:
smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject
这两个参数共同保证:只有来自 mynetworks 定义网段的主机,或通过 SASL 认证的用户,才能通过本服务器中继邮件,其他所有中继请求均被拒绝。
总结
Postfix + Dovecot 是 Debian 上成熟可靠的开源邮件服务器组合,本章完成了 SMTP 发送、IMAP/POP3 收信、TLS 加密和系统用户认证的基础配置。生产部署还需补充 SPF/DKIM/DMARC 发信声誉配置、Let's Encrypt 证书和反垃圾过滤,形成完整的邮件系统。