Answers:
我有相同的设置,“ VPN终止开关”比人们想象的要棘手。
不过,按照您的规范(读为“当VPN崩溃时杀死某些应用程序”),有一个简单的解决方案。
在Ubuntu上,网络监视器具有用于网络事件的回调,因此您可以编写脚本来杀死所需的应用程序。示例如下:
编辑/etc/NetworkManager/dispatcher.d/50vpndownkillapps.rb
:
#!/usr/bin/env ruby
if ARGV == [ 'tun0', 'vpn-down' ]
`pkill -f transmission`
`pkill -f deluge`
end
使它可执行:chmod 755 /etc/NetworkManager/dispatcher.d/50vpndownkillapps.rb
,然后享受:-)
该脚本使用Ruby(因此需要ruby),但是可以轻松转换为Shell脚本。
它还假定VPN适配器为tun0
,这是OpenVPN配置的标准。
我有同样的需求,我开发了自己的解决方案,因为在Linux上似乎没有专用的工具。无需删除/关闭打开的应用程序!:)
您需要设置iptables防火墙,以便您的计算机只能连接到指定的VPN服务器(除本地以外,不允许其他流量,因此不会有“泄漏”)。这是一个脚本(在网络上找到):
#!/bin/bash
# iptables setup on a local pc
# dropping all traffic not going trough vpn
# allowes traffic in local area network
# special rules for UPNP and Multicast discovery
FW="/sbin/iptables"
LCL="192.168.1.0/24"
VPN="10.0.0.0/12"
local_interface="eno1"
virtual_interface="tun0"
# VPN Servers
servers=(
123.123.123.123
124.124.124.124
)
#---------------------------------------------------------------
# Remove old rules and tables
#---------------------------------------------------------------
echo "Deleting old iptables rules..."
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
echo "Setting up new rules..."
#---------------------------------------------------------------
# Default Policy - Drop anything!
#---------------------------------------------------------------
$FW -P INPUT DROP
$FW -P FORWARD DROP
$FW -P OUTPUT DROP
#---------------------------------------------------------------
# Allow all local connections via loopback.
#---------------------------------------------------------------
$FW -A INPUT -i lo -j ACCEPT
$FW -A OUTPUT -o lo -j ACCEPT
#---------------------------------------------------------------
# Allow Multicast for local network.
#---------------------------------------------------------------
$FW -A INPUT -j ACCEPT -p igmp -s $LCL -d 224.0.0.0/4 -i $local_interface
$FW -A OUTPUT -j ACCEPT -p igmp -s $LCL -d 224.0.0.0/4 -o $local_interface
#---------------------------------------------------------------
# UPnP uses IGMP multicast to find media servers.
# Accept IGMP broadcast packets.
# Send SSDP Packets.
#---------------------------------------------------------------
$FW -A INPUT -j ACCEPT -p igmp -s $LCL -d 239.0.0.0/8 -i $local_interface
$FW -A OUTPUT -j ACCEPT -p udp -s $LCL -d 239.255.255.250 --dport 1900 -o $local_interface
#---------------------------------------------------------------
# Allow all bidirectional traffic from your firewall to the
# local area network
#---------------------------------------------------------------
$FW -A INPUT -j ACCEPT -s $LCL -i $local_interface
$FW -A OUTPUT -j ACCEPT -d $LCL -o $local_interface
#---------------------------------------------------------------
# Allow all bidirectional traffic from your firewall to the
# virtual privat network
#---------------------------------------------------------------
$FW -A INPUT -j ACCEPT -i $virtual_interface
$FW -A OUTPUT -j ACCEPT -o $virtual_interface
#---------------------------------------------------------------
# Connection to VPN servers (UDP 443)
#---------------------------------------------------------------
server_count=${#servers[@]}
for (( c = 0; c < $server_count; c++ ))
do
$FW -A INPUT -j ACCEPT -p udp -s ${servers[c]} --sport 1194 -i $local_interface
$FW -A OUTPUT -j ACCEPT -p udp -d ${servers[c]} --dport 1194 -o $local_interface
$FW -A INPUT -j ACCEPT -p tcp -s ${servers[c]} --sport 443 -i $local_interface
$FW -A OUTPUT -j ACCEPT -p tcp -d ${servers[c]} --dport 443 -o $local_interface
done
#---------------------------------------------------------------
# Log all dropped packages, debug only.
# View in /var/log/syslog or /var/log/messages
#---------------------------------------------------------------
#iptables -N logging
#iptables -A INPUT -j logging
#iptables -A OUTPUT -j logging
#iptables -A logging -m limit --limit 2/min -j LOG --log-prefix "IPTables general: " --log-level 7
#iptables -A logging -j DROP
# Disable internet for "no-internet" user
#iptables -A OUTPUT -m owner --gid-owner no-internet -j DROP
您将需要设置表servers=()
。只需指定您喜欢的VPN服务器的IP。
还要检查脚本开头的其他变量是否设置正确,否则会阻塞整个连接。
确保使用以下方法备份iptables:
sudo iptables-save > working.iptables.rules
(用还原sudo iptables-restore < working.iptables.rules
)
它支持TCP和UDP连接,如果仅需要其中之一,请从for ()
循环中删除不需要的两行。还要检查您的提供商是否使用相同的端口-可能不同。
与fe一起运行此脚本sudo /home/user/vpn.sh
。
如果您想在启动时加载它(iptables通常在重新启动后重置),请添加到/etc/rc.local
文件fe行中,例如bash /home/user/vpn.sh
。
下一部分是VPN自动连接器和监控器。这是我自己的想法:
#!/bin/bash
# CONNECTIONS
# Those values can be checked by running `nmcli con show`
vpn=(
85e60352-9e93-4be4-8b80-f6aae28d3c94
)
# NUMBER OF CONNECTIONS
total=${#vpn[@]}
# SLEEP
amount=10 # number of seconds to wait after each connection checking cycle
countdown=true # enable/disable animated countdown
skip=1 # how many seconds to substract between each animated countdown iteration
# LOGS
dir='/home/user/logs-vpn' # directory for storing logs
name='vpn' # prefix/name for a log file
seperate=true # create a seperate log file for each init session or log to single file
init=false # log init event (with logging setup)
start=false # log vpn start event
yes=false # log connected events
no=false # log disconnected events
# STYLE
clean='\e[1A\033[K' # clean & move to previous line
default='\e[0m' # default
blink='\e[5m' # blinking (works only in couple terminals, e.g. XTerm or tty)
dim='\e[2m' # dim/half-bright
disconnected='\e[91m' # light red
connected='\e[92m' # light green
count='\e[94m' # light blue
reconnecting='\e[96m' # light cyan
initializing='\e[93m' # light yellow
connection='\e[1m\e[91m' # bold light red
# SETUP
time=$(date +"%Y-%m-%d_%H-%M-%S")
if $separate; then
file="$dir/$time.log"
else
file="$dir/$name.log"
fi
# RESET
reset # reset screen
tput civis -- invisible # disable cursor
# RE-TIME
time=$(date +"%Y.%m.%d %H:%M:%S")
# INITIALIZATION
if $init; then
printf "$time INIT" >> $file
if $yes; then
printf " -y" >> $file
fi
if $no; then
printf " -n" >> $file
fi
printf "\n" >> $file
fi
# START CONNECTION
con=$(nmcli con show --active | grep " vpn")
if [[ $con == '' ]]; then
if $start; then
printf "$time START\n" >> $file
fi
time=$(date +"%H:%M:%S")
echo -e "${dim}[$time]${default} ${initializing}INITIALIZING...${default}"
echo ""
echo ""
random=$(((RANDOM % $total)-1))
try=${vpn[$random]}
(sleep 1s && nmcli con up uuid $try) >& /dev/null
sleep 10s
fi
# LOOP
while [ "true" ]; do
time=$(date +"%H:%M:%S")
# CLEAN AFTER COUNTDOWN
if $countdown; then
echo -en $clean
echo -en $clean
fi
# CHECK CONNECTION
con=$(nmcli con show --active | grep " vpn" | cut -f1 -d " ")
if [[ $con == '' ]]; then
if $no; then
printf "$time NO\n" >> $file
fi
echo -e "${dim}[$time]${default} ${disconnected}DISCONNECTED !!${default}"
echo -e "${blink}${reconnecting}re-connecting ...${default}"
random=$(((RANDOM % $total)-1))
try=${vpn[$random]}
(sleep 1s && nmcli con up uuid $try) >& /dev/null
else
if $yes; then
printf "$time YES\n" >> $file
fi
arr=(${con//./ })
echo -en $clean
echo -e "${dim}[$time]${default} ${connected}CONNECTED${default} (${connection}${arr[0]^^}${default})"
fi
# SLEEP
if $countdown; then
echo -e "${count}$amount${default}"
for (( c=$amount; c>=1; c=c-$skip )); do
echo -en $clean
echo -e "${count}$c${default}"
sleep $skip
done
echo -e "${count}0${default}"
else
sleep $amount
fi
done
它会在启动时自动连接,并以给定的间隔(amount=10
给出10秒的间隔)监视您的连接,并在连接丢失时重新连接。获得了日志记录功能和其他一些选项。
检查您的连接UUID的使用情况nmcli con show
,并将您的收藏夹(与添加到防火墙的IP匹配)添加到vpn=()
表中。每次它将随机选择此表中指定的连接。
您可以将其添加到您的自动启动中(不需要sudo特权)。这是一个如何在终端中启动它的示例:
mate-terminal --command="/home/user/vpn-reconnect.sh"
...这是在终端中运行的样子:
...这是VPN连接断开后防泄漏ping的样子:
请享用 :)
/etc/rc.local
?
我已经能够用UFW设置一个简单的VPN Kill Switch。它适用于我拥有的所有VPN。
这是我的ufw设置:
sudo ufw default deny outgoing
sudo ufw default deny incoming`
sudo ufw allow out 443/tcp
sudo ufw allow out 1194/udp
sudo ufw allow out on tun0 from any to any port 80
sudo ufw allow out on tun0 from any to any port 53
sudo ufw allow out on tun0 from any to any port 67
sudo ufw allow out on tun0 from any to any port 68
对我的作品就好了:)
sudo ufw allow out 443/tcp
在未连接VPN时允许安全的网站泄漏。您不想停止吗?具有AJAX或WebSockets的HTTPS站点可能会通过JavaScript计时器自行在后台重新连接。
我通过将Ufw设置为阻止所有传出流量,然后通过引用所有VPN节点的各自IP地址将其列入白名单来解决了这个问题。这听起来并不那么麻烦:以我的经验,VPN允许使用DNS查找来获取其各种IP地址。
我编写了一个PHP程序ufw-vpn。我已经使用了几年,随着时间的推移进行了各种小的改进。当然,您需要安装PHP,如果您希望克隆它而不是下载它,则需要安装Git。
您也可以使用wget来抓取它:
cd /path/to/a/folder
wget https://github.com/halfer/ufw-vpn/archive/master.zip
unzip master.zip
cd ufw-vpn-master
然后运行命令以检查它看起来是否正常(不带参数仅呈现语法消息):
php ufw-vpn.php
现在,假设您的VPN支持它,则可以使用完全限定的域来获取某个区域的服务器列表(您需要在提供商的文档中找到该服务器,或者从他们的支持部门中找到它):
php ufw-vpn.php earth.all.vpn.example.org add
这应该为您提供大量要添加的防火墙规则。要轻松安装它们,只需执行以下操作:
php ufw-vpn.php earth.all.vpn.example.org add > add-rules.sh
chmod u+x add-rules.sh && sudo add-rules.sh
VPN提供商会不时更新其IP地址,因此您需要更新其IP地址以进行匹配。您可以通过差异来做到这一点:
php ufw-vpn.php earth.all.vpn.example.org diff > diff-rules.sh
chmod u+x diff-rules.sh && sudo diff-rules.sh
对于差异,值得在执行之前检查规则,因为它将删除不属于VPN的所有内容。因此,如果您有一些自定义规则,则需要先删除它们,然后再运行。
存储库中提供了更多文档,并且所有文档都是开源的,因此您可以检查代码中的安全性问题。错误报告和功能建议非常欢迎。
ARGV
开始'tun0'
了很长一段时间,然后突然变成了'tun1'
没有通知的状态。因此,尽管有第一个(无用的)更改值,但if ARGV.last == 'vpn-down'