iptables-目标是将数据包路由到特定接口?

iptables-目标是将数据包路由到特定接口?

我的家庭服务器有两个主要接口,eth1(标准互联网连接)和tun0(OpenVPN 隧道)。我想使用iptables强制 UID 1002 拥有的本地进程生成的所有数据包通过 退出tun0,并强制所有其他数据包通过 退出eth1

我可以轻松标记匹配的数据包:

iptables -A OUTPUT -m owner --uid-owner 1002 -j MARK --set-mark 11

现在,我想在 POSTROUTING 链(可能是 mangle 表)中放置一些规则来匹配标有 11 的数据包并将它们发送到tun0,然后按照规则匹配所有数据包并将它们发送到eth1

我找到了 ROUTE 目标,但它似乎只重写了源接口(除非我读错了)。

ip routeiptables 能做到这一点吗?我是否必须(通过或仅使用旧命令)处理路由表route

编辑:我想也许我应该提供更多信息。我目前没有其他 iptables 规则(尽管我可能会在将来创建一些规则来执行不相关的任务)。此外,输出是ip route

default via 192.168.1.254 dev eth1  metric 203
10.32.0.49 dev tun0  proto kernel  scope link  src 10.32.0.50
85.17.27.71 via 192.168.1.254 dev eth1
192.168.1.0/24 dev eth1  proto kernel  scope link  src 192.168.1.73  metric 203

我没有动过路由表——这只是它目前的样子(尽管它看起来相当脏)。抱歉,但我没有route在这台机器上安装旧命令。

输出如下ip addr(当然,eth0 和 eth2 可以忽略 - 它们是目前未使用的 NIC):

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether 1c:6f:65:2a:73:3f brd ff:ff:ff:ff:ff:ff
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast     state UP qlen 1000
    link/ether 00:1b:21:9d:4e:bb brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.73/24 brd 192.168.1.255 scope global eth1
    inet6 fe80::21b:21ff:fe9d:4ebb/64 scope link
       valid_lft forever preferred_lft forever
4: eth2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether 00:1b:21:6a:c0:4b brd ff:ff:ff:ff:ff:ff
5: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc     pfifo_fast state UNKNOWN qlen 100
    link/none
    inet 10.32.0.50 peer 10.32.0.49/32 scope global tun0

编辑:我已经让一些东西工作了,但它没有将标记的数据包转发到 tun0。基本上,我添加了一个表 (11),并使用:

ip route add table 11 via 10.32.0.49 dev tun0
ip rule add priority 10000 fwmark 11 table 11

当我刚刚 时sudo -u user1000 wget -qO- whatismyip.org,我会得到我家的外部 IP 地址,但如果我这样做sudo -u user1002 wget -qO- whatismyip.org,我也会得到我家的 IP 地址(但我应该得到 OpenVPN 隧道另一端的 IP)。

运行iptables -vL确认数据包符合标记规则,但它们似乎没有遵循路由规则。

编辑:我花了很长时间在这上面,虽然它仍然不起作用,但我认为我已经更接近了。

iptables 规则必须位于mangle表的 OUTPUT 链中。我认为我也需要在表的 POSTROUTING 链中添加 MASQUERADE 规则nat来设置源地址。但是,OUTPUT 的 mangle 之后发生的重新路由无法正常工作。

我已经花了 5 个小时在这上面,所以我要休息一下,可能会在今晚晚些时候或明天的某个时候回来。

答案1

我最近遇到了类似的问题,尽管有点不同。我想路由仅有的通过 OpenVPN tap0 接口的 TCP 端口 25(SMTP),同时通过默认接口路由所有其他流量(即使是同一主机)。

为此,我必须标记数据包并设置处理规则。首先,添加一条规则,使内核通过2表路由带有标记的数据包3(稍后解释):

ip rule add fwmark 2 table 3

您可以为 增加一个符号名/etc/iproute2/rt_tables,但我没有这么做。数字23是随机选择的。事实上,它们可以相同,但为了清楚起见,我在这个例子中没有这样做(尽管我在自己的设置中这样做了)。

添加一条路由,用于通过不同的接口重定向流量,假设网关为10.0.0.1

ip route add default via 10.0.0.1 table 3

