为新的VPN连接设置路由和iptables,以仅重定向**端口80和443


8

我有一个新的VPN连接(使用openvpn),可以绕一些ISP限制进行路由。尽管运行良好,但它正在通过VPN 接收所有流量。这给我带来了下载问题(我的互联网连接速度比vpn允许的快得多)和远程访问问题。我运行ssh服务器,并运行一个守护进程,该守护进程允许我通过手机调度下载。

我在eth0上有我现有的以太网连接,在tun0上有新的VPN连接。

我相信我需要设置默认路由以在192.168.0.0/24网络上使用现有的eth0连接,并将默认网关设置为192.168.0.1(我的知识很不稳定,因为多年以来我都没有这样做)。如果是正确的话,那么我不确定该怎么做!我当前的路由表是:

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface    MSS   Window irtt
0.0.0.0         10.51.0.169     0.0.0.0         UG    0      0        0 tun0     0     0      0
10.51.0.1       10.51.0.169     255.255.255.255 UGH   0      0        0 tun0     0     0      0
10.51.0.169     0.0.0.0         255.255.255.255 UH    0      0        0 tun0     0     0      0
85.25.147.49    192.168.0.1     255.255.255.255 UGH   0      0        0 eth0     0     0      0
169.254.0.0     0.0.0.0         255.255.0.0     U     1000   0        0 eth0     0     0      0
192.168.0.0     0.0.0.0         255.255.255.0   U     1      0        0 eth0     0     0      0

修复路由之后,我相信我需要使用iptables来配置预路由或伪装,以将目标端口80或443的所有内容强制通过tun0。同样,我不确定如何执行此操作!

我在互联网上找到的所有内容都在尝试做更复杂的事情,并且尝试从树木中分拣木材是困难的。

任何帮助将非常感激。

更新

到目前为止,我已经从各种渠道搜集了以下内容:

#!/bin/sh

DEV1=eth0
IP1=`ifconfig|perl -nE'/dr:(\S+)/&&say$1'|grep 192.`
GW1=192.168.0.1
TABLE1=internet
TABLE2=vpn
DEV2=tun0
IP2=`ifconfig|perl -nE'/dr:(\S+)/&&say$1'|grep 10.`
GW2=`route -n | grep 'UG[ \t]' | awk '{print $2}'`

ip route flush table $TABLE1
ip route flush table $TABLE2
ip route show table main | grep -Ev ^default | while read ROUTE ; do
    ip route add table $TABLE1 $ROUTE
    ip route add table $TABLE2 $ROUTE
done
ip route add table $TABLE1 $GW1 dev $DEV1 src $IP1
ip route add table $TABLE2 $GW2 dev $DEV2 src $IP2
ip route add table $TABLE1 default via $GW1
ip route add table $TABLE2 default via $GW2

echo "1" > /proc/sys/net/ipv4/ip_forward
echo "1" > /proc/sys/net/ipv4/ip_dynaddr

ip rule add from $IP1 lookup $TABLE1
ip rule add from $IP2 lookup $TABLE2
ip rule add fwmark 1 lookup $TABLE1
ip rule add fwmark 2 lookup $TABLE2

iptables -t nat -A POSTROUTING -o $DEV1 -j SNAT --to-source $IP1
iptables -t nat -A POSTROUTING -o $DEV2 -j SNAT --to-source $IP2

iptables -t nat -A PREROUTING           -m state --state ESTABLISHED,RELATED          -j CONNMARK --restore-mark
iptables        -A OUTPUT               -m state --state ESTABLISHED,RELATED          -j CONNMARK --restore-mark
iptables -t nat -A PREROUTING -i $DEV1  -m state --state NEW                          -j CONNMARK --set-mark 1
iptables -t nat -A PREROUTING -i $DEV2  -m state --state NEW                          -j CONNMARK --set-mark 2
iptables -t nat -A PREROUTING           -m connmark --mark 1                          -j MARK --set-mark 1
iptables -t nat -A PREROUTING           -m connmark --mark 2                          -j MARK --set-mark 2
iptables -t nat -A PREROUTING           -m state --state NEW -m connmark ! --mark 0   -j CONNMARK --save-mark

iptables -t mangle -A PREROUTING -i $DEV2 -m state --state NEW -p tcp --dport  80 -j CONNMARK --set-mark 2
iptables -t mangle -A PREROUTING -i $DEV2 -m state --state NEW -p tcp --dport 443 -j CONNMARK --set-mark 2

route del default
route add default gw 192.168.0.1 eth0

现在,这似乎正在工作。除非不是!

与被阻止网站连接正在通过,不在端口80和443 的连接正在使用非VPN连接。

