こんにちは、VPN接続が常に接続されていることを確認するVPNモニター/キルスイッチアプリケーションを探しています。セキュリティで保護された接続が切断された場合、アプリケーションは、データ漏えいを防ぐために監視しているアプリケーションを削除します。 Windows用のそのようなアプリケーションがあることは知っています。ただし、Linuxに適した代替品はまだ見つかりません。
私は同じセットアップを持っていて、「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が必要です)が、シェルスクリプトに簡単に変換できます。
また、VPNアダプターがtun0
であると想定しています。これはOpenVPN構成の標準です。
これと同じニーズがあり、Linuxには専用のツールがないように思えるので、独自のソリューションを開発しました。開いているアプリケーションをドロップ/クローズする必要はありません! :)
Iptablesファイアウォールを設定して、マシンが指定されたVPNサーバーのみに接続できるようにする必要があります(ローカル以外のトラフィックは許可されないため、「リーク」はありません)。そのためのスクリプトを次に示します(Webで見つけました)。
#!/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接続をサポートします。そのうちの1つだけが必要な場合は、for ()
ループから不要な2行を削除します。プロバイダーが同じポートを使用しているかどうかも確認してください-異なる可能性があります。
このスクリプトをf.eで実行しますSudo /home/user/vpn.sh
。
起動時にそれをロードしたい場合(通常は再起動後にiptablesがリセットされます)、/etc/rc.local
ファイルに追加します。 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秒間隔)で接続を監視し、接続が失われると再接続します。ロギング機能とその他のオプションがあります。
nmcli con show
を使用して接続UUIDを確認し、(ファイアウォールに追加されたIPと一致する)お気に入りをvpn=()
テーブルに追加します。このテーブルで指定された接続をランダムに選択するたびに。
これを自動起動に追加できます(Sudo権限は不要です)。ターミナルで起動する方法の例を次に示します。
mate-terminal --command="/home/user/vpn-reconnect.sh"
...そして、これがターミナルで実行されている様子です:
...そして、VPN接続が切断された後の漏れ防止pingの様子を次に示します。
楽しい :)
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
私のためにうまく動作します:)
すべての発信トラフィックをブロックするようにUfwを設定し、個々のIPアドレスを参照してすべてのVPNノードをホワイトリストに登録することにより、この問題を解決しました。これは見た目ほど面倒ではありません。私の経験では、VPNはDNSルックアップを使用してさまざまなIPアドレスを取得できます。
fw-vpn と呼ばれるPHPプログラムを作成しました。私はそれを数年使用してきましたが、時間の経過とともにさまざまな小さな機能強化が行われました。もちろん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アドレスを随時更新するため、一致するように更新する必要があります。 diffを介して行うことができます。
php ufw-vpn.php earth.all.vpn.example.org diff > diff-rules.sh
chmod u+x diff-rules.sh && Sudo diff-rules.sh
Diffの場合、VPNに属さないものはすべて削除されるため、ルールを実行する前にルールを確認する価値があります。そのため、カスタムルールがある場合は、実行する前にそれらを削除する必要があります。
リポジトリにはさらにドキュメントが用意されており、すべてがオープンソースなので、セキュリティの問題についてコードを確認できます。バグレポートと機能の提案は大歓迎です。