Questão Existe um aplicativo VPN Monitor / Kill Switch para o Ubuntu?


Oi eu estou procurando um aplicativo VPN Monitor / Kill Switch que irá garantir a minha conexão VPN está sempre conectado. Se minha conexão segura cair, o aplicativo descartará os aplicativos que estão sendo monitorados para evitar vazamento de dados. Eu sei que existem tais aplicativos para o Windows. No entanto, ainda não encontrei uma alternativa adequada para o Linux.


9
2018-02-24 20:31


origem




Respostas:


Eu tive a mesma configuração, e "VPN kill switches" são mais complicados do que se poderia pensar.

Seguindo a sua especificação, que diz "matar certos aplicativos quando a VPN cai", há uma solução simples.

No Ubuntu, o monitor de rede tem retornos de chamada para eventos de rede, para que você possa escrever um script para matar os aplicativos que você deseja. Exemplo a seguir:

Editar /etc/NetworkManager/dispatcher.d/50vpndownkillapps.rb:

#!/usr/bin/env ruby

if ARGV == [ 'tun0', 'vpn-down' ]
  `pkill -f transmission`
  `pkill -f deluge`
end

Torne-o executável: chmod 755 /etc/NetworkManager/dispatcher.d/50vpndownkillapps.rb, e aproveitar :-)

Este script está em Ruby (por isso requer ruby), mas pode ser convertido para um script de shell.

Ele também assume que o adaptador VPN é tun0, que é o padrão para configurações OpenVPN.


5
2017-10-01 11:13



Por uma razão desconhecida, ARGV começou com 'tun0' por um longo tempo, e de repente mudou para 'tun1' sem aviso prévio. Então, para manter o kill switch funcionando apesar dessa primeira (inútil) mudança de valor, eu tive que mudar o teste para if ARGV.last == 'vpn-down' - zezollo


Eu tive essa mesma necessidade e desenvolvi minha própria solução, pois parece não haver nenhuma ferramenta dedicada para isso no Linux. Não há necessidade de largar / fechar aplicações abertas! :)

Você precisa configurar o firewall iptables, para que sua máquina possa se conectar APENAS a servidores VPN especificados (nenhum outro tráfego é permitido, exceto local, para que não haja "vazamentos"). Aqui está um script para isso (encontrado na 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

Você precisará configurar a tabela servers=(). Basta especificar os IPs dos seus servidores VPN favoritos.

Além disso, verifique se outras variáveis ​​no início do script estão definidas corretamente; caso contrário, bloqueará toda a sua conexão.

Certifique-se de fazer o backup do iptables com:

sudo iptables-save > working.iptables.rules

(restaurar com sudo iptables-restore < working.iptables.rules)

Ele suporta conexões TCP e UDP, se você precisar de apenas uma delas, remova duas linhas indesejadas de for () loop. Além disso, verifique se o seu provedor está usando as mesmas portas - pode ser diferente.

Execute este script com f.e. sudo /home/user/vpn.sh.

Se você quiser carregá-lo na inicialização (o iptables geralmente é redefinido após a reinicialização), adicione ao seu /etc/rc.local arquivo f.e. linha como bash /home/user/vpn.sh.


A próxima parte é o conector automático e monitor VPN. Aqui está minha própria invenção para isso:

#!/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

Ele se conectará automaticamente ao iniciar e monitorará sua conexão com um determinado intervalo (amount=10 dá 10 segundos de intervalo) e reconecta a conexão perdida. Tenho o recurso de registro e algumas outras opções.

Verifique suas conexões usando o UUID nmcli con show e adicione seus favoritos (correspondência com IP's adicionados ao firewall) para vpn=() mesa. Toda vez que ele irá selecionar aleatoriamente uma conexão especificada nesta tabela.

Você pode adicioná-lo ao seu início automático (não precisa de privilégio sudo). Aqui está um exemplo de como iniciá-lo no terminal:

mate-terminal --command="/home/user/vpn-reconnect.sh"

... e aqui está como está funcionando no terminal:

enter image description here

... e aqui está como um ping à prova de vazamento se parece depois que sua conexão VPN cai:

enter image description here

Apreciar :)


4
2017-12-28 09:58



Quanto ao carregamento do script na inicialização, por que você simplesmente não usa /etc/rc.local? - Andrea Lazzarotto
Bela ideia (funciona como charme!), Obrigado :) - GreggD
Isso é incrível, muito obrigado. Verificado para continuar funcionando a partir de julho de 2017. - Norr


Eu fui capaz de configurar um simples interruptor de kill da VPN com o UFW. Funciona com todas as vpn's que tenho.

Aqui estão minhas configurações do 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

Funciona para mim muito bem :)


2
2017-09-15 16:30



Parece ok, mas eu acho sudo ufw allow out 443/tcp permite o vazamento seguro do site quando a VPN não está conectada. Você não gostaria de parar com isso? Um site HTTPS com AJAX ou WebSockets pode reconectar-se em segundo plano por conta própria, talvez por meio de um temporizador de JavaScript. - halfer


Eu resolvi esse problema configurando o Ufw para bloquear todo o tráfego de saída e, em seguida, colocando na lista de permissões todos os nós da VPN referenciando seus endereços IP individuais. Isso não é tão oneroso quanto parece: VPNs na minha experiência permitem o uso de pesquisa de DNS para obter seus vários endereços IP.

Eu escrevi um programa PHP para fazer isso, chamado ufw-vpn. Eu usei por alguns anos, com vários pequenos aprimoramentos feitos ao longo do tempo. Você precisará do PHP instalado, é claro, e do Git se você deseja cloná-lo ao invés de baixá-lo.

Você também pode pegar usando wget:

cd /path/to/a/folder
wget https://github.com/halfer/ufw-vpn/archive/master.zip
unzip master.zip
cd ufw-vpn-master

Em seguida, execute o comando para verificar se parece OK (sem parâmetros apenas processa uma mensagem de sintaxe):

php ufw-vpn.php

Agora, supondo que sua VPN ofereça suporte a isso, você pode usar um domínio totalmente qualificado para obter uma lista de servidores para uma região (você precisará encontrar isso na documentação do seu provedor ou, talvez, no departamento de suporte):

php ufw-vpn.php earth.all.vpn.example.org add

Isso deve fornecer uma lista grande de regras de firewall a serem adicionadas. Para instalá-los facilmente, você pode fazer isso:

php ufw-vpn.php earth.all.vpn.example.org add > add-rules.sh
chmod u+x add-rules.sh && sudo add-rules.sh

De tempos em tempos, os provedores de VPN atualizarão seus endereços IP, portanto, você precisará atualizar o seu para corresponder. Você pode fazer isso através de um diff:

php ufw-vpn.php earth.all.vpn.example.org diff > diff-rules.sh
chmod u+x diff-rules.sh && sudo diff-rules.sh

Para um diff, vale a pena verificar as regras antes de executá-las, pois isso excluirá qualquer coisa que não pertença à VPN. Portanto, se você tiver algumas regras personalizadas, elas precisarão ser removidas antes da execução.

Mais documentos estão disponíveis no repositório e são todos de código aberto, para que você possa verificar o código em busca de problemas de segurança. Relatórios de bugs e sugestões de recursos são muito bem-vindos.


0
2017-12-11 11:53