我的家庭服务器有两个主要的接口, 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
。
我find了ROUTE目标,但似乎只是重写了源接口(除非我正确读取它)。
是iptables能够吗? 我必须乱搞路由表(通过ip route
或只是传统的route
命令),而不是?
编辑:我想也许我应该提供更多的信息。 目前我还没有其他的iptables规则(虽然我可能会创build一些规则来执行未来不相关的任务)。 另外, 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
我还没有碰到路由表 – 这就是目前的情况(虽然看起来很脏)。 对不起,我没有在这台机器上安装legacy 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
编辑:我已经得到了一些sorta工作,但它不转发标记数据包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链中。 我想我也需要在nat
表的POSTROUTING链中使用MASQUERADE规则来设置源地址。 但是,在OUTPUT的mangle之后发生的重新路由不能正常工作。
现在我花了5个小时,所以我rest一下,可能会在今天晚些时候或明天的某个时候返回。
我最近遇到了类似的问题,虽然略有不同。 我只想通过OpenVPN tap0接口路由TCP端口25(SMTP),而通过默认接口路由所有其他stream量(即使是相同的主机)。
为此,我必须标记数据包并设置处理规则。 首先,添加一个规则,使内核路由数据包标记为2
到表3
(稍后解释):
ip rule add fwmark 2 table 3
你可以在/etc/iproute2/rt_tables
添加一个符号名,但是我没有这么做。 数字2
和3
是随机select的。 事实上,这些可以是相同的,但为了清楚起见,我没有在这个例子中做到这一点(虽然我在我自己的设置中)。
假设网关为10.0.0.1
,则添加一个路由以将stream量redirect到另一个接口:
ip route add default via 10.0.0.1 table 3
很重要! 冲洗你的路由caching,否则你将不会得到回应,并用手在头发上坐几个小时:
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 。 调整到您的要求。 例如,如果您只想通过tap0
接口路由出站HTTPstream量,请将465更改为80。
要防止通过tap0
发送的数据包将您的LAN地址作为源IP,请使用以下规则将其更改为您的接口地址(假设接口tap0
IP地址为10.0.0.2
):
iptables -t nat -A POSTROUTING -o tap0 -j SNAT --to-source 10.0.0.2
最后,放松反向path源validation。 有些人build议你把它设置为0
,但是根据https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt,2似乎是更好的select。 如果你跳过这个,你会收到数据包(这可以使用tcpdump -i tap0 -n
来确认),但数据包不被接受。 该命令改变设置,使数据包得到接受:
sysctl -w net.ipv4.conf.tap0.rp_filter=2
我解决了这个问题 问题在于表11中的路由规则。表11 正在受到攻击,但路由规则使其无法运行。 这个脚本是我现在使用的,它似乎工作得很好(虽然这显然是特定于我的设置)。 另外,我创build了一个专用于主要上行链路(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的路由表中遇到“奇怪的事情”,因为服务器被configuration为“推送”路由,使所有stream量都能通过VPNnetworking接口而不是“裸露的”互联网。 或者你的OpenVPNconfiguration或者任何脚本/应用程序设置它是设置路由。
在前一种情况下,你可以编辑你的OpenVPNconfiguration,并把一行包含“route-nopull”
在后者中,检查configurationOpenVPN或任何包装(networkingpipe理器openvpn,例如在许多当前的Linux桌面发行版)
无论哪种情况,取消设置的路由configuration都比清空表更安全,这取决于您何时运行此脚本以及您的系统正在做什么。干杯!
我想你想要:
/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
但是我没有testing过以上。
这可以通过iptables命令执行简单的ip命令来完成
对于1002:
ip rule add uidrange 1002-1002 table 502
通过你想说的接口添加表502的默认路由
eth0 ip rule add default via abcd dev eth0