IPTables y preguntas de DHCP?

8

En mi otro hilo, estaba hablando de algunas cosas interesantes sobre la política y los estados de iptables , ahora me gustaría entender más sobre cómo funciona el DHCP y cómo lo entiende iptables.

ETH0 está conectado a mi conmutador principal que recibe la IP dinámica de mi enrutador para obtener no solo acceso a Internet sino también acceso a mi red externa.

ETH1 es la tarjeta interna que está conectada a un conmutador interno donde los clientes X reciben su IPS de este servidor

La red ETH1 es 192.168.1.0/255.255.255.0 donde la IP del servidor es 192.168.1.254.

Por lo que entendí, dhcp es un protocolo de arranque, por lo que incluso si tiene sus políticas de firewall para DROP todo, su red aún recibiría el DHCP, que en las pruebas que hice parecía ser cierto.

Desde tcpdump:

root@test:~# tcpdump -i eth1 port 67 or 68
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes
11:34:03.943928 IP 192.168.1.2.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 00:0c:29:29:52:8b (oui Unknown), length 303
11:34:03.957647 IP 192.168.1.254.bootps > 192.168.1.2.bootpc: BOOTP/DHCP, Reply, length 300
11:34:06.492153 IP 192.168.1.2.bootpc > 192.168.1.254.bootps: BOOTP/DHCP, Request from 00:0c:29:29:52:8b (oui Unknown), length 303
11:34:06.506593 IP 192.168.1.254.bootps > 192.168.1.2.bootpc: BOOTP/DHCP, Reply, length 300

Hice una regla de registro simple para ver qué hace iptables:

root@test:~# tail -f /var/log/syslog
Oct 15 11:30:58 test kernel: IN=eth1 OUT= MAC=ff:ff:ff:ff:ff:ff:00:0c:29:29:52:8b:08:00 SRC=192.168.1.2 DST=255.255.255.255 LEN=331 TOS=0x00 PREC=0x00 TTL=128 ID=9527 PROTO=UDP SPT=68 DPT=67 LEN=311
Oct 15 11:31:43 test kernel: IN=eth1 OUT= MAC=ff:ff:ff:ff:ff:ff:00:0c:29:29:52:8b:08:00 SRC=192.168.1.2 DST=255.255.255.255 LEN=331 TOS=0x00 PREC=0x00 TTL=128 ID=9529 PROTO=UDP SPT=68 DPT=67 LEN=311
Oct 15 11:33:32 test kernel: IN=eth1 OUT= MAC=ff:ff:ff:ff:ff:ff:00:0c:29:29:52:8b:08:00 SRC=192.168.1.2 DST=255.255.255.255 LEN=331 TOS=0x00 PREC=0x00 TTL=128 ID=9531 PROTO=UDP SPT=68 DPT=67 LEN=311
Oct 15 11:34:03 test kernel: IN=eth1 OUT= MAC=ff:ff:ff:ff:ff:ff:00:0c:29:29:52:8b:08:00 SRC=192.168.1.2 DST=255.255.255.255 LEN=331 TOS=0x00 PREC=0x00 TTL=128 ID=9533 PROTO=UDP SPT=68 DPT=67 LEN=311

Aquí están mis reglas de iptables en el momento:

# deny all traffic
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT DROP

# Use stateful inspection feature to only allow incoming connections
# related to connections I have already established myself
$IPT -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
$IPT -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# allow all traffic on lo interface
$IPT -A INPUT -i lo -j ACCEPT
$IPT -A OUTPUT -o lo -j ACCEPT

Entonces, incluso con la POLÍTICA predeterminada para eliminar todo, todavía obtengo el DHCP en mi red, mientras que toma mucho más tiempo renovar una IP y tal.

Si agrego la siguiente regla a mi firewall:

$IPT -I OUTPUT -o $INTIF -p udp --dport 67:68 --sport 67:68 -j ACCEPT

Tomará MUCHO MENOS TIEMPO actualizar cualquier dhcp del cliente.

Considerando lo anterior:

  1. ¿Por qué lleva más tiempo actualizarlo incluso si no está siendo bloqueado?
  2. ¿es posible DROP el servidor dhcp en absoluto sin apagarlo?
  3. ¿Es posible ACEPTAR el servidor dhcp dentro de iptables con BOOTP? ¿Cómo se hace eso?