但是连接到被阻止网站的端口80和443连接也正在使用非VPN连接!

当达到了总体目标时,我相对感到高兴,但是很高兴知道为什么它无法正常运行。

有任何想法吗?

作为参考,我现在有3个路由表,主要,互联网和VPN。它们的列表如下...

主要:

default via 192.168.0.1 dev eth0 
10.38.0.1 via 10.38.0.205 dev tun0 
10.38.0.205 dev tun0  proto kernel  scope link  src 10.38.0.206 
85.removed via 192.168.0.1 dev eth0 
169.254.0.0/16 dev eth0  scope link  metric 1000 
192.168.0.0/24 dev eth0  proto kernel  scope link  src 192.168.0.73  metric 1 

互联网:

default via 192.168.0.1 dev eth0 
10.38.0.1 via 10.38.0.205 dev tun0 
10.38.0.205 dev tun0  proto kernel  scope link  src 10.38.0.206 
85.removed via 192.168.0.1 dev eth0 
169.254.0.0/16 dev eth0  scope link  metric 1000 
192.168.0.0/24 dev eth0  proto kernel  scope link  src 192.168.0.73  metric 1 
192.168.0.1 dev eth0  scope link  src 192.168.0.73

VPN:

default via 10.38.0.205 dev tun0 
10.38.0.1 via 10.38.0.205 dev tun0 
10.38.0.205 dev tun0  proto kernel  scope link  src 10.38.0.206 
85.removed via 192.168.0.1 dev eth0 
169.254.0.0/16 dev eth0  scope link  metric 1000 
192.168.0.0/24 dev eth0  proto kernel  scope link  src 192.168.0.73  metric 1

上面的脚本确实按预期工作。我只是希望看到流量来自netstat中的10.地址。但是,所有流量都来自192。,但端口80和443通过VPN定向。我将整个解决方案作为一个答案,但是@anttir的建议是iproute2和fwmark的建议。我没有遇到过,没有它们,我仍然会把头撞在砖墙上!
史蒂夫

Answers:


4

因此,以上大部分内容,但是整个解决方案如下:

编辑/ etc / iproute2 / rt_tables并在底部添加2行:

101 internet
102 vpn

您可以为这些表赋予其他更有意义的名称,只是保持一致。

然后您需要在/etc/init.d中创建一个脚本(我称其为rt_setup)

#!/bin/sh

DEV1=eth0
IP1=`ifconfig|perl -nE'/dr:(\S+)/&&say$1'|grep 192.`
GW1=192.168.0.1
TABLE1=internet
TABLE2=vpn
DEV2=tun0
IP2=`ifconfig|perl -nE'/dr:(\S+)/&&say$1'|grep 10.`
GW2=`route -n | grep 'UG[ \t]' | awk '{print $2}'`

ip route flush table $TABLE1
ip route flush table $TABLE2
ip route show table main | grep -Ev ^default | while read ROUTE ; do
    ip route add table $TABLE1 $ROUTE
    ip route add table $TABLE2 $ROUTE
done
ip route add table $TABLE1 $GW1 dev $DEV1 src $IP1
ip route add table $TABLE2 $GW2 dev $DEV2 src $IP2
ip route add table $TABLE1 default via $GW1
ip route add table $TABLE2 default via $GW2

echo "1" > /proc/sys/net/ipv4/ip_forward
echo "1" > /proc/sys/net/ipv4/ip_dynaddr

ip rule add from $IP1 lookup $TABLE1
ip rule add from $IP2 lookup $TABLE2
ip rule add fwmark 1 lookup $TABLE1
ip rule add fwmark 2 lookup $TABLE2

iptables -t nat -A POSTROUTING -o $DEV1 -j SNAT --to-source $IP1
iptables -t nat -A POSTROUTING -o $DEV2 -j SNAT --to-source $IP2

iptables -t nat -A PREROUTING           -m state --state ESTABLISHED,RELATED          -j CONNMARK --restore-mark
iptables        -A OUTPUT               -m state --state ESTABLISHED,RELATED          -j CONNMARK --restore-mark
iptables -t nat -A PREROUTING -i $DEV1  -m state --state NEW                          -j CONNMARK --set-mark 1
iptables -t nat -A PREROUTING -i $DEV2  -m state --state NEW                          -j CONNMARK --set-mark 2
iptables -t nat -A PREROUTING           -m connmark --mark 1                          -j MARK --set-mark 1
iptables -t nat -A PREROUTING           -m connmark --mark 2                          -j MARK --set-mark 2
iptables -t nat -A PREROUTING           -m state --state NEW -m connmark ! --mark 0   -j CONNMARK --save-mark

