22. 邮件服务基础
本章介绍 RHEL 9 上 Postfix(SMTP 发送)和 Dovecot(IMAP/POP3 接收)的配置,以及外部 SMTP 中继和 SPF/DKIM 邮件安全机制。邮件服务涉及多个协议层,本章聚焦企业内网和中继两种最常见的部署场景。
实验环境说明
完整的公网邮件服务需要公网 IP、真实域名和 PTR 反向解析记录,超出实验范围。本章以 linuxdc.local 作为内部测试域名演示配置流程;公网部署的额外要求在各节末尾说明。
22.1 前提条件
- 已完成第四阶段前序配置(第 20–21 章)。
- 通过 SecureCRT(SSH 端口 2222)以
ops用户、密钥认证方式登录192.168.1.100,执行sudo -i切换至 root 环境。 - SELinux 处于 Enforcing 模式,firewalld 已启用(第 12 章)。
- 时间同步已配置(第 8 章),DKIM 签名依赖准确的系统时间。
本章全局参数
| 参数 | 值 |
|---|---|
| 主机名 | linuxdc |
| IP | 192.168.1.100 |
| 邮件域名 | linuxdc.local |
| SMTP 中继服务器 | 192.168.1.200:587 |
| DKIM 选择器 | mail |
22.2 Postfix 配置(SMTP)
22.2.1 安装与启动
dnf install -y postfix mailx
systemctl enable --now postfix
systemctl status postfix
22.2.2 基础参数配置
vim /etc/postfix/main.cf
修改以下关键参数:
# 服务器身份标识(与系统主机名一致)
myhostname = linuxdc.linuxdc.local
mydomain = linuxdc.local
# 发件人地址域
myorigin = $mydomain
# 监听所有网络接口(默认仅 localhost)
inet_interfaces = all
inet_protocols = ipv4
# 接收邮件的本地目标域
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
# 允许无认证转发的受信任网段(仅内网,切勿设为 0.0.0.0/0)
mynetworks = 127.0.0.0/8 192.168.1.0/24
# 单封邮件最大体积(10 MB)
message_size_limit = 10485760
# 邮件队列目录
queue_directory = /var/spool/postfix
# 验证配置语法,显示所有非默认参数
postfix check
postconf -n
systemctl restart postfix
开放防火墙(内网 SMTP):
firewall-cmd --permanent --add-service=smtp
firewall-cmd --reload
发送测试邮件:
echo "Test body from linuxdc" | mail -s "Test Mail" root
# 查看本地投递的邮件
cat /var/spool/mail/root
检查点
/var/spool/mail/root 中收到测试邮件;postconf -n 输出中包含已配置的参数。
22.3 Dovecot 配置(IMAP/POP3)
22.3.1 安装与启动
dnf install -y dovecot
systemctl enable --now dovecot
systemctl status dovecot
开放防火墙:
firewall-cmd --permanent --add-service=imap
firewall-cmd --permanent --add-service=pop3
firewall-cmd --permanent --add-service=imaps
firewall-cmd --permanent --add-service=pop3s
firewall-cmd --reload
22.3.2 基础配置
vim /etc/dovecot/dovecot.conf
确认以下行已启用(取消注释):
protocols = imap pop3 lmtp
listen = *
vim /etc/dovecot/conf.d/10-auth.conf
修改认证参数:
# 实验环境允许明文(生产必须关闭,通过 TLS 保护)
disable_plaintext_auth = no
auth_mechanisms = plain login
vim /etc/dovecot/conf.d/10-mail.conf
指定邮箱存储位置:
mail_location = mbox:~/mail:INBOX=/var/spool/mail/%u
systemctl restart dovecot
# 验证端口监听状态
ss -tuln | grep -E ':143|:110|:993|:995'
验证 IMAP 连接(Telnet 方式):
telnet localhost 143
# 依次输入以下命令:
# a1 LOGIN root <root系统密码>
# a2 LIST "" "*"
# a3 LOGOUT
检查点
ss -tuln 显示 143(IMAP)和 110(POP3)端口监听;telnet localhost 143 后执行 LOGIN 命令返回 OK Logged in。
生产环境必须启用 TLS
生产部署中必须将 disable_plaintext_auth = yes,并配置有效的 TLS 证书(/etc/dovecot/conf.d/10-ssl.conf),强制客户端通过加密通道(IMAPS/993、POP3S/995)连接,防止密码明文传输。
22.4 配置外部 SMTP 中继
当本机 IP 可能被列入黑名单,或企业统一通过专用邮件网关发信时,配置外部中继转发。
vim /etc/postfix/main.cf
追加以下配置:
# 中继服务器地址(方括号跳过 MX 查询,直接连接指定主机)
relayhost = [192.168.1.200]:587
# SASL 认证(若中继服务器要求账户认证)
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
# TLS 加密传输
smtp_use_tls = yes
smtp_tls_security_level = encrypt
smtp_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt
smtp_tls_loglevel = 1
创建认证凭证文件:
tee /etc/postfix/sasl_passwd << 'EOF'
[192.168.1.200]:587 relay_user:relay_password
EOF
# 将明文凭证转换为 Postfix 哈希数据库
postmap /etc/postfix/sasl_passwd
# 保护凭证文件
chmod 600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
systemctl restart postfix
测试中继:
echo "Relay test" | mail -s "Relay Test" admin@linuxdc.local
tail -30 /var/log/maillog
22.5 邮件安全配置
22.5.1 SPF 记录
SPF(Sender Policy Framework)在 DNS 中声明哪些 IP 有权代表域名发送邮件,接收方通过查询 DNS 验证发件 IP 是否被授权。
在 DNS 管理平台为 linuxdc.local 添加 TXT 记录:
linuxdc.local. IN TXT "v=spf1 a mx ip4:192.168.1.100 ~all"
SPF 限定符说明:
| 限定符 | 含义 |
|---|---|
+all |
允许所有(不推荐,等同于无保护) |
~all |
软失败(softfail,标记为可疑但不拒绝) |
-all |
硬失败(reject,拒绝未授权来源) |
?all |
中立(neutral,不做判断) |
验证(内网 DNS):
dig TXT linuxdc.local
22.5.2 配置 DKIM(OpenDKIM)
DKIM(DomainKeys Identified Mail)使用私钥对每封发出的邮件生成数字签名,接收方通过 DNS 查询公钥验证签名,确认邮件内容完整且来源真实。
dnf install -y opendkim opendkim-tools
systemctl enable --now opendkim
生成密钥对:
mkdir -p /etc/opendkim/keys/linuxdc.local
opendkim-genkey \
-s mail \
-d linuxdc.local \
-D /etc/opendkim/keys/linuxdc.local/
# 设置私钥权限
chown -R opendkim:opendkim /etc/opendkim/keys/
chmod 600 /etc/opendkim/keys/linuxdc.local/mail.private
配置 OpenDKIM 主配置文件:
vim /etc/opendkim.conf
关键参数:
Mode sv
Domain linuxdc.local
KeyFile /etc/opendkim/keys/linuxdc.local/mail.private
Selector mail
Socket inet:8891@localhost
UserID opendkim:opendkim
KeyTable /etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable
ExternalIgnoreList /etc/opendkim/TrustedHosts
InternalHosts /etc/opendkim/TrustedHosts
配置密钥表、签名表和受信任主机:
tee /etc/opendkim/KeyTable << 'EOF'
mail._domainkey.linuxdc.local linuxdc.local:mail:/etc/opendkim/keys/linuxdc.local/mail.private
EOF
tee /etc/opendkim/SigningTable << 'EOF'
*@linuxdc.local mail._domainkey.linuxdc.local
EOF
tee /etc/opendkim/TrustedHosts << 'EOF'
127.0.0.1
localhost
192.168.1.100
linuxdc.local
linuxdc
EOF
将 OpenDKIM 集成到 Postfix(milter 接口):
vim /etc/postfix/main.cf
追加:
# OpenDKIM milter 集成
milter_default_action = accept
milter_protocol = 6
smtpd_milters = inet:localhost:8891
non_smtpd_milters = $smtpd_milters
systemctl restart opendkim postfix
查看公钥内容(需添加到 DNS TXT 记录):
cat /etc/opendkim/keys/linuxdc.local/mail.txt
DNS TXT 记录格式:
mail._domainkey.linuxdc.local. IN TXT "v=DKIM1; k=rsa; p=<公钥内容>"
检查点
systemctl is-active opendkim 返回 active;发送测试邮件后在 /var/log/maillog 中查看 DKIM 签名相关日志。
22.6 常见问题与排查
| 问题现象 | 排查步骤 |
|---|---|
| 邮件发送失败 | tail -50 /var/log/maillog;postconf -n 确认配置参数 |
| SASL 认证失败 | 确认 sasl_passwd 权限为 600;执行 postmap 重建哈希库后重启 |
| Dovecot IMAP 连接拒绝 | ss -tuln | grep :143;journalctl -u dovecot -n 20 |
| DKIM 签名验证失败 | 检查私钥权限(600)和所有者(opendkim);journalctl -u opendkim -n 20 |
| 邮件进入队列但未发出 | postqueue -p 查看队列及错误原因;postqueue -f 强制重试 |
# Postfix 队列管理
postqueue -p # 查看当前邮件队列
postqueue -f # 强制重发队列中所有邮件
postsuper -d ALL # 清空全部队列(谨慎操作)
# 日志实时追踪
tail -f /var/log/maillog
22.7 实践任务
- 登录
linuxdc(SecureCRT 端口 2222,ops用户,密钥认证,sudo -i切换 root)。 - 安装 Postfix,配置
myhostname、mydomain、mynetworks,发送测试邮件并验证/var/spool/mail/root收到。 - 安装 Dovecot,配置 IMAP/POP3,用
telnet localhost 143验证连接正常,执行LOGIN命令。 - 配置外部中继(
relayhost = [192.168.1.200]:587),创建sasl_passwd,验证postconf -n显示中继配置。 - 安装 OpenDKIM,生成密钥对,完成
KeyTable/SigningTable/TrustedHosts配置,集成 Postfix milter,验证systemctl is-active opendkim为active。 - 查看公钥文件
mail.txt,了解其 DNS TXT 记录格式。
22.8 自测问题
Q1:mynetworks 参数设置不当有何安全风险?
mynetworks 定义哪些 IP 范围可无需认证地通过本机 Postfix 发送邮件(中继)。若设置为 0.0.0.0/0,服务器成为开放中继(Open Relay),全球垃圾邮件发送者均可通过此服务器转发邮件,IP 地址将迅速被各大 RBL(实时黑名单)收录,导致所有从此 IP 发出的邮件被拒绝。生产环境必须严格限制为 127.0.0.0/8 加受信任的内网网段。
Q2:DKIM 的签名验证原理是什么?
发信时,OpenDKIM 用域名私钥对邮件头部字段(From、Subject、Date 等)和邮件体内容生成哈希签名,将签名值写入邮件头的 DKIM-Signature 字段一同发出。收信方 MTA 从 DKIM-Signature 中读取域名和选择器,向 DNS 查询 mail._domainkey.域名 的 TXT 记录获取对应公钥,用公钥验证签名是否有效,从而确认邮件内容未遭篡改且确实来自声明的域名。
Q3:为什么 SPF、DKIM、DMARC 三者需要同时配置?
三者从不同维度防御邮件欺诈:SPF 验证发件服务器 IP 是否被该域名授权发信,但无法防止邮件内容被篡改;DKIM 验证邮件内容完整性与发件域真实性,但无法限制 SPF 通过后的横向滥用;DMARC 基于 SPF 和 DKIM 的验证结果制定处置策略(放行/隔离/拒绝),并向域名管理员提供定期汇报,形成闭环。仅配置其中一两项时攻击者仍有绕过途径,三者联合才能有效防范域名仿冒(Email Spoofing)和网络钓鱼攻击。
22.9 章节总结
本章完成了 RHEL 9 邮件服务的基础配置:Postfix 作为 SMTP 发送代理(含内网直发与外部中继两种模式)、Dovecot 提供 IMAP/POP3 接收访问,以及 SPF 和 DKIM 邮件安全机制的完整部署流程。邮件服务配置层次复杂,生产上线前需确保 DNS 记录(SPF/DKIM/PTR/MX)、TLS 证书和防垃圾邮件策略均已到位,并通过 mail-tester.com 等工具验证发信质量评分。