我有一个带有 centos7 的 HAProxy 盒子,并为 smtp 集群做负载平衡代理,为我们的客户提供邮件中继。
default gateway => 10.0.0.1
master-relay.example.net => 10.0.0.254
relay1.example.net => 10.0.0.10 | gateway 10.0.0.1
relay2.example.net => 10.0.0.11 | gateway 10.0.0.1
relay3.example.net => 10.0.0.12 | gateway 10.0.0.1
每个中继都配置了后缀以侦听端口 25 和 587。
我需要实现的是,当任何人尝试发送直接连接到 3 个中继之一(relay1、relay2 或 relay3)的邮件时,会将应答数据包转发到默认网关。这通常是当任何外部邮件服务器尝试向我们发送电子邮件并随机连接到具有相同优先级的 3 台 MX 服务器之一时。
但是,当移动或 webmail 客户端连接到集群以将电子邮件中继到主中继时,该客户端连接到 3 台 MX 服务器之一以传递邮件。
这是集群的 HAProxy 配置:
# Puerto 25 - SMTP (Postfix Cluster)
frontend frontend-smtp-25
bind 10.0.0.254:25 transparent
option tcplog
default_backend backend-smtp-25
backend backend-smtp-25
option tcplog
source 0.0.0.0 usesrc clientip
server mx1 10.0.0.10:25 check
server mx2 10.0.0.11:25 check
server mx3 10.0.0.12:25 check
# Puerto 587 - STARTTLS (Postfix Cluster)
frontend frontend-smtp-587
bind 10.0.0.254:587 transparent
option tcplog
default_backend backend-smtp-587
backend backend-smtp-587
option tcplog
source 0.0.0.0 usesrc clientip
server mx1 10.0.0.10:587 check
server mx2 10.0.0.11:587 check
server mx3 10.0.0.12:587 check
内核参数:
net.ipv4.tcp_tw_reuse
net.ipv4.tcp_tw_recycle
net.ipv4.ip_local_port_range = 1025 65535
net.ipv4.ip_nonlocal_bind = 1
net.ipv4.ip_forward = 1
防火墙规则:
iptables -t mangle -N DIVERT
iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
iptables -t mangle -A DIVERT -j MARK --set-mark 1
iptables -t mangle -A DIVERT -j ACCEPT
ip rule add fwmark 1 lookup 100
ip route add local 0.0.0.0/0 dev lo table 100
现在使用此配置,如果我将中继盒的默认网关更改为主中继,一切正常,并且在后缀日志中我可以看到客户端的 IP 地址,而不是主中继的 IP 地址,但这里我有一个问题,如果任何人都直接连接到relay1,例如这个答案是通过主中继而不是通过网关,客户端丢弃数据包,因为不是来自relay1盒子。
我试图做的是在所有 3 个中继盒上标记主中继的源 MAC 地址,所有与标记匹配的都将默认网关更改为主中继的网关。
所有 IP 都是公共 IP,并且都可以从互联网上看到。
我能做的是将2个IP放在同一个接口中,如果有任何数据包到达IP1,则回复一个网关,如果涉及IP2,则回复另一个网关,但如果可能的话,我真的更喜欢mac规则。
我不能制定规则来强制如果数据包来自主中继 IP 地址再次回复它,因为它将使用客户端 IP 地址到达代理。
提前致谢
以下是中继(即
relay1
或relay2
)在透明模式下relay3
正确处理通过default-gateway
(10.0.0.1
) 或通过 HAProxymaster-relay
(10.0.0.254
) 的流量(充当网关)的目标和方法:中继应该使用普通网关
default-gateway
进行正常流量,即:default-gateway
。master-relay
中继应为 HAProxy 的透明中继流量使用备用网关,因此仅适用于:master-relay
已通过充当备用网关的远程发起流量的出站回复。区分路由案例 1. 和案例 2. 的选择器是备用网关的源 MAC 地址
master-relay
。比方说02:03:04:05:06:07
。选择,一旦在连接的第一个数据包完成,对于该连接的所有其他数据包部分应该保持相同。
这需要策略路由,带有备用路由表 (
ip route add table ...
,附加路由决策 (ip rule add fwmark...
),依赖于iptables
使用mac
MAC 地址选择器的匹配模块,MARK
更改路由决策的CONNMARK
目标,以及记住整个连接决策的目标。情况 1. 是没有特殊处理的默认情况和情况 2. 例外情况,您应该恢复路由更改,
default-gateway
像往常一样用作默认网关:情况 2. 将存储在备用路由表中。不用起名字,随便选个号都行,选
1000254
(254
是保留的,是主表...):使用它的路由决策将由标记值(来自
iptables
的MARK
目标)触发。让我们选择254
:从Netfilter 和 General Networking 中的数据包流中可以看出,在路由决策(或重新路由检查)完成之前,或可以设置标记中的
iptables
规则。这就是最终将如何改变路线。因此,对于单个传入数据包,这将是:mangle/PREROUTING
mangle/OUTPUT
iptables
现在要为整个连接记住它,它应该用
CONNMARK
调用包装,调用存储和检索此流的 conntrack 条目中的标记,并只允许第一次设置它,而不会忘记 OUTPUT 方向。此博客中有一些解释:To Linux and beyond !网络过滤器康马克。无需为 LAN 流量标记数据包,因此将其过滤掉(这conntrack -L
在最后使用 see 时会有所帮助)。最后,包括前面的规则,它变成:而已。这种情况甚至不需要设置
rp_filter
为松散模式,因为只涉及一个网络接口。请注意,如果您需要冗余(或者如果其 IP 可能出于任何原因更改其 MAC 地址,则
master-relay
只需添加一个额外的 MAC ) ,您可以轻松插入更多表、规则和标记以具有多个。具有 IP和 MACmaster-relay
的附加 HAProxy 示例:10.0.0.250
0A:09:08:07:06:05
conntrack -L
将显示连接标记,因此可用于区分连接是否通过master-relay
而不是默认连接,因为它的标记将254
代替0
: