rum*_*pel 27 linux networking routing iptables
我的问题与仅允许某些接口上的某些出站流量基本相同。
我有两个接口eth1(10.0.0.2) 和wlan0(192.168.0.2)。我的默认路由是eth1. 假设我希望所有 https 流量都通过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
Run Code Online (Sandbox Code Playgroud)
现在 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
Run Code Online (Sandbox Code Playgroud)
但这也不起作用。所以我有点卡在这里。有什么建议?
bah*_*mat 27
你很接近。
应用程序看不到返回流量的实际原因是内核内置的 IP 欺骗保护。即,返回流量与路由表不匹配,因此被丢弃。您可以通过关闭这样的欺骗保护来解决这个问题:
sudo sysctl net.ipv4.conf.wlan0.rp_filter=0
Run Code Online (Sandbox Code Playgroud)
但我不会推荐它。更合适的方法是创建一个备用路由实例。
确保您已iproute安装该软件包。如果你有ip命令,那么你就设置好了(看起来你有,但如果没有先得到它)。
/etc/iproute2/rt_tables通过附加以下行来编辑并添加一个新表:
200 wlan-route
Run Code Online (Sandbox Code Playgroud)
然后,您需要配置以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
Run Code Online (Sandbox Code Playgroud)
您的最终注释脚本如下所示:
# 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
Run Code Online (Sandbox Code Playgroud)
小智 10
巴哈马的解决方案是正确的;但是,请注意,让我完成这项工作的唯一方法是禁用系统中每个接口的 rp_filter,而不仅仅是 NATing 中涉及的两个接口(在本例中为 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
Run Code Online (Sandbox Code Playgroud)
(请参阅本页末尾的重要说明:Advanced Routing Howto -- 此处发布的链接已不存在,但我是通过回溯机找到的)