![我如何强制所有互联网流量通过 PPTP VPN 但仍允许本地局域网访问?](https://linux22.com/image/588808/%E6%88%91%E5%A6%82%E4%BD%95%E5%BC%BA%E5%88%B6%E6%89%80%E6%9C%89%E4%BA%92%E8%81%94%E7%BD%91%E6%B5%81%E9%87%8F%E9%80%9A%E8%BF%87%20PPTP%20VPN%20%E4%BD%86%E4%BB%8D%E5%85%81%E8%AE%B8%E6%9C%AC%E5%9C%B0%E5%B1%80%E5%9F%9F%E7%BD%91%E8%AE%BF%E9%97%AE%EF%BC%9F.png)
我有一台运行 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 是直接连接的,因此它比默认网关具有优先级。