Un enrutador UDP de mierda para el año 2020 y más allá.
Así que estoy jugando con Roon y tengo esta complicada red doméstica que deja a Roon perplejo. Empecé a depurar cosas y resulta que Roon envía mensajes de difusión a UDP/9003. Por supuesto, mi firewall/enrutador no reenviará estos mensajes, porque eso es lo correcto.
Desafortunadamente, realmente quiero que estos mensajes de difusión se reenvíen a otras VLAN/subredes de mi red local. Comencé a usar udp-proxy-relay-redux, que funcionó muy bien al principio.
Pero también me gustan mucho estos mensajes reenviados a través de mis conexiones OpenVPN que utilizan el controlador tun
, que es una interfaz punto a punto y explícitamente no admite transmisiones. Esto no funcionó bien con udp-proxy-relay-redux porque Roon se porta mal y todavía intenta enviar "transmisiones" a la dirección .255 que luego se dejan caer al suelo porque mi servidor VPN no tiene la dirección xxx255. Básicamente, en una interfaz punto a punto, estas "transmisiones" eran tratadas como un paquete destinado a otro host y legítimamente ignoradas.
En lugar de utilizar un socket UDP normal para escuchar mensajes de difusión, udp-proxy-2020
utiliza libpcap para "olfatear" los mensajes de difusión UDP. Esto significa que puede ser mucho más flexible sobre qué paquetes "ve" para luego enviarlos mediante libpcap/inyección de paquetes a todas las demás interfaces configuradas. Si esto te hace decir "ew", bueno, bienvenido al 2020.
Estoy escribiendo esto en GoLang para que al menos la compilación cruzada en su enrutador/firewall aleatorio de Linux/FreeBSD sea razonablemente fácil. No hay que realizar complejos C cruzados ni intentar instalar Python/Ruby y un montón de bibliotecas.
Además: ¡JAJAJAJAJAJAJAJA! ¡Nada de eso es cierto! La necesidad de usar libpcap significa que tengo que realizar una compilación cruzada usando CGO porque gopacket/pcapgo solo admite Linux para lectura y escritura en interfaces de red (¿ethernet?).
Se admite prácticamente cualquier sistema tipo Unix porque la lista de dependencias es solo libpcap
y golang
. Desarrollo en MacOS y me dirijo específicamente a pfSense/FreeBSD y Ubiquiti USG, EdgeRouter y DreamMachine/Pro, ya que son bastante comunes entre la comunidad de usuarios de Roon.
Si está utilizando una distribución basada en Linux RedHat o Debian, la forma más sencilla de instalarla es tomar el archivo .rpm
o .deb
apropiado e instalarlo con su administrador de paquetes. Luego edite /etc/udp-proxy-2020.conf
e inicie mediante: systemctl start udp-proxy-2020
.
También hay una imagen de Docker disponible para Linux en AMD64 y ARM64 (como Ubiquiti UDM).
Tenga en cuenta que para las implementaciones de Docker, debe utilizar una red de host.
Libero binarios para Linux, FreeBSD (pfSense) y MacOS para hardware Intel, ARM y MIPS.
Ahora hay instrucciones y scripts de inicio disponibles en el directorio de scripts de inicio. Si descubres cómo agregar soporte para otra plataforma, ¡envíame una solicitud de extracción!
Ejecute udp-proxy-2020 --help
para obtener una lista actualizada de opciones de línea de comando.
Además, tenga en cuenta que en muchos sistemas operativos deberá ejecutarlo como usuario root
. Los sistemas Linux pueden otorgar opcionalmente la capacidad CAP_NET_RAW
.
Actualmente sólo hay unas pocas banderas de las que probablemente debas preocuparte:
--interface
: especifica dos o más interfaces de red para escuchar.--port
: especifica uno o más puertos UDP para monitorear.--level
- Especifica el nivel de registro: [trace|debug|warn|info|error]Opciones avanzadas:
--fixed-ip
-- Codifique una @ para enviar siempre tráfico. Útil para cosas como OpenVPN en modo de sitio a sitio.--timeout
: número de ms para el valor de tiempo de espera de pcap. (el valor predeterminado es 250 ms)--cache-ttl
: número de minutos para almacenar en caché las IP. (el valor predeterminado es 180 min / 3 h) Es posible que sea necesario aumentar este valor si tiene problemas para pasar tráfico a los clientes en túneles OpenVPN si no puede usar --fixed-ip
porque los clientes no tienen una IP fija.--no-listen
-- No escuche en los puertos UDP especificados para evitar conflictos--deliver-local
-- Entrega paquetes localmente en la interfaz loopback Por supuesto, hay otras opciones; ejecute ./udp-proxy-2020 --help
para obtener una lista completa.
Ejemplo:
udp-proxy-2020 --port 9003 --interface eth0,eth0.100,eth1,tun0 --cache-ttl 300
Reenviaría paquetes udp/9003 en cuatro interfaces: eth0, eth1, VLAN100 en eth0 y tun0. Las IP del cliente en tun0 se recordarán durante 5 minutos una vez que se hayan aprendido.
Nota: "aprender" requiere que el cliente envíe primero un mensaje udp/9003. Si su aplicación requiere que se envíe primero un mensaje al cliente, deberá especificar --fixed-ip=1.2.3.4@tun0
donde 1.2.3.4
es la dirección IP del cliente en tun0.
Probé ambas configuraciones de VPN "road warrior" con el cliente Roon ejecutándose en mi computadora portátil y conectándome nuevamente al firewall de mi hogar a través de OpenVPN y Wireguard. Yo personalmente uso Wireguard en lugar de OpenVPN porque es más seguro y tiene mejor rendimiento.
También probé la VPN de sitio a sitio usando Wireguard + pfSense. Seguí las instrucciones de Wireguard VPN de sitio a sitio de pfSense e instalé udp-proxy-2020
en ambos firewalls. Debe configurar la opción --interface
para incluir las interfaces de red LAN y Wireguard.
Si está compilando para la misma plataforma en la que desea ejecutar udp-proxy-2020
, solo necesita asegurarse de tener libpcap
y los encabezados necesarios (es posible que necesite un paquete -dev
para eso) y ejecutar make
o gmake
según corresponda ( necesitamos GNU Make, no BSD Make).
Si necesita crear una plataforma multiplataforma, uno de los siguientes objetivos puede ayudarle:
make linux-amd64
a través de Dockermake linux-mips64
(Linux/MIPS64 big-endian para Ubiquiti USG/EdgeRouter) a través de Dockermake linux-arm
a través de Docker:make freebsd
(pfSense 2.6) a través de Vagrant y VirtualBoxmake docker
Puede obtener una lista completa de los objetivos creados e información básica sobre ellos ejecutando: make help
.
A partir de v0.0.11, udp-proxy-2020
ahora crea de forma predeterminada un socket de escucha UDP en los --port
especificados. Esto evita que el sistema operativo subyacente emita mensajes de puerto ICMP inalcanzable que pueden dañar a ciertos clientes (en particular, el cliente Roon iOS).
El único momento en el que debería necesitar usar el indicador --no-listen
es si hay otra pieza de software que se está ejecutando en el mismo host que udp-proxy-2020
.
A partir de v0.1.0, sí. Debe especificar las opciones --deliver-local
y --no-listen
para que entregue paquetes a través de la interfaz loopback.
Estas banderas son para depurar problemas con udp-proxy-2020
. Deberías usar estas banderas cuando te indique que lo hagas como parte de un ticket que hayas abierto para udp-proxy-2020
.
Desde la página de lanzamientos en Github.
No, no es un proxy. Es más como un enrutador. No necesita realizar ningún cambio más que ejecutarlo en el enrutador/firewall de su hogar.
Sinceramente no pensé mucho en el nombre y esto fue lo primero que me vino a la mente. Además, nombrar es difícil.
tun
, como las utilizadas por OpenVPNraw
, como las utilizadas por Wireguard.vti
para IPSec de sitio a sitioTenga en cuenta que los túneles VPN L2TP en Linux no son compatibles con udp-proxy-2020 porque el kernel de Linux expone esas interfaces como Linux SLL, lo que no proporciona una decodificación precisa de los paquetes.
Así que no lo he hecho yo mismo, pero Bart Verhoeven, en los foros de la comunidad de Roon, escribió este procedimiento muy detallado.
udp-proxy-2020 está diseñado para múltiples plataformas de hardware y sistema operativo:
darwin-amd64
linux-amd64
linux-arm64
(RasPi 2 V1.2 y superior, Ubiquiti UniFi Dream Machine)linux-armv7
(RasPi 2 V1.1 y anteriores)linux-armv6
linux-armv5
linux-mips64
(Ubiquiti USG/EdgeRouter)freebsd-amd64
(funciona con pfSense en x86)freebsd-arm64
(Netgate SG-1100 y SG-2100)freebsd-armv7
(Netgate SG-3100)Honestamente, solo envíame un correo electrónico diciendo gracias o "estrella" este proyecto en GitHub, es suficiente gracias.
De vez en cuando, alguien me pregunta si puedo darme unos cuantos dólares, pero realmente no necesito dinero. Si aún desea donarme algunos dólares, preferiría que lo donara al Second Harvest Food Bank, que es local para mí y podría utilizar su dinero mejor que yo.