回答:
私も同じ設定で、「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接続をサポートしfor ()
ます。これらの1つだけが必要な場合は、不要な2行をループから削除してください。また、プロバイダーが同じポートを使用しているかどうかを確認してください-異なる場合があります。
このスクリプトをfeで実行します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秒間隔)で接続を監視し、接続が失われると再接続します。ロギング機能といくつかの他のオプションを取得しました。
使用している接続UUIDを確認し、nmcli con show
お気に入り(ファイアウォールに追加されたIPと一致)をvpn=()
テーブルに追加します。毎回、このテーブルで指定された接続をランダムに選択します。
自動起動に追加できます(sudo権限は必要ありません)。端末で起動する方法の例を次に示します。
mate-terminal --command="/home/user/vpn-reconnect.sh"
...そしてこれがターミナルで実行されている様子です:
...そして、VPN接続が切断された後のリーク防止pingは次のようになります。
楽しい :)
/etc/rc.local
か?
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
私にとってはうまくいきます:)
sudo ufw allow out 443/tcp
、VPNが接続されていない場合は、安全なWebサイトの漏洩を許可しているようです。あなたはそれを止めたくないですか?AJAXまたはWebSocketsを備えたHTTPSサイトは、おそらくJavaScriptタイマーを介して、バックグラウンドで再接続する可能性があります。
すべての送信トラフィックをブロックするようにUfwを設定し、個々のIPアドレスを参照してすべてのVPNノードをホワイトリストに登録することで、この問題を解決しました。これは、思ったほど面倒ではありません。私の経験では、VPNを使用すると、DNSルックアップを使用してさまざまなIPアドレスを取得できます。
これを行うためのufw-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アドレスを更新するため、一致するように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に属していないものはすべて削除されるため、実行する前にルールを確認することをお勧めします。そのため、カスタムルールがある場合は、実行する前に削除する必要があります。
より多くのドキュメントがリポジトリで利用可能であり、それはすべてオープンソースなので、セキュリティの問題がないかコードを確認できます。バグレポートと機能提案は大歓迎です。
ARGV
始めた'tun0'
が、突然'tun1'
予告なしに変わった。したがって、この最初の(役に立たない)値の変更にもかかわらずキルスイッチを機能させるには、テストを次のように変更する必要がありました。if ARGV.last == 'vpn-down'