Existe um aplicativo VPN Monitor / Kill Switch para Ubuntu?

10

Olá, estou procurando um aplicativo VPN Monitor / Kill Switch que garanta que minha conexão VPN esteja sempre conectada. Se minha conexão segura cair, o aplicativo descartará os aplicativos que está monitorando para evitar vazamento de dados. Eu sei que existem aplicativos para Windows. No entanto, ainda não encontrei uma alternativa adequada para o Linux.

AsianXL
fonte

Respostas:

5

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

No entanto, seguindo sua especificação, que diz "matar certos aplicativos quando a VPN cair", existe uma solução simples.

No Ubuntu, o monitor de rede possui retornos de chamada para eventos de rede, para que você possa escrever um script para matar os aplicativos que 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

O tornam executável:, chmod 755 /etc/NetworkManager/dispatcher.d/50vpndownkillapps.rbe aproveite :-)

Este script está em Ruby (portanto, requer ruby), mas pode ser convertido trivialmente em um script de shell.

Ele também pressupõe que o adaptador VPN seja tun0, o padrão para as configurações do OpenVPN.

Marcus
fonte
1
Por um motivo desconhecido, ARGVcomeçou 'tun0'por um longo tempo e de repente mudou para 'tun1'sem aviso prévio. Assim, para manter o kill switch trabalhando apesar deste primeiro (inútil) valor mudando, eu tive que mudar o testeif ARGV.last == 'vpn-down'
zezollo
3

Eu tinha 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 descartar / fechar aplicativos abertos! :)

Você precisa configurar o firewall do iptables, para que sua máquina possa se conectar SOMENTE 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.

Verifique também se outras variáveis ​​no início do script estão definidas corretamente, caso contrário, ele 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 apenas de uma delas, remova duas linhas indesejadas do for ()loop. Verifique também se o seu provedor está usando as mesmas portas - pode ser diferente.

Execute este script com fe sudo /home/user/vpn.sh.

Se você deseja carregá-lo na inicialização (o iptables geralmente redefine após a reinicialização), adicione ao seu /etc/rc.localarquivo uma linha como bash /home/user/vpn.sh.


A próxima parte é o conector automático e o monitor da VPN. Aqui está minha própria engenhoca 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 conecta automaticamente ao iniciar e monitora sua conexão com um determinado intervalo ( amount=10fornece um intervalo de 10 segundos) e se reconecta com a conexão perdida. Possui recurso de log e algumas outras opções.

Verifique as UUIDs de suas conexões nmcli con showe adicione seus favoritos (combinando com os IPs adicionados ao firewall) na vpn=()tabela. Sempre que ele seleciona aleatoriamente uma conexão especificada nesta tabela.

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

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

... e aqui está como ele fica rodando no terminal:

insira a descrição da imagem aqui

... e veja como um ping à prova de vazamento se parece após a queda da sua conexão VPN:

insira a descrição da imagem aqui

Apreciar :)

GreggD
fonte
1
Em relação ao carregamento do script na inicialização, por que você não usa simplesmente /etc/rc.local?
Andrea Lazzarotto
Ideia bonita (funciona como charme!), Obrigado :)
GreggD
Isso é incrível, muito obrigado. Verificado como funcionando ainda em julho de 2017.
Norr 15/07/19
2

Consegui configurar um simples switch de interrupção de VPN com a UFW. Ele funciona com todos os VPNs que eu tenho.

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

Reeby
fonte
Parece bom, mas acho que sudo ufw allow out 443/tcppermite o vazamento seguro de sites quando a VPN não está conectada. Você não gostaria de parar com isso? Um site HTTPS com AJAX ou WebSockets pode se reconectar em segundo plano por conta própria, talvez por meio de um timer JavaScript.
halfer
0

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

Eu escrevi um programa PHP para fazer isso, chamado ufw-vpn . Eu o uso há alguns anos, com várias pequenas melhorias feitas ao longo do tempo. Você precisará do PHP instalado, é claro, e do Git, se desejar cloná-lo em vez de baixá-lo.

Você também pode pegá-lo usando o 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 está OK (sem parâmetros, apenas gera uma mensagem de sintaxe):

php ufw-vpn.php

Agora, supondo que sua VPN o suporte, 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 grande lista de regras de firewall a serem adicionadas. Para instalá-los facilmente, basta fazer o seguinte:

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

Periodicamente, os provedores de VPN atualizam 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 uma comparação, vale a pena verificar as regras antes de executá-las, pois excluirá qualquer coisa que não pertença à VPN. Portanto, se você tiver algumas regras personalizadas, elas deverã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 quanto a problemas de segurança. Relatórios de bugs e sugestões de recursos são muito bem-vindos.

halter
fonte