如何将所有发往旧主机的流量重定向到新主机?

如何将所有发往旧主机的流量重定向到新主机?

我们正在转移一系列服务,比如从1.2.3.45.6.7.8

为了测试新服务是否配置正确,我们希望将来自测试工作站的所有发往原始主机的流量重定向(到新主机)。

当然,这样的重定向可以在网络内的路由器上实现 - 但出于稳定性原因,我们决定直接在每个工作站上实现它(所有都是 OS X 10.10 Yosemite,因此使用 pre-v4.7 OpenBSD pf)。

我已添加到/etc/pf.anchors/com.apple

rdr-anchor "910.TestServiceMove/*"
anchor "910.TestServiceMove/*"
load anchor "910.TestServiceMove" from "/etc/pf.anchors/910.TestServiceMove"

并创建/etc/pf.anchors/910.TestServiceMove

rdr pass log on lo0 from any to 1.2.3.4 -> 5.6.7.8
pass out log route-to lo0 from any to 1.2.3.4 keep state

加载规则后,两者似乎都能正常工作:

$ sudo tcpdump -v -n -e -ttt -i pflog0
tcpdump:警告:pflog0:未分配 IPv4 地址
tcpdump:监听 pflog0,链接类型为 PFLOG(OpenBSD pflog 文件),捕获大小为 65535 字节
00:00:00.000000 规则 0.910.TestServiceMove.0/0(匹配):在 en1 上传递:(tos 0x0、ttl 64、id 40691、偏移量 0、标志 [DF]、proto TCP(6)、长度 64)
    9.9.9.9.58029 > 1.2.3.4.22:标志 [S]、cksum 0x291a(正确)、seq 3399416413、win 65535、选项 [mss 1460、nop、wscale 5、nop、nop、TS val 2063366865 ecr 0、sackOK、eol]、长度 0
00:00:00.000047 规则 0/0(匹配):rdr 在 lo0 上:(tos 0x0、ttl 64、id 40691、偏移量 0、标志 [DF]、proto TCP(6)、长度 64、坏 cksum 896a(->b4da)!)
    9.9.9.9.58029 > 5.6.7.8.22:标志 [S]、cksum 0xb284(正确)、seq 3399416413、win 65535、选项 [mss 1460、nop、wscale 5、nop、nop、TS val 2063366865 ecr 0、sackOK、eol]、长度 0

但 TCP 握手并未完成(SYN-ACK 被忽略,并且 SYN 被重复发送直到连接超时):

$ sudo tcpdump -v -n -e -ttt 主机 5.6.7.8
tcpdump:数据链路类型 PKTAP
tcpdump:监听 pktap,链接类型为 PKTAP(Packet Tap),捕获大小为 65535 字节
00:00:00.000000 e8:80:2e:e7:67:bc > 84:80:2d:35:e5:43,以太网类型 IPv4 (0x0800),长度 78:(tos 0x0,ttl 63,id 40691,偏移量 0,标志 [DF],proto TCP (6),长度 64)
    9.9.9.9.58029 > 5.6.7.8.22:标志 [S]、cksum 0xb284(正确)、seq 3399416413、win 65535、选项 [mss 1460、nop、wscale 5、nop、nop、TS val 2063366865 ecr 0、sackOK、eol]、长度 0
00:00:00.015524 84:80:2d:35:e5:43 > e8:80:2e:e7:67:bc,以太网类型 IPv4 (0x0800),长度 74:(tos 0x0,ttl 52,id 0,偏移量 0,标志 [DF],proto TCP (6),长度 60)
    5.6.7.8.22 > 9.9.9.9.58029:标志 [S.],cksum 0x7ce4(正确),seq 1901846890,ack 3399416414,win 14480,选项 [mss 1460,sackOK,TS val 523934721 ecr 2063366865,nop,wscale 7],长度 0
