使用多宿主服务器丢弃IPstream量

(在深入细节之前,我以Apache和SSH为例来介绍这个问题,但这不是特定于TCPstream量的问题,而是基于TCP和UDP协议的问题。

我有一个运行Ubuntu 9.04的多链路多宿主服务器,eth0连接到外部networking,eth1连接到内部networking。 外部networking呈现给“世界其他地方”,内部networking包含所有开发人员工作站和主力服务器。 有一个防火墙阻止来自“其他地方”到内部networking的stream量,但不阻止传出的请求。

$ /sbin/ifconfig eth0 Link encap:Ethernet HWaddr 00:30:18:a5:62:63 inet addr:xxx.yyy.159.36 Bcast:xxx.yyy.159.47 Mask:255.255.255.240 [snip] eth1 Link encap:Ethernet HWaddr 00:02:b3:bd:03:29 inet addr:xxx.zzz.109.65 Bcast:xxx.zzz.109.255 Mask:255.255.255.0 [snip] $ route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface xxx.yyy.159.32 0.0.0.0 255.255.255.240 U 0 0 0 eth0 xxx.zzz.109.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1 0.0.0.0 xxx.yyy.159.33 0.0.0.0 UG 100 0 0 eth0 

Apache正在侦听端口80,sshd在22:

 $ netstat --tcp -a Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 *:www *:* LISTEN tcp 0 0 *:ssh *:* LISTEN [snip] 

从我的开发机器里面,xxx.zzz.109.40,我可以连接到内部地址,一切都很好。 从外面我可以连接到外面的地址,一切工作就像它应该。

但是对于某些types的testing,我想从我的开发机器连接到外部地址,但服务器拒绝连接请求。 我猜测它正在寻找它的路由表,并且由于传入的数据来自应该在eth1上的地址,但是到达eth0的地址正在丢弃它,可能是为了安全防范。

有什么办法可以放松这个限制吗?

奇怪的是,这个过去一直在8.04上工作,但是在8.10或9.04上不能工作,所以在去年的某个时候内核正在做一些额外的检查。 要使连接正常工作,返回path必须与源path相同,这意味着从我的开发机器到达eth0的消息将不得不在eth0上返回,然后路由回到我的机器。


这里是一个图,没有任何地方的NAT。

图表http://i25.tinypic.com/ff37yx.png

假设你没有任何防止这种情况的iptables规则,你需要禁用返回path过滤。 你可以这样做:

 # echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter 

您也可以使用特定的接口名称,而不是所有接口名称,也有一个默认的,这将影响新创build的接口。

从:

反向path滤波器; 这是一个检查,看看是否到达接口的数据包,发送到原始数据包的源地址的数据包是否会在该接口发出; 如果没有,则到达的分组被丢弃。 它可以被认为是一个尝试检测包含欺骗源地址的数据包。

你没有显示你的防火墙configuration,但我敢打赌,有一个规则,在那里做了一些不幸的事情,从内部过滤连接到外部IP地址。 一个严重的NATconfiguration也可能是错误的,但我有麻烦设想的东西如此病态的结果从一个普通的尝试。

只是为了澄清一点,就是因为一个数据包来自一个接口,而另一个接口的IP地址不会导致内核拒绝该数据包。 无论发生什么,这不是内核的错。

另外,stream量的tcpdump(在服务器的内部和外部接口以及客户端上)都将在诊断上有用。

什么是您的开发机器的默认网关? 假设三层交换机/路由器的默认网关应知道如何到达服务器的其他接口。

你应该有类似的东西

 ip route xxx.yyy.159.36 netmask 255.255.255.240 gw xxx.zzz.109.65 

这应该使事情工作。 但是,如果这是不够的,然后使用机器xxx.zzz.109.65启用IP转发

 sysctl net.ipv4.ip_forward = 1 

另外编辑/etc/sysctl.conf并启用ip转发。

确保xxx.zzz.109.65上的filter table的iptables FORWARD链允许为您的开发机器转发数据包。

我猜你正在使用iptables NAT作为你的互联网nat路由器使用该框 – 显然,如果不是这样的话,这将无济于事,否则,你可能需要像这样的东西:

 iptables -t nat -I POSTROUTING -s xxx.zzz.109.0/24 -d xxx.yyy.159.36 -j ACCEPT 

这将跳过你为从内部传输到外部的数据包所做的任何目的地为该服务器的外部IP的任何东西。

只是要肛门,我不会称上述networkingconfiguration多宿主。 它只是在同一个AS内的两个networking之间转发。 在具有单个上游连接提供商的叶networking的情况下,现在的多宿主实际上意味着连接到两个或更多个邻居(AS),或者至less连接到同一上游邻居(AS)的多个路由。

许多有用的想法已经给出。 我会a)仔细检查它不是防火墙/ NAT。 在你的REJECT和DROP规则之前添加一个-j LOG规则,看看有没有可疑的东西被抓到。 b)在两个接口(-i any)上运行tcpdump并查找数据包。

顺便说一句,“服务器拒绝连接请求”是什么意思? 你看到一些(立即)拒绝信息或连接超时吗?

这已经成为您的防火墙规则的一个问题。 最有可能的是,盒子自己的外部IP被“所有外部stream量”所累加,因此不被允许回到内部客户端。 尝试在该IP地址的防火墙规则中添加一个例外; 即明确允许networking服务器的外部IP地址向内部networking发送stream量。

更多的debugging将要求您发布您的防火墙规则。