У мене була така сама потреба, і я розробив власне рішення, оскільки, схоже, немає спеціального інструменту для цього в 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=()
. Просто вкажіть IP-адреси ваших улюблених серверів VPN.
Також перевірте, чи інші змінні на початку скрипту встановлені належним чином, інакше це заблокує все ваше з'єднання.
Обов’язково зробіть резервну копію 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
та додайте в vpn=()
таблицю вибрані файли (відповідні IP-адресам, доданим до брандмауера) . Щоразу він випадковим чином вибере з'єднання, вказане в цій таблиці.
Ви можете додати його до свого автозапуску (не потребує приватності sudo). Ось приклад, як запустити його в терміналі:
mate-terminal --command="/home/user/vpn-reconnect.sh"
... і ось як це виглядає працює в терміналі:
... і ось як виглядає герметичний пінг після падіння вашого VPN-з'єднання:
Насолоджуйтесь :)
ARGV
він починався з'tun0'
тривалого часу і раптом змінився на'tun1'
без повідомлення. Отже, щоб утримати роботу перемикача вбивства, незважаючи на перше (марне) змінне значення, мені довелося змінити тест наif ARGV.last == 'vpn-down'