你好,我正在寻找一款 VPN 监控/Kill Switch 应用程序,以确保我的 VPN 连接始终保持连接。如果我的安全连接断开,该应用程序将删除其监控的应用程序以防止数据泄露。我知道 Windows 上有这样的应用程序。但是,我还没有找到适合 Linux 的替代品。
答案1
有几种解决方案,取决于您想要挂接的服务。
OpenVPN 设备关闭事件
OpenVPN 支持设备关闭事件的挂钩,允许运行脚本。
只需将选项添加--down <script_name>
到 OpenVPN 启动命令中;例如,如果它在您有一个 systemd 单元中:
ExecStart=/usr/sbin/openvpn --down /path/to/kill_switch.sh
在脚本中放入你想要的任何内容:
#!/bin/bash
pkill -f transmission
pkill -f deluge
NetworkManager VPN 断开事件
在 Ubuntu 上,网络监视器具有网络事件回调功能,因此您可以编写脚本来终止您想要的应用程序。示例:
编辑/etc/NetworkManager/dispatcher.d/50vpndownkillapps.sh
:
#!/bin/bash
if [[ $1 == "tun0" && $2 == "vpn-down" ]]; then
pkill -f transmission
pkill -f deluge
fi
使其可执行:chmod 755 /etc/NetworkManager/dispatcher.d/50vpndownkillapps.sh
,然后享受:-)
它还假定 VPN 适配器是tun0
,这是 OpenVPN 配置的标准。
答案2
我有同样的需求,并且我开发了自己的解决方案,因为 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 的样子如下:
享受 :)
答案3
我已经能够使用 UFW 设置一个简单的 VPN 终止开关。它适用于我拥有的所有 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
对我来说很好用:)
答案4
我通过设置 Ufw 来阻止所有传出流量,然后通过引用其各自的 IP 地址将所有 VPN 节点列入白名单,从而解决了这个问题。这并不像听起来那么繁琐:根据我的经验,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 地址以匹配。您可以通过 diff 进行更新:
php ufw-vpn.php earth.all.vpn.example.org diff > diff-rules.sh
chmod u+x diff-rules.sh && sudo diff-rules.sh
为了区别起见,在执行之前检查规则是值得的,因为它会删除任何不属于 VPN 的内容。因此,如果您有一些自定义规则,则需要在运行之前将其删除。
存储库中提供了更多文档,并且全部开源,因此您可以检查代码是否存在安全问题。非常欢迎提交错误报告和功能建议。