跳转至

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/maillogpostconf -n 确认配置参数
SASL 认证失败 确认 sasl_passwd 权限为 600;执行 postmap 重建哈希库后重启
Dovecot IMAP 连接拒绝 ss -tuln | grep :143journalctl -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 实践任务

  1. 登录 linuxdc(SecureCRT 端口 2222,ops 用户,密钥认证,sudo -i 切换 root)。
  2. 安装 Postfix,配置 myhostnamemydomainmynetworks,发送测试邮件并验证 /var/spool/mail/root 收到。
  3. 安装 Dovecot,配置 IMAP/POP3,用 telnet localhost 143 验证连接正常,执行 LOGIN 命令。
  4. 配置外部中继(relayhost = [192.168.1.200]:587),创建 sasl_passwd,验证 postconf -n 显示中继配置。
  5. 安装 OpenDKIM,生成密钥对,完成 KeyTable/SigningTable/TrustedHosts 配置,集成 Postfix milter,验证 systemctl is-active opendkimactive
  6. 查看公钥文件 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 等工具验证发信质量评分。