跳转至

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 typeInternet Site
  • System mail namemail.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/<邮件文件名>

检查点

mailuserMaildir/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

实践任务

  1. 安装 Postfix,完成 main.cf 基础配置,确认服务正常启动
  2. 启用 submission 端口 587,用 ss -tuln 确认监听
  3. 安装 Dovecot,配置 maildir 存储,创建 mailuser 并发送测试邮件
  4. 查看 /var/log/mail.log,确认邮件投递有 status=sent 记录

自测问题

1. Postfix 的 mydestinationmynetworks 参数分别控制什么?

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 证书和反垃圾过滤,形成完整的邮件系统。