iptables -t mangle -A PREROUTING -i $DEV2 -m state --state NEW -p tcp --dport  80 -j CONNMARK --set-mark 2
iptables -t mangle -A PREROUTING -i $DEV2 -m state --state NEW -p tcp --dport 443 -j CONNMARK --set-mark 2

route del default
route add default gw 192.168.0.1 eth0

然后,显然,从/etc/rc2.d链接它(我使用ubuntu,运行级别可能与您有所不同)。确保给它一个比openvpn链接的S号!

该脚本可以做很多事情。顶部设置变量,并使用一些perl和awk语句来选择动态IP和网关地址。第二部分清理您在ipruote2中设置的表,并将当前路由表复制到其中。然后,它会创建两条新路由,以及两条新的默认网关,其中一条通过VPN,一条通过我的本地网络。

我不认为接下来的两行是必需的,但是它们使ip转发可以在iptables中使用。

接下来,该脚本会创建一些规则,用于在哪里查找源自相关IP地址的流量,以及在何处查找流量是否经过专门标记。

POSTROUTING和PREROUTING确保来自地址的流量得到答复!

最终的iptables PREROUTING是标记流量的部分,并确保将进入端口80或443的所有内容标记为使用表2(VPN)

最后两行从默认路由表中删除VPN网关,然后重新添加我的本地网络网关。

就目前而言,该过程非常出色。VPN在计算机启动时启动,此脚本在几秒钟后运行(我可以添加一个sleep语句,以确保在运行此脚本之前VPN已完全初始化)。我的远程访问连接(SSH等)工作良好。我没有连接到端口80或443的连接正在使用我的本地连接,但是所有Web流量都通过VPN,并且绕过了ISP所设置的控件!

正如我在问题的评论中所说的那样,如果没有@anttir的建议,我什至不会开始研究这条路线。在该建议的支持下,站点http://blog.khax.net/2009/11/28/multi-gateway-routing-with-iptables-and-iproute2/http://linux-ip.net/ html / adv-multi-internet.html非常有用(即使代码不是100%完成!)


1
最后一项添加是,我确实sleep 20在脚本顶部添加了a ,因为openvpn连接未及时完成。我还添加echo 2 > /proc/sys/net/ipv4/conf/tun0/rp_filter了脚本,因为有必要禁用tun0的反向数据包筛选器。当从tun0返回带有源地址S的答复时,反向数据包过滤器将检查“如果我将数据包路由到地址S,并且不会通过tun0,我将丢弃该数据包”-并且因为这样做查找没有有效的fwmark,它确定路由将是通常的默认路由,因此将数据包丢弃。
史蒂夫

我必须编辑您的脚本才能使其适合我。最后一行route add default gw 192.168.0.1 eth0似乎将端口80/443流量路由通过本地网关,而不是通过预期的tun0。将最后一行更改为route add default tun0似乎对我有用。

1

每个协议的路由有点复杂。通常,路由表用于根据目标IP检查网关,并使用openvpn或192.168.0.1默认网关。

在VPN的另一端设置例如Squid http代理,并将浏览器设置为使用代理会更容易。

您不会使用iptables,因为它会更改HTTP连接的目标IP,并且无法正常工作。

您可以创建一个默认路由设置为VPN端点的新路由表(/ etc / iproute2 / rt_tables),使用iptables fwmark(-j MARK)标记所有HTTP数据包,然后使用ip规则为该规则创建自定义规则。标记的软件包以使用新的路由表。


谢谢你的帮助。我一定会看看这些。事情有些棘手,因为我无法控制服务器端,而我却无法控制。另外,我不能使用鱿鱼,因为我需要通过连接路由https流量,而squid不能很好地工作。
史蒂夫

在VPN上路由几个IP以及在VPN之外的世界其他地方如何路由?
2011年

我确实考虑过仅路由几个IP,但是列表随着站点的移动而变化,因此我需要使其易于在PC上的其他用户使用。我已经开始研究设置新的路由表并标记数据包。标记数据包很容易,这是我不太确定的路由表。我可以为看起来正确的VPN设置一个,为看起来正确的其他设置一个,但是我不确定对main做什么,因为main仍然设置为默认值(哪个是VPN)。仍在播放...
Steve

linux-ip.net/html/adv-multi-internet.html ip规则显示和ip规则添加fwmark 4表4优先级10000
AnttiRytsölä11年

添加了对原始内容的更新,详细说明了到目前为止的工作!啊!刚刚意识到我已经编辑了您的答案,而不是我的问题。抱歉! 没用太多,也没意识到我可以编辑别人的答案!
史蒂夫
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.