Evite el tráfico saliente a menos que la conexión OpenVPN esté activa usando pf.conf en Mac OS X


19

He podido denegar todas las conexiones a redes externas a menos que mi conexión OpenVPN esté activa usando pf.conf. Sin embargo, pierdo la conectividad Wi-Fi si la conexión se interrumpe al cerrar y abrir la tapa de la computadora portátil o al activar y desactivar Wi-Fi nuevamente.

  • Estoy en Mac OS 10.8.1.
  • Me conecto a la Web a través de Wi-Fi (desde diferentes lugares, incluido el Wi-Fi público).
  • La conexión OpenVPN se configura con Viscosidad.

Tengo las siguientes reglas de filtro de paquetes configuradas en /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

Comienzo el servicio de filtro de paquetes con sudo pfctl -ey cargo las nuevas reglas con sudo pfctl -f /etc/pf.conf.

También he editado /System/Library/LaunchDaemons/com.apple.pfctl.plisty cambiado la línea <string>-f</string>para leer <string>-ef</string>para que el filtro de paquetes se inicie al inicio del sistema.

Todo esto parece funcionar muy bien al principio: las aplicaciones solo pueden conectarse a la web si la conexión OpenVPN está activa, por lo que nunca pierdo datos a través de una conexión insegura.

Pero, si cierro y vuelvo a abrir la tapa de mi computadora portátil o apago y vuelvo a encender el Wi-Fi, la conexión Wi-Fi se pierde y veo un signo de exclamación en el icono de Wi-Fi en la barra de estado. Al hacer clic en el icono de Wi-Fi, aparece el mensaje "Alerta: sin conexión a Internet":

No hay mensaje de conexión a internet

Para recuperar la conexión, tengo que desconectar y volver a conectar el wifi, a veces cinco o seis veces, antes de que desaparezca el mensaje "Alerta: Sin conexión a Internet" y pueda volver a abrir la conexión VPN. Otras veces, la alerta de Wi-Fi desaparece por sí sola, el signo de exclamación se borra y puedo volver a conectarme. De cualquier manera, puede tomar cinco minutos o más para volver a conectarse, lo cual puede ser frustrante.

Eliminar la línea block allresuelve el problema (pero permite conexiones inseguras), por lo que parece que hay un servicio que estoy bloqueando que Apple requiere para recuperar y confirmar una conexión Wi-Fi. Yo he tratado:

  • Habilitación pass on $wifi proto icmp allde icmp agregando a pf.conf
  • Habilitar la resolución DNS agregando pass on $wifi proto udp from $wifi to any port 53
  • Intentando aprender más registrando paquetes bloqueados (cambiando block alla block log all), pero el registro parece estar deshabilitado en OS X, porque sudo tcpdump -n -e -ttt -i pflog0al ver los resultados del registro en "tcpdump: pflog0: No existe tal dispositivo".

Nada de esto ayuda a restablecer una conexión Wi-Fi más rápido.

¿Qué más puedo hacer para determinar qué servicio debe estar disponible para recuperar la conectividad Wi-Fi, o qué regla debo agregar a pf.conf para que las reconexiones Wi-Fi sean más confiables?


1
Esto puede ser relevante para los que vienen después: sparklabs.com/support/preventing_network_and_dns_traffic_leaks
ptim

Respuestas:


14

Al monitorear las conexiones de red con Little Snitch, descubrí que Apple usa la aplicación mDNSResponder en segundo plano para verificar si la conexión Wi-Fi está disponible. mDNSResponder envía paquetes UDP a servidores de nombres para verificar la conectividad y resolver los nombres de host a las IP.

Cambiar la regla UDP que tenía anteriormente para permitir todos los paquetes UDP a través de Wi-Fi permite que mDNSResponder se conecte, lo que significa que Wi-Fi ahora se vuelve a conectar por primera vez después de una desconexión. En caso de que ayude a otros en el futuro, mi pf.conf final que incluye las reglas predeterminadas de Apple para Mountain Lion se ve así:

#
# 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)

Esto significa que los datos ahora se pueden filtrar a través de Wi-Fi por el pequeño número de aplicaciones que usan el protocolo UDP, desafortunadamente, como ntpd (para sincronización de tiempo) y mDNSResponder. Pero esto todavía parece mejor que permitir que los datos viajen sin protección a través de TCP, que es lo que usa la mayoría de las aplicaciones. Si alguien tiene alguna sugerencia para mejorar esta configuración, los comentarios u otras respuestas son bienvenidas.


