¿Transformar un paquete de unidifusión UDP en una transmisión?


8

Necesitamos activar algunas computadoras en nuestra LAN interna, desde Internet.
Tenemos un enrutador algo cerrado, con muy pocas formas de configurarlo.
Me gustaría usar netfilter (iptables) para hacer esto porque no involucra un demonio o similar, pero otras soluciones están bien.

Lo que tengo en mente:

  • la computadora externa emite un paquete WOL (Wake-On-LAN) a la dirección IP pública (con el MAC correcto dentro)
  • el puerto correcto está abierto en el enrutador (digamos 1234), redirigiendo los datos a una caja de Linux
  • el cuadro de Linux transforma el paquete de unidifusión UDP en un paquete de difusión (exactamente el mismo contenido, solo la dirección de destino se modifica a 255.255.255.255 o 192.168.0.255)
  • el paquete de multidifusión llega a cada NIC y la computadora deseada ahora está activa

Para eso, una regla muy simple de netfilter es:
iptables --table nat --append PREROUTING --in-interface eth+ --protocol udp --destination-port 1234 --jump DNAT --to-destination 192.168.0.255

Alas netfilter parece ignorar la transformación para transmitir. 192.168.0.255 y 255.255.255.255 no dan nada. También probé con 192.168.0.0 y 0.0.0.0
. Usé tcpdump para ver qué sucede:
tcpdump -n dst port 1234
13:54:28.583556 IP www.xxx.yyy.zzz.43852 > 192.168.0.100.1234: UDP, length 102
y nada más. Debería tener una segunda línea como:
13:54:28.xxxxxx IP www.xxx.yyy.zzz.43852 > 192.168.0.255.1234: UDP, length 102

Si redirijo a una dirección que no es de multidifusión, todo está bien. Tengo las 2 líneas esperadas. Pero obviamente esto no funciona para WOL.

¿Hay alguna manera de decirle a netfilter que emita paquetes de difusión?

Otros métodos en los que pienso:

  • use iptables para hacer coincidir los paquetes deseados, regístrelos y use un demonio para monitorear el archivo de registro y disparar el paquete de difusión
  • use iptables para redirigir los paquetes deseados a un demonio local, que dispara el paquete de difusión (más simple)
  • usar socat (¿cómo?)

Un paquete de difusión no es solo un paquete enviado a una dirección de difusión. Hay una bandera para los sockets llamada SO_BROADCAST. Estoy tratando de descubrir cómo iptables puede modificarlo.
lgeorget 01 de

@lgeorget: iptables no está relacionado con sockets.
Bertrand SCHITS el

En efecto. No estoy mirando el lugar correcto. Debe haber una opción en algún lugar para que iptables le permita enviar paquetes de difusión.
lgeorget 01 de

1
¿Has probado iptables --table nat --append PREROUTING --in-interface eth + --protocol udp --destination-port 1234 --jump DNAT --to-destination 192.168.0.0?
lgeorget 01 de

@lgeorget: gracias por la idea. Pero el mismo resultado. Actualizo la pregunta
Gregory MOUSSAT

Respuestas:


12

socatEs una utilidad asesina. Poner en algún lugar de sus guiones de inicio:

socat -u -T1 UDP-LISTEN:1234,fork UDP-DATAGRAM:255.255.255.255:5678,broadcast

Algunos usuarios tienen problemas con UDP-LISTEN, por lo que usar UDP-RECV parece mejor (advertencia: podría enviar los paquetes de difusión en un bucle sin fin):

socat -u UDP-RECV:1234 UDP-DATAGRAM:255.255.255.255:5678,broadcast

forkPermita que Socat siga escuchando los próximos paquetes.
T1limite la vida de los subprocesos bifurcados a 1 segundo.
255.255.255.255es más general que 192.168.0.255. Permitiéndole copiar y pegar sin pensar en su estructura de red actual. Advertencia: esto probablemente envíe los paquetes emitidos a todas las interfaces.