非常重要!刷新路由缓存,否则您将得不到响应,只能坐在那里,双手抓着头发几个小时:

ip route flush cache

现在,设置标记指定数据包的防火墙规则:

iptables -t mangle -A OUTPUT -p tcp --dport 465 -j MARK --set-mark 2

上述规则仅适用于数据包来自本地计算机的情况。请参阅http://inai.de/images/nf-packet-flow.png。根据您的要求进行调整。例如,如果您只想通过接口路由传出的 HTTP 流量tap0,请将 465 更改为 80。

为了防止发送的数据包tap0将您的 LAN 地址作为源 IP,请使用以下规则将其更改为您的接口地址(假设10.0.0.2为接口的 IP 地址tap0):

iptables -t nat -A POSTROUTING -o tap0 -j SNAT --to-source 10.0.0.2

最后,放宽反向路径源验证。有人建议您将其设置为0,但2根据https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt。如果您跳过此步骤,您将收到数据包(可以使用 确认tcpdump -i tap0 -n),但数据包不会被接受。更改设置以便数据包被接受的命令:

sysctl -w net.ipv4.conf.tap0.rp_filter=2

答案2

我解决了这个问题。问题出在表 11 中的路由规则上。表 11曾是受到攻击,但路由规则使其无法运行。这个脚本是我现在使用的,它似乎运行良好(尽管它显然特定于我的设置)。此外,我创建了一个专门用于主上行链路(eth1)的新表 21。

# Add relevant iptables entries.
iptables -t mangle -A OUTPUT -m owner --uid-owner 1002 -j MARK --set-mark 11
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE

# Flush ALL THE THINGS.
ip route flush table main
ip route flush table 11
ip route flush table 21
ip rule flush

# Restore the basic rules and add our own.
ip rule add lookup default priority 32767
ip rule add lookup main priority 32766
ip rule add fwmark 11 priority 1000 table 11
# This next rule basically sends all other traffic down eth1.
ip rule add priority 2000 table 21

# Restore the main table.  I flushed it because OpenVPN does weird things to it.
ip route add 127.0.0.0/8 via 127.0.0.1 dev lo
ip route add 192.168.1.0/24 dev eth1 src 192.168.1.73
ip route add default via 192.168.1.254

# Set up table 21.  This sends all traffic to eth1.
ip route add 192.168.1.0/24 dev eth1 table 21
ip route add default via 192.168.1.254 dev eth1 table 21

# Set up table 11.  I honestly don't know why 'default' won't work, or
# why the second line here is needed.  But it works this way.
ip route add 10.32.0.49/32 dev tun0 table 11
ip route add 10.32.0.1 via 10.32.0.50 dev tun0 table 11
ip route add 0.0.0.0/1 via 10.32.0.50 dev tun0 table 11

ip route flush cache

## MeanderingCode 编辑(因为我还不能评论)

谢谢你的回答!这似乎可能会变得很混乱,因为你必须在这里维护路线信息(可能会重复或破坏可能需要设置路线的其他内容)。

您可能会在 OpenVPN 的路由表中遇到“奇怪的事情”,因为服务器配置为“推送”路由,使所有流量都通过 VPN 网络接口而不是“裸”互联网进行路由。或者您的 OpenVPN 配置或任何设置它的脚本/应用程序正在设置路由。

在前一种情况下,您可以编辑您的 OpenVPN 配置并输入包含“route-nopull”的行;
在后一种情况下,检查 OpenVPN 或任何包装器(例如,在许多当前的 Linux 桌面发行版中,network-manager-openvpn)的配置;
在这两种情况下,消除正在设置的路由配置比刷新表更干净、更安全,这取决于您何时运行此脚本以及您的系统正在执行的其他操作。

干杯!

答案3

我想你想要:

/sbin/ip route add default via 10.32.0.49 dev tun0 table 11
/sbin/ip rule add priority 10000 fwmark 11 table 11

http://lartc.org/howto/lartc.netfilter.html

但我还没有测试过上述内容。

答案4

无需使用 iptables 命令即可完成此操作。只需执行一个简单的 ip 命令

对于 uid 1002:

ip rule add uidrange 1002-1002 table 502

然后通过您想要的接口为该表 502 添加一条默认路由,例如:

ip rule add default via a.b.c.d dev eth0

相关内容