我如何强制所有互联网流量通过 PPTP VPN 但仍允许本地局域网访问?

我如何强制所有互联网流量通过 PPTP VPN 但仍允许本地局域网访问?

我有一台运行 Linux Mint 12 的服务器,我想让它始终连接到 PPTP VPN。VPN 服务器非常可靠,但偶尔会掉线,所以我只想让它在 VPN 连接中断时禁用所有互联网活动。

我还想找到一种方法来自动重新启动它,但这不是什么大问题,因为这种情况很少发生。

我还希望始终能够从我的局域网连接到该盒子,无论 VPN 是否启动。

当 VPN 正确连接时,我的 ifconfig 如下所示:

eth0      Link encap:Ethernet  HWaddr 00:22:15:21:59:9a  
          inet addr:192.168.0.171  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::222:15ff:fe21:599a/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:37389 errors:0 dropped:0 overruns:0 frame:0
          TX packets:29028 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:37781384 (37.7 MB)  TX bytes:19281394 (19.2 MB)
          Interrupt:41 Base address:0x8000 

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:1446 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1446 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:472178 (472.1 KB)  TX bytes:472178 (472.1 KB)

tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          inet addr:10.10.11.10  P-t-P:10.10.11.9  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:14 errors:0 dropped:0 overruns:0 frame:0
          TX packets:23 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100 
          RX bytes:1368 (1.3 KB)  TX bytes:1812 (1.8 KB)

这是我在其他地方找到的 iptables 脚本,它似乎是针对我试图解决的问题,但它最终阻止了所有访问,但我不确定需要更改什么:

#!/bin/bash

#Set variables
IPT=/sbin/iptables
VPN=`ifconfig|perl -nE'/dr:(\S+)/&&say$1'|grep 10.`
LAN=192.168.0.0/24

#Flush rules
$IPT -F
$IPT -X

#Default policies and define chains
$IPT -P OUTPUT DROP
$IPT -P INPUT DROP
$IPT -P FORWARD DROP

#Allow input from LAN and tun0 ONLY
$IPT -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A INPUT -i tun0 -m conntrack --ctstate NEW -j ACCEPT
$IPT -A INPUT -s $LAN -m conntrack --ctstate NEW -j ACCEPT
$IPT -A INPUT -j DROP

#Allow output from lo and tun0 ONLY
$IPT -A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT
$IPT -A OUTPUT -o tun0 -m conntrack --ctstate NEW -j ACCEPT
$IPT -A OUTPUT -d $VPN -m conntrack --ctstate NEW -j ACCEPT
$IPT -A OUTPUT -j DROP
exit 0

感谢您的帮助。

答案1

这些 iptables 规则不允许流量到达 VPN 服务器,因此无法建立 VPN。您需要在链中的OUTPUT最后一条DROP规则之前添加以下规则,其中 1.2.3.4 是 VPN 服务器的 IP 地址。这些规则允许 TCP 连接到端口 1723(PPTP 控制通道)和 GRE 数据包(数据通道)。

iptables --append OUTPUT --destination 1.2.3.4 --protocol tcp --dport 1723 --jump ACCEPT
iptables --append OUTPUT --destination 1.2.3.4 --protocol gre --jump ACCEPT

答案2

有两种方法可以实现此目的:基于路由和基于防火墙。

路由方法

未连接到 VPN 的机器的典型路由表如下所示:

10.23.11.0/24 dev eth0
default via 10.23.11.1

第一条路由通往 LAN 上的主机,第二条路由将其他所有路由发送到默认网关。连接到 VPN 时,路由表如下所示(其中 1.2.3.4 是 VPN 服务器的公共 IP,10.8.0.1 是 VPN 服务器的私有 IP):

10.23.11.0/24 dev eth0
1.2.3.4 via 10.23.11.1
default via 10.8.0.1

第一条路由相同,第三条路由是通过 VPN 发送所有内容。但请注意第二条规则:它规定要到达 VPN 服务器的公共 IP,数据包应通过默认网关发送。这样 VPN 客户端创建的隧道数据包才能真正到达服务器;如果没有此路由,VPN 客户端创建的数据包将再次通过 VPN 发送,并且永远不会到达服务器。

现在,如果删除第三条路由,那么发往 Internet 上除 VPN 服务器之外任何地方的数据包都将没有匹配的路由,因此主机永远不会将它们发送出去。因此,我们希望当 VPN 未连接时,路由表如下所示:

10.23.11.0/24 dev eth0
1.2.3.4 via 10.23.11.1

LAN 上的主机仍可访问,VPN 服务器仍可访问(因为我们需要能够启动 VPN),但其他所有内容都无法路由出去。不过,完成此设置可能有点棘手,特别是如果您使用 DHCP。/etc/network/interfaces然而,Debian 上的静态配置将涉及以下内容:

auto eth0
iface eth0 inet static
    address 10.23.11.10
    netmask 255.255.255.0
    up ip route add 1.2.3.4 via 10.23.11.1

请注意,没有gateway声明,因为这是安装默认路由。

这种方法的缺点是,非 VPN 流量仍允许以未加密的形式传出 VPN 服务器。如果您在 VPN 服务器上运行其他服务,并且需要确保它们受到保护,那么您必须使用防火墙方法。

编辑:@JamesRyan 认为这种方法很脆弱,因为默认路由可能会自动或意外添加。另一种方法是添加黑洞路由,将流量发送到某个不会再路由的地方。但是,这不适用于自动添加的默认路由,因为它已经使用了最高优先级度量 0。仍然需要删除默认路由,但可以添加类似以下内容。

default via 127.255.255.255

防火墙方法

此处的想法是阻止物理接口上的所有传出流量,但 VPN 客户端创建的隧道流量和发往 LAN 的流量除外。允许 VPN 的流量取决于所使用的协议。PPTP 使用 TCP 端口 1723 作为控制通道,并且研究生入学考试 (GRE)作为实际隧道。OpenVPN 使用 UDP 端口 1194。防火墙规则如下所示:

iptables --append OUTPUT --out-interface eth0 --destination 10.23.11.0/24 --jump ACCEPT
iptables --append OUTPUT --out-interface eth0 --destination 1.2.3.4 --protocol tcp --dport 1723 --jump ACCEPT
iptables --append OUTPUT --out-interface eth0 --destination 1.2.3.4 --protocol gre --jump ACCEPT
iptables --append OUTPUT --out-interface eth0 --jump REJECT

第一条规则接受 LAN 的流量。第二条和第三条规则接受到 VPN 服务器的 VPN 流量。第四条规则拒绝离开物理接口的所有其他流量。

如果您使用的 DNS 服务器不在 LAN 上,您可能需要接受的另一件事是 DNS,因为 VPN 客户端可能需要执行 DNS 查找才能找到 VPN 服务器。在之前插入以下规则将REJECT允许 DNS 流量流向 Google 的公共 DNS 服务。

iptables --append OUTPUT --out-interface eth0 --destination 8.8.8.8 --protocol udp --dport 53 --jump ACCEPT

答案3

添加另一个指向空接口的具有更高度量的默认路由。当 VPN 不可用时,第二条路由将启动并将流量黑洞化

答案4

这不是一个 iptables 问题 — — 您不需要 iptables。

只需设置默认路由以通过 VPN,您就大功告成了。您还可以添加另一个具有较差度量的默认路由,以便在 VPN 发生故障时使用。

您的 LAN 是直接连接的,因此它比默认网关具有优先级。

相关内容