Como tú, noté que WOL funciona con cualquier puerto. Me pregunto si esto es confiable. Muchos documentos solo hablan de los puertos 0, 7 y 9.
Esto permite utilizar un puerto no privilegiado, por lo que puede ejecutar socatcon el usuario nobody.

Gracias lgeorget Hauke Lagingy Gregory MOUSSATpor haber participado en esta respuesta.
Siéntase libre de agregar detalles.


Lo intenté pero el problema es que UDP-LISTEN cerrará el socket después de que haya llegado el primer paquete, sin importar la bifurcación. Utilice UDP-RECV en su lugar.
lgeorget 01 de

No hay problema aqui. ¿Usaste la opción "tenedor"? Veo en el hombre los paquetes de fusión UDP-RECV. No tengo idea de lo que significa. UDP-RECVFROM no exhibe este comportamiento, pero puede ser un error en el hombre.
Bertrand SCHITS el

Sí, usé el 'tenedor'. Intenté con un socat y dos procesos de netcat (uno para enviar paquetes a socat, el otro para recibir los paquetes de difusión). Con UPD-LISTEN, socat simula una conexión y cierra el zócalo al final. Con UDP-RECV, utiliza el comportamiento predeterminado sin conexión de UDP. De socat man: "Normalmente, las conexiones de socket terminarán con shutdown (2) que termina el socket incluso si es compartido por múltiples procesos".
lgeorget 01 de

2
¿Socat se transmitirá en todas las interfaces entonces?
Hauke ​​Laging

1
@lgeorget: "echo 'dummy' | nc -u -q 0 127.0.0.1 1234" funciona perfectamente con -UDP-LISTEN. Puedo ejecutarlo varias veces. Pero tengo problemas con -UDP-RECV y -UDP-RECVFROM: los paquetes se transmiten a la velocidad de enlace máxima hasta que se elimina el socat. ¿Ves el mismo problema con tcpdump?
Bertrand SCHITS el

3

El tráfico de difusión por definición está destinado a la máquina local. Esto significa que el paquete obtiene DNAT a 192.168.0.255 y luego el núcleo ve el paquete y decide que está destinado al enrutador, por lo que verá este paquete en la cadena de ENTRADA. El enrutador (y cualquier otro dispositivo) pensará que los paquetes 192.168.0.255 están destinados a sí mismo y no los reenviará más. Los paquetes de difusión no se enrutan / reenvían por diseño.

Hay una gran solución con el truco ARP mencionado. "Perderá" una dirección IP. Usaré ficticio 192.168.0.254en este ejemplo; recuerde no asignar nunca 192.168.0.254a ningún dispositivo en su red:

  1. Cree una entrada ARP estática en la interfaz LAN para la dirección IP que nunca usará para ninguna máquina:

    arp -i ethLAN --set 192.168.0.254 FF:FF:FF:FF:FF:FF
    
  2. DNAT su tráfico UDP Wake-On-Lan en la interfaz WAN a esta dirección IP ficticia:

    iptables --table nat --append PREROUTING  --in-interface ethWAN --protocol udp --destination-port 1234 --jump DNAT --to-destination 192.168.0.254
    

Esto funciona perfecto para paquetes WOL. Esta solución alternativa también funciona en productos basados ​​en el kernel de Linux, como los dispositivos Mikrotik y los dispositivos openwrt. Utilizo este truco en los dispositivos Mikrotik para activar mi máquina de forma remota con mi teléfono celular.


Los paquetes recibidos de Internet no se transmiten. Es por eso que la pregunta es "Transformar UNICAST a BROADCAST"
Gregory MOUSSAT

2

Encontré esta pregunta en Serverfault .

Sin embargo, no pude obtener ese tráfico de transmisión a través de mi enrutador. Los paquetes DNATted ni siquiera llegaron a mi cadena FORWARD. Tal vez hay alguna opción extraña del núcleo que no lo permite.

Pero la idea ARP es interesante. Supongo que eso debe ir acompañado de una regla en OUTPUT que prohíbe los paquetes a esta dirección para que solo se pueda llegar con tráfico reenviado.