Si conoces buenos enlaces, no me importaría tomar mucho :)

Guapo
fuente
Estoy un poco confundido por su salida de registro tcpdump e iptables. ¿Está monitoreando la interfaz de red en modo promiscuo? ¿Su servidor con firewall realmente utiliza DHCP para configurar su NIC?
Steven Monday
@Steven el servidor que tiene el firewall que es el mencionado anteriormente tiene eth0 y eth1, eth0 recibe dhcp como cliente desde el exterior y eth1 es mi servidor dhcp para mi red interna, de la que estoy hablando. ¿Qué quieres decir con que Are you monitoring the network interface in promiscuous modetodavía estoy aprendiendo ...
Guapo
Oh ok ¡Realmente necesita describir mejor su red y servidores si quiere que alguien entienda su pregunta!
Steven lunes
Acerca del modo promisorio: en.wikipedia.org/wiki/Promiscuous_mode
Steven Monday
@ Steven lo hará ahora, gracias por señalar, ¿crees que tengo que especificar algo más que no sea el diseño de la red?
Guapo

Respuestas:

13

Contestaré # 2: No.

Al obtener una dirección IP, el demonio dhcp crea un socket sin procesar para la interfaz de red y maneja el protocolo UDP. Por lo tanto, los paquetes UDP nunca pasan por iptables.

La razón por la que el demonio dhcp tiene que implementar UDP es que el núcleo solo puede manejar UDP (de hecho, todo el conjunto TCP / IP) cuando la interfaz tiene una dirección IP. Anteriormente, los demonios dhcp primero le daban a una interfaz la dirección IP de 0.0.0.0, pero eso ya no funciona.

Mark Wagner
fuente
paquete de zócalo. raw sockets no pasan por iptables. Afaict. unix.stackexchange.com/a/447524/29483
sourcejedi
5

Agregando

$IPT -I INPUT -i $INTIF -p udp --dport 67:68 --sport 67:68 -j ACCEPT

hará que la actualización de DHCPD sea más rápida :) Funcionará tanto de ENTRADA como de SALIDA. Puede DROP dhcpd con ebtables, no con iptables. DHCPD escuchando a 0.0.0.0, no dentro de IP

Ta Coen
fuente
+1 Lo tenía en INPUT y me estaba tomando la misma cantidad de tiempo que si no lo tuviera en mis reglas. Cuando lo hice OUTPUT hizo una GRAN diferencia. Leeré sobre ebtables gracias.
Guapo
$ IPT -I INPUT -i $ INTIF -s 0/0 -p udp --dport 67:68 --sport 67:68 -j ACCEPT
Ta Coen
acabo de probar lo anterior y todavía me toma demasiado tiempo en comparación con el uso de la regla OUTPUT
Guapo
Dado que la política es DROP, deberá usar INPUT y OUTPUT.
Ta Coen
3

Mi observación reciente, sobre OpenWRT Kamikaze 7.09 = 2.4.34 y udhcpc de busybox 1.4.2:

Tengo una política de "ACEPTAR" en la cadena de SALIDA, y en la dirección de ENTRADA, originalmente me basé en esta clásica regla general:

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

para permitir las respuestas DHCP en (a mi udhcpc) ​​en la interfaz WAN. Es decir, aquí es donde el servidor DHCP aguas arriba de mi ISP me asigna una dirección IP.

Tenga en cuenta la diferencia entre un intercambio DHCP inicial (descubrimiento, oferta, solicitud, reconocimiento) y una renovación de arrendamiento DHCP (solicitud, reconocimiento).

Después del arranque, udhcpc comienza con el intercambio inicial completo. Ese intercambio tendría éxito. Y otra renovación o dos tendrían éxito también, solo una solicitud y reconocimiento. El servidor DHCP de mi ISP normalmente solicita un tiempo de renovación de aproximadamente una hora a 1.5 horas, por lo tanto, mi cliente DHCP solicita una renovación cada 30 a 45 minutos (este comportamiento se basa en el RFC).

