Evitar tráfego de saída, a menos que a conexão OpenVPN esteja ativa usando o pf.conf no Mac OS X

19

Consegui negar todas as conexões com redes externas, a menos que minha conexão OpenVPN esteja ativa usando o pf.conf. No entanto, perco a conectividade Wi-Fi se a conexão for interrompida fechando e abrindo a tampa do laptop ou alternando o Wi-Fi novamente.

  • Estou no Mac OS 10.8.1.
  • Eu me conecto à Web via Wi-Fi (de vários locais, incluindo Wi-Fi público).
  • A conexão OpenVPN é configurada com viscosidade.

Eu tenho as seguintes regras de filtro de pacotes configuradas em /etc/pf.conf

# Deny all packets unless they pass through the OpenVPN connection
wifi=en1
vpn=tun0

block all

set skip on lo
pass on $wifi proto udp to [OpenVPN server IP address] port 443
pass on $vpn

Inicio o serviço de filtro de pacotes sudo pfctl -ee carrego as novas regras sudo pfctl -f /etc/pf.conf.

Também editei /System/Library/LaunchDaemons/com.apple.pfctl.pliste alterei a linha <string>-f</string>para ler, <string>-ef</string>para que o filtro de pacotes seja iniciado na inicialização do sistema.

Tudo isso parece funcionar muito bem no começo: os aplicativos só podem se conectar à Web se a conexão OpenVPN estiver ativa; portanto, nunca estou vazando dados por uma conexão insegura.

Mas, se eu fechar e reabrir a tampa do laptop ou desligar e ligar o Wi-Fi novamente, a conexão Wi-Fi será perdida e vejo um ponto de exclamação no ícone Wi-Fi na barra de status. Clicar no ícone Wi-Fi mostra a mensagem "Alerta: sem conexão à Internet":

Nenhuma mensagem de conexão com a Internet

Para recuperar a conexão, preciso desconectar e reconectar o Wi-Fi, às vezes cinco ou seis vezes, antes que a mensagem "Alerta: sem conexão à Internet" desapareça e eu possa abrir a conexão VPN novamente. Outras vezes, o alerta de Wi-Fi desaparece por conta própria, o ponto de exclamação é apagado e eu consigo me conectar novamente. De qualquer forma, pode levar cinco minutos ou mais para se conectar novamente, o que pode ser frustrante.

A remoção da linha block allresolve o problema (mas permite conexões não seguras), pelo que parece que estou bloqueando um serviço que a Apple precisa para recuperar e confirmar uma conexão Wi-Fi. Eu tentei:

  • Ativando o icmp adicionando pass on $wifi proto icmp allao pf.conf
  • Habilitando a resolução DNS adicionando pass on $wifi proto udp from $wifi to any port 53
  • Tentando aprender mais registrando pacotes bloqueados (alterando block allpara block log all), mas o log parece estar desativado no OS X, porque fazer sudo tcpdump -n -e -ttt -i pflog0para ver o log resulta em "tcpdump: pflog0: esse dispositivo não existe".

Nada disso ajuda a restabelecer uma conexão Wi-Fi mais rapidamente.

O que mais posso fazer para determinar qual serviço precisa estar disponível para recuperar a conectividade Wi-Fi ou que regra devo adicionar ao pf.conf para tornar as reconexões Wi-Fi mais confiáveis?

usuario
fonte
1
este pode ser relevante para quem vem depois: sparklabs.com/support/preventing_network_and_dns_traffic_leaks
PTIM

Respostas:

14

Ao monitorar as conexões de rede usando o Little Snitch, descobri que a Apple usa o aplicativo mDNSResponder em segundo plano para verificar se a conexão Wi-Fi está disponível. O mDNSResponder envia pacotes UDP aos servidores de nomes para verificar a conectividade e resolver nomes de host para IPs.

Alterar a regra UDP que eu tinha anteriormente para permitir todos os pacotes UDP via Wi-Fi permite que o mDNSResponder se conecte, o que significa que o Wi-Fi agora se reconecta pela primeira vez após uma desconexão. Caso isso ajude outras pessoas no futuro, meu pf.conf final, incluindo as regras padrão da Apple para o Mountain Lion, fica assim:

#
# com.apple anchor point
#
scrub-anchor "com.apple/*"
nat-anchor "com.apple/*"
rdr-anchor "com.apple/*"as
dummynet-anchor "com.apple/*"
anchor "com.apple/*"
load anchor "com.apple" from "/etc/pf.anchors/com.apple"

#
# Allow connection via Viscosity only
#
wifi=en1 #change this to en0 on MacBook Airs and other Macs without ethernet ports
vpn=tun0
vpn2=tap0

block all

set skip on lo          # allow local traffic

pass on p2p0            #allow AirDrop
pass on p2p1            #allow AirDrop
pass on p2p2            #allow AirDrop
pass quick proto tcp to any port 631    #allow AirPrint

pass on $wifi proto udp # allow only UDP packets over unprotected Wi-Fi
pass on $vpn            # allow everything else through the VPN (tun interface)
pass on $vpn2           # allow everything else through the VPN (tap interface)

Isso significa que agora os dados podem ser vazados pelo Wi-Fi pelo pequeno número de aplicativos que usam o protocolo UDP, infelizmente, como o ntpd (para sincronização de horário) e o mDNSResponder. Mas isso ainda parece melhor do que permitir que os dados viajem desprotegidos pelo TCP, que é o que a maioria dos aplicativos usa. Se alguém tiver alguma sugestão para melhorar essa configuração, comentários ou respostas adicionais serão bem-vindos.

