我有一台 Postfix 邮件服务器,运行在一台有多个网络适配器的主机上,其中一个是虚拟 tun0 设备。我需要这台邮件服务器接受任何适配器上的连接 - 并且只在虚拟 tun 设备上发送电子邮件。
我有一个配置,与这个问题的答案一致,定义 smtp_bind_address=10.20.30.40 - 其中 10.20.30.40 是与 tun0 设备关联的地址。此服务器不支持 IPV6。
多年来,这似乎运行良好 - 直到有一天,tun0 设备死机了 - Postfix 通过默认网络设备 eth0(10.0.0,1)而不是 tun0 发送电子邮件。
这是预期的行为吗?我可以更改哪些设置以确保 Postfix 仅通过 tun0 (10.20.30.40) 发送电子邮件 - 如果 tun0 不可用,则将消息留在队列中?
如果相关的话,这是在 Ubuntu 16.04.2 LTS 上,带有 Postfix 版本 3.1.0-3。tun0 是使用 OpenVPN 版本 2.3.10-1ubuntu2.1 实现的
-- 编辑以添加额外详细信息 --
$ route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.0.0.1 0.0.0.0 UG 0 0 0 eth0
10.0.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
10.20.30.40 0.0.0.0 255.255.255.255 UH 0 0 0 tun0
该服务器运行多项服务 - Postfix 只是其中之一。只有电子邮件需要通过 10.20.30.40 路由 - 所有其他服务都需要通过默认网关路由。
答案1
实际情况是,postfix 将首先使用配置smtp_bind_address
。在您的情况下,它是绑定到 tun0 的静态 ip。当 tun0 启动时,它将通过 tun0 传递出去。如果 tun0 关闭,则客户端bind
将失败,导致 postfix 恢复到不绑定客户端 tcp 端点的默认行为,因此它将使用连接到 eth0 的默认路由。
看起来 postfix 没有提供适合解决 smtp_bind_address 失败的方案。
因此,答案是使用 IP 表规则简单地阻止接口 eth0 上的端口 25 上的出站电子邮件。这将导致所有电子邮件在失败之前或直到 tun0 恢复之前排队一段时间。
类似下面的方法应该可以工作:
iptables -A OUTPUT -i eth0 -p tcp --dport 25 -j DROP
这将阻止所有电子邮件通过 eth0 从端口 25 发出并直接来自您的服务器(未路由)。它不会阻止通过 tun0 发送的电子邮件流量。
答案2
从我在实验室中收集和测试的情况来看,这似乎按预期工作。如果不可用,smtp_bind_address 将故障转移到另一个 inet_interface。
也许您可以设置另一个 Postfix 实例,该实例只有一个 inet_interface 10.20.30.40
,并将 postmap/relay 传出到该实例?也许这样您就可以通过多个适配器接收,并强制通过单个 IP 发送。
答案3
我已经有一段时间没有摆弄过 postfix 了。但我认为你应该使用智能主机中继。
智能主机是一种电子邮件消息传输代理,它允许简单邮件传输协议 (SMTP) 服务器将电子邮件路由到中间邮件服务器,而不是直接路由到收件人的服务器。
中继服务器是与您的邮件域中的发件人 SPF 记录相对应的邮件服务器。您的 ISP 应该能够充当您的智能主机电子邮件中继服务器。
从记忆中,它可以像设置设置一样简单/etc/postfix/main.cf
例如中继主机 = mx1.mydomain.com:587
那么你就不需要关心邮件从哪个接口发送了。