00:00:00.986946 e8:80:2e:e7:67:bc > 84:80:2d:35:e5:43,以太网类型 IPv4 (0x0800),长度 78:(tos 0x0,ttl 63,id 25319,偏移量 0,标志 [DF],proto TCP (6),长度 64)
    9.9.9.9.58029 > 5.6.7.8.22:标志 [S]、cksum 0xae9c(正确)、seq 3399416413、win 65535、选项 [mss 1460、nop、wscale 5、nop、nop、TS val 2063367865 ecr 0、sackOK、eol]、长度 0
00:00:00.014938 84:80:2d:35:e5:43 > e8:80:2e:e7:67:bc,以太网类型 IPv4 (0x0800),长度 74:(tos 0x0,ttl 52,id 0,偏移量 0,标志 [DF],proto TCP (6),长度 60)
    5.6.7.8.22 > 9.9.9.9.58029:标志 [S.],cksum 0x78fa(正确),seq 1901846890,ack 3399416414,win 14480,选项 [mss 1460,sackOK,TS val 523935723 ecr 2063366865,nop,wscale 7],长度 0
00:00:00.397794 84:80:2d:35:e5:43 > e8:80:2e:e7:67:bc,以太网类型 IPv4 (0x0800),长度 74:(tos 0x0,ttl 52,id 0,偏移量 0,标志 [DF],proto TCP (6),长度 60)
    5.6.7.8.22 > 9.9.9.9.58029:标志 [S.],cksum 0x776c(正确),seq 1901846890,ack 3399416414,win 14480,选项 [mss 1460,sackOK,TS val 523936121 ecr 2063366865,nop,wscale 7],长度 0
00:00:00.588237 e8:80:2e:e7:67:bc > 84:80:2d:35:e5:43,以太网类型 IPv4 (0x0800),长度 78:(tos 0x0,ttl 63,id 50201,偏移量 0,标志 [DF],proto TCP (6),长度 64)
    9.9.9.9.58029 > 5.6.7.8.22:标志 [S],cksum 0xaab4(正确),seq 3399416413,win 65535,选项 [mss 1460,nop,wscale 5,nop,nop,TS val 2063368865 ecr 0,sackOK,eol],长度 0

我猜想 TCP 堆栈会丢弃来自 SYN 发送目标主机以外的主机的 SYN-ACK。但重定向规则不应该重写两个都方向——事实上,难道不应该keep state确保为此目的跟踪连接吗?

答案1

如果您访问的服务都是通过名称访问的,那么我只需在开发机器上的 hosts 文件中创建一个主机条目。

例如,如果你的机器名为 myserver 并解析为 1.2.3.4 ,那么你现在可以创建一个主机文件条目 /etc/hosts

我的服务器 5.6.7.8

现在尝试访问我的服务器的任何内容最终都会访问新机器。

或者,只需在旧地址上使用新服务器创建一个新的隔离网络,并将您的开发机器插入其中进行测试。

直接重定向或路由规则的问题在于,新服务器不会以旧地址的名称进行应答。因此,您必须使用 NAT。

答案2

将机器置于简单的负载均衡器或 NAT 之后不是更简单吗?无论如何,这通常更像是一种行业标准做法,并且可以让您随着时间的推移进一步扩展应用程序。

答案3

您能否仅从“新”服务器子接口提供“旧”地址,还是新地址位于完全不同的子网中?

如果您无法将新 IP 附加到新服务器,则您实际上并没有移动地址。要将流量通过旧地址路由到新服务器,您需要对旧子网中的地址进行 NAT。流量将落在“旧”地址上,然后通过源 NAT 发送到同一服务器/设备上的新地址并发送到“新”IP。然后,返回流量将传回 SNAT 地址,该地址将取消 NAT 流量并将其返回给原始请求者。这确实不是一个好的长期解决方案,特别是如果“新”地址跨 WAN 链接。您推迟了不可避免的故障,并且还增加了延迟。

更好的长期解决方案是考虑:1. 使用 DNS 而不是 IP 2. 虚拟化 IP 地址(NAT 设备,如防火墙或 ipmasq 盒),3. 或服务器本身(负载均衡器)

相关内容