Pero, alrededor de la tercera o cuarta renovación, comenzaría a ponerse interesante. TCPdump mostraría unos tres intentos de renovación, seguidos de un intercambio inicial completo, que en un lapso de tiempo de solo unos minutos o incluso segundos. Como si a udhcpc no le gustara lo que obtuvo :-( y finalmente quedaría satisfecho con el intercambio completo. Después de eso, otra renovación en media hora tendría éxito ... y la historia se repetiría nuevamente.

Me di cuenta de que tal vez sea el seguimiento de la conexión en el kernel lo que está mal. Como si la entrada de conntrack caducara después de dos horas más o menos, y las renovaciones posteriores de DHCP fallan porque el ACK del servidor en realidad no llega a udhcpc escuchando en el socket. Tenga en cuenta que tcpdump (libpcap) escucha en la interfaz sin formato y puede ver todos los paquetes entrantes, antes de que estén sujetos a iptables. Una vez que udhcpc abandona las renovaciones y, desesperado, trata de comenzar desde cero utilizando un intercambio completo (comenzando con DESCUBRIR), el núcleo establece una nueva entrada de Conntrack y puede entender los paquetes relacionados por más tiempo ...

Efectivamente, una vez que agregué algo como:

iptables -A INPUT -i $OUT_IF -p udp --sport 67 --dport 68 -j ACCEPT

Las renovaciones parecen funcionar para siempre.

Puede encontrar útiles los siguientes argumentos de tcpdump cmdline:

tcpdump -vv -s 1500 -i eth0.1 port 67 or port 68

Nota: el -vvpide la salida detallada del disector. eth0.1es mi puerto WAN (también una interfaz "NAT fuera").

Un atributo interesante en los paquetes ACK es el LT: campo = tiempo de arrendamiento máximo / sugerido en segundos. Las solicitudes de DHCP se envían del puerto 68 al puerto 67. Las respuestas provienen del puerto 67 al puerto 68.

frr
fuente
Tu historia no tiene sentido. No importa si es inicial o renovar, el cliente siempre inicia el intercambio de DHCP enviando desde el puerto 68 al puerto 67, ya sea a una IP específica o como transmisión. Y con ACEPTACIÓN saliente, esto siempre funcionará. Una respuesta del destino saliente siempre debe pasar a través de entrante por la regla ESTABLECIDA, por lo que la renovación debe funcionar para siempre solo con la regla ESTABLECIDA, ya que cada renovación también renueva o recrea el estado de Conntrack.
Mecki
Una renovación envía una solicitud openwrt:68 -> dhcpserver:67y el ACK será dhcpserver:67 -> openwrt:68. Esto cuenta como ESTABLECIDO y pasará. Si el antiguo estado de conntrack expiró, esto establece uno nuevo. Si hay un problema, solo puede ser con el intercambio inicial como el DESCUBRIMIENTO es 0.0.0.0:68 -> 255.255.255.255:67y la OFERTA será dhcpserver:67 -> new-openwrt:68, lo que no cuenta como ESTABLECIDO. Esto solo funciona porque DHCP generalmente pasa por alto iptables con un socket de paquetes en Linux, de lo contrario se requiere una regla entrante que permita paquetes desde el puerto UDP 67 o al puerto UDP 68.
Mecki
1
También dice que varias renovaciones tuvieron éxito, sin embargo, cada renovación que tenga éxito también renovará el estado de Conntrack, por lo que si sus estados de Conntrack expiran después de 2 horas, una renovación lo extenderá nuevamente por otras 2 horas y así sucesivamente y así nunca expirará . Sin embargo, el tiempo de espera predeterminado de conntrack para UDP es de solo 30 segundos y no de 2 horas, y dudo que OpenWRT haya cambiado eso a 2 horas, ya que sería una locura. Entonces tu historia me parece totalmente defectuosa.
Mecki
@Mecki, gracias por los valiosos comentarios :-) Por ahora, mi respuesta tiene 4 años. Hace aproximadamente un año, mi ASUS WL500G Deluxe estaba empezando a debilitarse (después de aproximadamente 12 años de tiempo de ejecución, debido a los reemplazos de condensadores) y tiré ese viejo Kamikaze junto con el hardware. En este momento estoy ejecutando un OpenWRT más actual en un TP-Link AP moderno, y después de pensarlo, no he reutilizado mis scripts de firewall antiguos. OpenWRT ahora parece tener un buen firewall listo para usar ... Quiero decir que no puedo verificar mis reclamos anteriores. Todo lo que sé es que la regla adicional de iptables ayudó.
Viernes