Esto es algo que me ha interesado casualmente, ¡ver sus resultados me ha inspirado a ir a casa y probarlo! ¡Gracias!
jakev

@SixSlayer ¡Parece funcionar bastante bien! Tengo Viscosity configurado para conectarse automáticamente en el inicio y en las conexiones caídas, lo que hace que todo sea prácticamente perfecto. Lo principal a tener en cuenta es que pf.conf y com.apple.pfctl.plist se restablecen al valor predeterminado después de las actualizaciones del sistema operativo, aparentemente, por lo que vale la pena mantener una copia de seguridad de ambos.
Nick

En mi humilde opinión lo UDP es una especie de fastidio. No soy un chico de la red, pero esto me ayuda a aprender, y me fascina tener control sobre este tipo de detalles. Pasaré algún tiempo buscando una solución, pero si alguien me gana, igual de bien.
jakev

Esto es increíble, exactamente lo que estaba buscando. ¡Gracias!
keo

¿Has logrado tener muchas conexiones OpenVPN abiertas al mismo tiempo y enrutarlas en paralelo? (para ganar y sumar ancho de banda)
keo

11

No necesita permitir todos los UDP. La 'm' en mDNS significa 'multidifusión', y utiliza una dirección IP de destino de multidifusión específica llamada "dirección de multidifusión local de enlace" y un UDPnúmero de puerto 5353.

Esto significa que en su solución anterior, está permitiendo innecesariamente el tráfico a todos los puertos UDP 65535 a las 3,7 mil millones de direcciones IP enrutables en el mundo para evitar su VPN. Se sorprenderá de cuántas aplicaciones usan UDP, por lo que está rechazando significativamente el propósito de su idea original para evitar el tráfico saliente cuando la VPN está inactiva.

¿Por qué no utilizar esta regla en su lugar?

pass on $wifi proto udp to 224.0.0.251 port 5353

Una regla general muy importante con la configuración del firewall: cuando haga excepciones a través de su firewall, siempre trate de usar la regla más específica posible. La especificidad a veces se produce a expensas de la comodidad y la facilidad de uso, es decir, es posible que descubra que hay otro protocolo de enlace local que debe dejarse pasar y agregue otra regla específica.

Si cambia la regla anterior y encuentra que el problema wifi original regresa, entonces su PF puede estar bloqueando DHCP, el protocolo utilizado para configurar automáticamente las direcciones IP de sus dispositivos de red. (en una red doméstica, normalmente su enrutador de banda ancha sería su servidor DHCP). La regla que necesitaría para permitir DHCP sería:

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

* Nota: puede que tenga que sustituir 0.0.0.0a any. El DHCPREQUESTpaquete que su computadora primero envía tiene una dirección de origen 0.0.0.0porque en esa etapa, su computadora aún no tiene una dirección IP.
Para ser honesto, me inclinaría más hacia el uso any. Otra opción es extraer cualquier especificación de origen, es decir pass on $wifi proto udp to 255.255.255.255 port 67, pero eso significa que perdemos la parte del puerto de origen de la regla, y ser lo más específico posible es siempre la opción más segura.

Espero que ayude. Aquí hay algunos enlaces útiles:

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

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


1

Esto me dio suficiente información de fondo para dar el gran salto y usar pf.conf. Esto es lo que uso en mi 10.8 para que se vuelva a conectar después de que la conexión VPN caiga:

(Solo uso ethernet pero puedes cambiar $ lan por $ wifi y debería 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

1

Con el objetivo de crear las reglas PF de una manera "fácil", identificando las interfaces activas existentes, incluidas las interfaces actuales (vpn) , se puede utilizar este pequeño programa de interruptores de muerte ,

Todavía está en progreso, pero podría ser un buen comienzo para identificar la IP externa y las interfaces activas para crear correctamente las reglas del firewall.

ejemplo o salida usando la -iopción (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

Pasando la IP del 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á lejos de ser perfecto, pero el trabajo está en progreso. Puede encontrar más información / código aquí: https://github.com/vpn-kill-switch/killswitch


0

- Como complemento -

Es posible que desee agregar esta línea:

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

para permitir que mDNS funcione en ipv6

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.