Ste*_*eve 8 linux routing openvpn iptables
我有一个新的 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
Run Code Online (Sandbox Code Playgroud)
修复路由后,我相信我需要使用 iptables 来配置预路由或伪装以通过 tun0 强制目标端口 80 或 443 的所有内容。同样,我不完全确定如何做到这一点!
我在互联网上找到的所有东西都试图做一些更复杂的事情,而试图从树上分拣木材被证明是困难的。
任何帮助将非常感激。
更新
到目前为止,从各种来源,我拼凑了以下内容:
#!/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
Run Code Online (Sandbox Code Playgroud)
现在这似乎奏效了。除了它不是!
与被阻止网站的连接正在通过,不在端口 80 和 443上的连接正在使用非 VPN 连接。
但是,未连接到被阻止网站的端口 80 和 443 连接也在使用非 VPN 连接!
由于达到了总体目标,我比较高兴,但很高兴知道为什么它不能完全正确地工作。
有任何想法吗?
作为参考,我现在有 3 个路由表,main、internet 和 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
Run Code Online (Sandbox Code Playgroud)
互联网:
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
Run Code Online (Sandbox Code Playgroud)
虚拟专用网:
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
Run Code Online (Sandbox Code Playgroud)
所以,大部分内容都在上面,但整个解决方案如下:
编辑 /etc/iproute2/rt_tables 并在底部添加 2 行:
101 internet
102 vpn
Run Code Online (Sandbox Code Playgroud)
您可以为这些表指定其他更有意义的名称,但要保持一致。
然后你需要在/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
Run Code Online (Sandbox Code Playgroud)
然后,显然,从 /etc/rc2.d 链接它(我使用 ubuntu,运行级别可能与你不同)。确保您给它的 S 编号高于openvpn 链接!
该脚本做了很多事情。顶部部分设置变量,使用一些 perl 和 awk 语句来获取动态 IP 和网关地址。第二部分清理您在 ipruote2 中设置的表,并将当前路由表复制到其中。然后,它会创建两条新路由和两个默认网关,其中 VPN 路由通过 VPN,互联网路由通过我的本地网络。
我不相信接下来的两行是必要的,但它们启用了 ip 转发以在 iptables 中使用。
接下来,脚本创建一些规则,规定在哪里查找源自相关 IP 地址的流量,以及在哪里查找流量(如果流量经过专门标记)。
POSTROUTING 和 PREROUTING 确保来自某个地址的流量得到回复!
最后的 iptables PREROUTING 是标记流量的部分,并确保任何前往端口 80 或 443 的内容都被标记为使用表 2 (VPN)
最后两行从默认路由表中删除 VPN 网关,并添加回我的本地网络网关。
就目前情况而言,这个过程非常顺利。VPN 在机器启动时启动,并且该脚本在几秒钟后运行(我可能添加一个睡眠语句只是为了确保 VPN 在运行该脚本之前完全初始化)。我的远程访问连接(ssh 等)运行良好。我不连接到端口 80 或 443 的连接正在使用我的本地连接,但所有网络流量都通过 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% 完整!)
归档时间: |
|
查看次数: |
13381 次 |
最近记录: |