1

Socat OpenWRT

Socat ya se ha indicado como respuesta, sin embargo, la respuesta indicada no funcionó para mí en mi plataforma, OpenWRT, con una dirección WAN dinámica.

Mi objetivo es reenviar paquetes de unidifusión UDP Wake-on-Lan del puerto UDP 9 de la interfaz WAN a una transmisión de subred en 192.168.20.255.

El roto (iptables)

Yo también probé con iptables, pero cada vez que agrego una regla que termina en 255, la regla se convierte en Mush con la dirección de destino 0.0.0.0 cuando imprimo con:

iptables -t nat -L

Creo que iptables no es capaz de multiplexar el tráfico, como se requiere en una conversión de difusión única para difusión.

Lo malo (entradas falsas de arp)

Fingir entradas arp no es tan malo, porque los paquetes llegan a todos en el segmento de ethernet, pero tiene las siguientes desventajas

  • Usted "consume" una dirección IP
  • La dirección IP de destino en el paquete WoL es incorrecta, aunque la obtenga porque la dirección MAC es FFFF ...
  • Un mal funcionamiento de IP puede ocurrir si alguien en la red usa esa dirección IP.
  • Es una transmisión de Ethernet, y no una transmisión de IP.

Nota: Esto se puede hacer con el arpcomando o ip neighcomando.

El bueno

socat, como lo indica la respuesta anterior, es rudo. La respuesta anterior de socat, sin embargo, me encontré con algunos problemas.

  1. Mi socat no reenvió el tráfico cuando el destino de transmisión UDP era 255.255.255.255. Evité esto restringiendo la subred de difusión a la que uso probablemente sea más segura.
  2. Cuando configuré la dirección de enlace en 0.0.0.0, me encontré con una tormenta de transmisión debido al tráfico que rebotaba en socat desde mi LAN. Primero resolví esto vinculando a mis ddns públicos, sin embargo, esto no es ideal porque es posible que los ddns no estén disponibles y mi dirección IP asignada dinámicamente sea mi cambio.

Pude vincularme a 0.0.0.0 (todas las direcciones) y evitar la tormenta de transmisión al agregar una regla de iptables para evitar que la transmisión entrante rebote en socat desde el lado de LAN. Esta regla, además de una regla de iptables para aceptar el tráfico en el puerto UDP 9, y una regla de iptables para registrarla, obtenemos las siguientes tres reglas además del comando socat.

iptables -I input_wan_rule -p udp --dport 9 -j ACCEPT -m comment --comment "firewall entry to allow udp port 9 to socat"
iptables -I input_wan_rule -p udp --dport 9 -j LOG --log-prefix 'Received MAGIC PACKET on udp/9'
iptables -I input_lan_rule -p udp --dport 9 -d 192.168.20.0/24 -j DROP -m comment --comment "block broadcast from bouncing back to socat to avoid storm"

killall socat 2>/dev/null
socat -u -T1 UDP-LISTEN:9,bind=0.0.0.0,fork UDP-DATAGRAM:192.168.20.255:9,broadcast &

Para los OpenWRTers, pegar esto /etc/firewall.usery emitir /etc/init.d/firewall restartes suficiente.

Felicitaciones, ahora debería tener WoL trabajando para su red desde cualquier lugar de la web.


0

En realidad, netfilter no puede hacer ninguna transmisión, el mecanismo de enrutamiento lo hace.

Pero descarta cualquier transmisión reenviada por defecto.

Se hizo posible reenviar la transmisión UDP dirigida en el kernel de Linux reciente (alrededor de la versión 5.0)

Debe modificar el bc_forwardingparámetro para transmitir la interfaz de red:

sudo sysctl -w net.ipv4.conf.eth1.bc_forwarding=1

(Nota: parece la opción net.ipv4.conf. Todo .bc_forwarding no funciona)

Así que ahora, kernel sobre 5.0 + iptables debería ser suficiente para ti

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.