OpenSMTPD多出站服务器主机名配置:根据发件人字段自动设置出站主机名及发件人地址
我刚好在FreeBSD环境下处理过类似的OpenSMTPD配置需求,结合你的场景,给你一套可行的解决方案——既能自动替换系统/非特权用户的发件人地址,又能根据发件人域名匹配对应的出站主机名,完美解决DKIM签名的问题。
一、先解决发件人地址自动映射问题
首先我们需要把系统本地用户(比如john、root)映射到真实的邮箱地址,这样不管用户用sendmail还是系统脚本发邮件,发件人都会自动替换成你指定的域名邮箱。
- 创建用户-邮箱映射文件
在/etc/mail/下新建一个映射文件,比如user_to_mailaddr,内容根据你的需求填写:
john john@example.org root admin@example.com www-data noreply@example.net
每行格式是「系统用户名 目标邮箱地址」,注意用空格或制表符分隔。
- 在smtpd.conf中加载映射并添加重写规则
打开/etc/mail/smtpd.conf,先添加映射表的定义:
table user_to_mailaddr file:/etc/mail/user_to_mailaddr
然后添加发件人重写规则,让本地用户的发件人地址自动替换为映射里的邮箱:
rewrite from local:$user to table:user_to_mailaddr
这条规则会匹配所有本地用户发送的邮件,把发件人从「用户名@服务器主机名」替换成映射中对应的真实邮箱。
二、根据发件人域名配置对应出站主机名
接下来要让不同域名的发件人使用对应的出站主机名(也就是EHLO/HELO时发送的主机名),同时可以绑定对应域名的DKIM密钥。
- 为每个域名定义独立的relay动作
在smtpd.conf中,为每个你使用的域名定义一个action,指定对应的出站主机名和DKIM密钥(如果需要):
# 对应example.org域名的出站配置 action relay_exampleorg relay hostname example.org dkim dkim_keys # 对应example.com域名的出站配置 action relay_examplecom relay hostname example.com dkim dkim_keys # 对应example.net域名的出站配置 action relay_examplenet relay hostname example.net dkim dkim_keys
- 如果你的邮件需要通过中继服务器发送,把
relay改成relay host smtp://你的中继地址,比如relay host smtp://smtp.example.org dkim dkim_keys是用来指定DKIM密钥表的,如果你还没配置DKIM,可以先去掉这部分,后续再补充
- 添加匹配规则,绑定发件人域名到对应动作
在smtpd.conf中添加match规则,让不同域名的发件人匹配到对应的relay动作:
match from domain example.org action relay_exampleorg match from domain example.com action relay_examplecom match from domain example.net action relay_examplenet
这里的from domain会匹配重写后的发件人地址域名,确保对应的邮件用正确的主机名出站。
- 更新本地域名列表
确保/etc/mail/domains文件包含你所有使用的域名,这样OpenSMTPD才会认可这些域名是本地可处理的:
example.org example.com example.net
三、重载配置并测试
完成配置后,重载OpenSMTPD让配置生效:
service smtpd reload
然后用非特权用户测试一下,比如用john用户发邮件:
echo "测试邮件内容" | sendmail -v test@external-domain.com
之后查看/var/log/maillog,你应该会看到发件人变成了john@example.org,出站主机名是example.org,而且不会再出现「No MX found for domain」的错误(因为现在用的是真实域名)。
补充:DKIM密钥配置(可选但推荐)
如果需要给不同域名配置DKIM签名,先为每个域名生成密钥,然后在/etc/mail/dkim/下创建dkim_keys表文件,内容格式如下:
example.org example.org:dkim:/etc/mail/dkim/example.org.private example.com example.com:dkim:/etc/mail/dkim/example.com.private
然后在smtpd.conf中加载这个表:
table dkim_keys file:/etc/mail/dkim/dkim_keys
这样之前定义的relay动作里的dkim dkim_keys就会自动用对应域名的密钥签名邮件了。
备注:内容来源于stack exchange,提问作者Jarmo Pertman

