根据目的端口在不同接口上输出流量


23

我的问题与“ 仅允许某些接口上的某些出站流量”基本相同。

我有两个接口eth1(10.0.0.2)和wlan0(192.168.0.2)。我的默认路线是eth1。假设我希望所有https-traffic通过wlan0。现在,如果我使用另一个问题中建议的解决方案,则https流量将通过wlan0,但仍将具有eth1(10.0.0.2)的源地址。由于此地址不可用于wlan0网关,因此答案永远不会回来。简单的方法是仅在应用程序中正确设置bind-addr,但在这种情况下不适用。

我认为我需要重写src-addr:

# first mark it so that iproute can route it through wlan0
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# now rewrite the src-addr
iptables -A POSTROUTING -t nat -o wlan0 -p tcp --dport 443 -j SNAT --to 192.168.0.2

现在tcpdump看到传出的数据包很好,传入的数据包到达192.168.0.2,但是它们可能永远都不会结束在应用程序中,因为我所看到的只是应用程序正在重新发送SYN数据包,尽管SYN-已经收到ACK。

所以我想,也许我也需要重写传入地址:

iptables -A PREROUTING -t nat -i wlan0 -p tcp --sport 443 -j DNAT --to 10.0.0.2

但这也不起作用。所以我有点卡在这里。有什么建议么?

Answers:


24

你近了

应用程序看不到返回流量的实际原因是由于内核的内置IP欺骗保护。即,返回流量与路由表不匹配,因此被丢弃。您可以通过关闭欺骗保护来解决此问题,如下所示:

sudo sysctl net.ipv4.conf.wlan0.rp_filter=0

但是我不推荐它。更合适的方法是创建备用路由实例。

  1. 该标记是必需的。收下。
  2. 源NAT也很有必要。
  3. 最终的DNAT是不必要的,因此您可以将其删除。

确保已iproute安装软件包。如果您有该ip命令,则可以进行设置(看起来像您所做的,但是如果没有,请先设置)。

/etc/iproute2/rt_tables通过添加以下行来编辑并添加新表:

200 wlan-route

然后,您需要配置以wlan-route默认网关命名的新路由表,并创建规则以有条件地将流量发送到该表。我假设您的默认网关为192.168.0.1。自然,这需要匹配您的实际网络,而不仅仅是我的假设。

ip route add default via 192.168.0.1 dev wlan0 table wlan-route
ip rule add fwmark 0x1 table wlan-route

最终带注释的脚本如下所示:

# Populate secondary routing table
ip route add default via 192.168.0.1 dev wlan0 table wlan-route
# Anything with this fwmark will use the secondary routing table
ip rule add fwmark 0x1 table wlan-route
# Mark these packets so that iproute can route it through wlan-route
iptables -A OUTPUT -t mangle -o eth1 -p tcp --dport 443 -j MARK --set-mark 1
# now rewrite the src-addr
iptables -A POSTROUTING -t nat -o wlan0 -p tcp --dport 443 -j SNAT --to 192.168.0.2

感谢您抽出宝贵的时间对此进行研究。但是,这已经是我正在使用的(如另一个问题中所述),所以我设置了其他路由,但仍然相同。SYN-ACK返回到192.168.0.2,但显然从未到达应用程序。
伦佩尔

返回并再次阅读我的答案。我解决了。
bahamat 2011年

有关欺骗保护的部分?尝试后仍然没有变化。抱歉,来回读了几次,但还没有得到我所缺少的内容。
伦佩尔

您需要srcip route命令中添加一个选项以指定正确的源地址。
David Schwartz

@DavidSchwartz:POSTROUTING SNAT会的。
bahamat 2011年

8

巴哈马特的解决方案是正确的;但是,请注意,让我完成此工作的唯一方法是禁用系统中每个接口的rp_filter,而不仅是NAT中涉及的两个接口(在这种情况下为eth1和wlan0)。

for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > $f; done
echo 1 > /proc/sys/net/ipv4/route/flush

(请参阅本页末尾的重要说明:“ 高级路由方法” -此处发布的链接已不存在,但我是通过Wayback机器找到的)


感谢您的回答,考虑到您的回答,我也只能让bahamats解决方案起作用。
Dynalon 2014年

对我来说,在相当标准的ubuntu 12.04 LTS盒子上,除了禁用rp_filter和刷新路由缓存外,我还不得不从iptables参数中删除接口名称。没有足够的时间调查原因。
Costin Gușă 2014年

0

一个建议:您应该始终使用--sport而不是--dport在输出链中使用。

NAT会改变dport,这将使您的规则难以理解。


2
我有没有得到的东西?dport和目标端口一样,无法更改。这是会话尝试访问的服务的端口,例如http,ssh,smtp。您可能对运动和运动感到困惑,或者我缺少明显的东西。:P
某人

0

我认为以下是必要的:

ip ru add from 192.168.0.2 table 3 prio 300
ip ro add table 3 default via 192.168.0.1 dev wlan0
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.