我有这个拓扑
服务器 A:
- eth0 IP:
10.10.20.11/24
和10.10.20.13/24
- eth3:
88.x.x.x
(VLAN ID 为 10) - 主网关:GW2(
10.10.20.3
)
服务器B:
- eth0 IP:
10.10.20.23/24
- 默认网关:
server A
(10.10.20.11
)
从外面我可以 ping 88.x.x.x
IP。Server A
可以 ping Server B
。Server B
我禁用了防火墙。
现在我尝试使用以下规则来路由从88.x.x.x
Server A
到的流量:Server B
<?xml version="1.0" encoding="utf-8"?>
<direct>
<passthrough ipv="ipv4">-A PREROUTING -t nat -p tcp -d 88.x.x.x --dport X -j DNAT --to-destination 10.10.10.23:Y</passthrough>
</direct>
Sysctl 变量开启server A
:在故障排除过程中我得到了一些结果:
tcpdump port X
在Server A
显示包- 没有显示任何数据
tcpdump dst 10.10.10.23
包Server A
。 tcpdump port Y
不Server B
显示任何内容。- 以下在服务器 a 上运行:
telnet 10.10.10.23 Y
禁用后,rp_filter
我得到了半工作拓扑 - 至少我在 tcpdump 中看到了重定向和 DNATted 数据包。
此后我得到了以下图片:
- 服务器 A:
tcpdump -i any port X -n
IP 85.x.x.x > 88.x.x.x.X
- 服务器 A:
tcpdump -i any port Y -n
IP 85.x.x.x > 10.10.10.23.Y:
- 服务器B:
tcpdump -i any port Y -n
IP 85.x.x.x > 10.10.10.23.Y
我已经将 tcpdump 过滤器扩展至,port Y and icmp
并且开始看到主机icmp admin prohibited
回复中的消息10.10.10.23
。然后我打开了防火墙规则server B
-icmp
消息停止了。
目前我有以下路由配置:-Server A
ip -4 ru ls:
0: from all lookup local
32764: from 88.XX/27 lookup 2014
32765: from 10.10.20.11 lookup 1000
32766: from all lookup main
32767: from all lookup default
ip -4 r ls table all:
default via GW1 dev eth3 table 2014
88.x.x.x/27 dev eth3 table 2014
default via 10.10.20.3 dev eth0 table 1000
default via 10.10.20.3 dev eth0
10.10.20.0/24 dev eth0 proto kernel scope link src 10.10.20.11
88.x.x.x/27 dev eth3 proto kernel scope link src 88.x.x.x
broadcast 10.10.20.0 dev eth0 table local proto kernel scope link src 10.10.20.11
local 10.10.20.11 dev eth0 table local proto kernel scope host src 10.10.20.11
local 10.10.20.13 dev eth0 table local proto kernel scope host src 10.10.20.11
broadcast 10.10.20.255 dev eth0 table local proto kernel scope link src 10.10.20.11
broadcast 88.x.x.x dev eth3 table local proto kernel scope link src 88.x.x.x
local 88.x.x.x dev eth3 table local proto kernel scope host src 88.x.x.x
broadcast 127.0.0.0 dev lo table local proto kernel scope link src 127.0.0.1
local 127.0.0.0/8 dev lo table local proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo table local proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo table local proto kernel scope link src 127.0.0.1
Server B
ip -4 r ls:
default via 10.10.20.11 dev eth0
10.10.20.0/24 dev eth0 proto kernel scope link src 10.10.20.23
Server B
我需要从外部通过真实 IP ( )进行访问88.x.x.x
。我做错了什么或遗漏了什么?
答案1
排除故障步骤:
检查实际路由。在服务器 A 上运行
ip route get 10.10.10.23 from 8.8.8.8 iif eth1
。您应该在该命令的输出中看到有效路由。如果您看到RTNETLINK answers: No route to host
,则表示您已禁用转发。请参阅下一步。类似输出RTNETLINK answers: Invalid cross-device
表示rp_filter
过滤类似的数据包。您也可以完全禁用它或将其设置为loose
模式。在服务器 A 上检查转发( )。它应该在输出sysctl` 命令中
ip netconf show dev <iface>
启用。forwarding on
). You can turn on it with
在 SNAT 规则中您应该使用
--to-source 10.10.10.Z
,其中10.10.10.Z
是服务器 A 的接口地址eth0
。否则,在转换来自服务器 B 的回复数据包时会产生副作用。如果服务器 B 的默认网关是服务器 A,则 SNAT 规则不是必需的。检查服务器 A 上的完整规则集。使用
iptables-save -c
命令列出所有带有计数器的规则。您应该在链规则中看到非零计数器FORWARD
。对serverB执行类似的步骤:检查路由,检查防火墙规则集,检查tcpdump输出。
在两台主机上运行
tcpdump
并检查流量。tcpdump
在防火墙之前捕获传入数据包,但在防火墙之后捕获传出数据包。最好将其包含icmp
在 tcpdump 过滤器中,否则您将看不到类似 icmp 拒绝的情况port unreachable
。完成上述所有步骤后,您应该将这些防火墙规则添加到配置中,
server A
以使回复的数据包能够server B
通过GW1
:
iptables -t mangle -A FORWARD\
-p tcp --dst 10.10.20.23 \
-m conntrack --ctstate DNAT --ctorigdst 88.x.x.x --ctdir ORIGINAL \
-j CONNMARK --set-mark 2014
iptables -t mangle -A PREROUTING \
-i eth0 -p tcp \
-m conntrack --ctstate DNAT --ctdir REPLY \
-j CONNMARK --restore-mark
并在 PBR 中添加一条附加路由规则:
ip rule add fwmark 2014 lookup 2014