usuario
fonte
Isso é algo em que casualmente me interessei, ver seus resultados me inspirou a ir para casa e experimentá-lo! obrigado!
jakev
@SixSlayer Parece funcionar muito bem! Eu tenho a viscosidade configurada para conexão automática na inicialização e nas conexões descartadas, o que torna a coisa toda praticamente perfeita. O principal a notar é que pf.conf e com.apple.pfctl.plist são redefinidos para o padrão após as atualizações do sistema operacional, aparentemente, então vale a pena manter um backup de ambos.
Nick
IMHO a coisa UDP é uma espécie de chatice. Eu não sou um cara da rede, mas isso meio que me ajuda a aprender, e eu tenho um fascínio por ter controle sobre esses tipos de detalhes. Vou passar algum tempo procurando uma solução, mas se alguém me vencer, também.
jakev
isso é incrível - exatamente o que eu estava procurando. Obrigado!
keo 7/09/12
Você já conseguiu ter muitas conexões OpenVPN abertas ao mesmo tempo e rotear através delas em paralelo? (para ganhar e somar largura de banda)
keo
11

Você não precisa permitir todos os UDP. O 'm' no mDNS significa 'multicast' e usa um endereço IP de destino multicast específico chamado "endereço local de multicast do link" e um UDPnúmero de porta 5353.

Isso significa que, na sua solução acima, você está desnecessariamente permitindo que o tráfego em todas as portas 65535 UDP para todos os endereços IP roteáveis ​​de 3,7 bilhões de milhões no mundo ignore sua VPN. Você ficaria surpreso com o número de aplicativos que usam o UDP, portanto, você está derrotando significativamente o objetivo da sua ideia original de impedir o tráfego de saída quando a VPN está inoperante.

Por que não usar esta regra:

pass on $wifi proto udp to 224.0.0.251 port 5353

Uma regra prática muito importante na configuração do firewall - ao fazer exceções no firewall, tente sempre usar a regra mais específica possível. Às vezes, a especificidade ocorre às custas da conveniência e da facilidade de uso, ou seja, você pode descobrir que existe algum outro protocolo local de link que precisa ser liberado e adicionar mais uma regra específica.

Se você alternar na regra acima e descobrir que o problema original do wifi retorna, seu PF pode estar bloqueando o DHCP, o protocolo usado para configurar automaticamente os endereços IP dos seus dispositivos de rede. (em uma rede doméstica, normalmente o seu roteador de banda larga seria o servidor DHCP). A regra que você precisaria para permitir o DHCP seria:

pass on $wifi proto udp from 0.0.0.0 port 68 to 255.255.255.255 port 67

* Nota: pode ser necessário substituir 0.0.0.0para any. O DHCPREQUESTpacote que o seu computador envia pela primeira vez tem um endereço de origem 0.0.0.0porque, nessa fase, o computador ainda não tem um endereço IP.
Para ser sincero, eu me inclinaria mais para usar any. Outra opção é extrair qualquer especificação de fonte, ou seja pass on $wifi proto udp to 255.255.255.255 port 67, mas isso significa que perdemos a parte da regra da porta de origem, e ser o mais específico possível é sempre a opção mais segura.

Espero que ajude. Aqui estão alguns links úteis:

mDNS: http://en.wikipedia.org/wiki/Multicast_DNS#Packet_structure

DHSP: http://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol#DHCP_discovery

esmagadoramente
fonte
1

Isso me deu informações suficientes para dar o grande salto e usar o pf.conf. Aqui está o que eu uso no meu 10.8 para reconectá-lo após a queda da conexão VPN:

(Eu só uso ethernet, mas você pode alterar $ lan por $ wifi e deve funcionar)

lan=en0
wifi=en1
vpn=tun0
block all
set skip on lo
pass on $lan proto { udp,tcp } to 8.8.8.8
pass on $lan proto tcp to vpn.btguard.com port 1194
pass on $vpn
Cedric
fonte
1

Com o objetivo de criar as regras de PF de uma maneira "fácil", identificando as interfaces ativas existentes, incluindo as interfaces atuais (vpn), este pequeno programa de interrupção pode ser usado,

Ainda está em andamento, mas pode ser um bom começo para identificar IP externo e interfaces ativas, a fim de criar corretamente as regras de firewall.

exemplo ou saída usando a -iopção (info):

$ killswitch -i
Interface  MAC address         IP
en1        bc:57:36:d1:82:ba   192.168.1.7
ppp0                           10.10.1.3

public IP address: 93.117.82.123

Passando o ip do servidor -ip:

# --------------------------------------------------------------
# Sat, 19 Nov 2016 12:37:24 +0100
# sudo pfctl -Fa -f ~/.killswitch.pf.conf -e
# --------------------------------------------------------------
int_en1 = "en1"
vpn_ppp0 = "ppp0"
vpn_ip = "93.117.82.123"
set block-policy drop
set ruleset-optimization basic
set skip on lo0
block all
pass on $int_en1 proto udp to 224.0.0.251 port 5353
pass on $int_en1 proto udp from any port 67 to any port 68
pass on $int_en1 inet proto icmp all icmp-type 8 code 0
pass on $int_en1 proto {tcp, udp} from any to $vpn_ip
pass on $vpn_ppp0 all

Está longe de ser perfeito, mas o trabalho está em andamento. Mais informações / código podem ser encontrados aqui: https://github.com/vpn-kill-switch/killswitch

nbari
fonte
0

- Como adição -

Você pode adicionar esta linha:

pass on $wifi inet6 proto udp from any to FF02:0000:0000:0000:0000:0000:0000:00FB port 5353

para permitir que o mDNS opere no ipv6

user263367
fonte