El contenedor LXC no puede cargar reglas de iptables grandes

El contenedor LXC no puede cargar reglas de iptables grandes

Me enfrento a un problema extraño cuando intento cargar un gran conjunto de reglas de iptables en un contenedor LXC (está funcionando bien en una máquina virtual).

El contenedor ejecuta Linux Debian 12 bookworm.

Puedo configurar las reglas y guardarlas con:

 /usr/sbin/netfilter-persistent save

Sin embargo, si intento cargarlos, aparece este mensaje de error (el archivo tiene 694 caracteres de longitud).

$ sudo  iptables-restore < /etc/iptables/rules.v4
sendmsg() failed: Message too long
iptables-restore: line 692 failed: Message too long.

Lo extraño es que si agrego el modo detallado, funciona bien.

$ sudo  iptables-restore -v < /etc/iptables/rules.v4 && echo ok
(...)
# Completed on Fri Sep 15 08:57:48 2023
ok

Sin embargo, si intento cargar un archivo grande (33750 líneas), siempre aparece el error "Mensaje demasiado largo", en modo detallado o no.

Todas las pruebas de carga funcionan bien en una máquina virtual (mismo sistema operativo).

Entonces me pregunto si hay un límite de línea o de memoria en algún lugar de LXC. Intenté jugar con él limits.confpero todavía no cambió nada.

Alguna idea ?

EDITARAquí hay más información para reproducir este comportamiento:

Versión del núcleo:

Linux xxxxxx 6.2.16-10-pve #1 SMP PREEMPT_DYNAMIC PMX 6.2.16-10 (2023-08-18T11:42Z) x86_64 GNU/Linux

Algunas versiones de paquetes (contenedor invitado):

ii  iptables                            1.8.9-2                                 amd64        administration tools for packet filtering and NAT
ii  iptables-persistent                 1.0.20                                  all          boot-time loader for netfilter rules, iptables plugin
ii  libip4tc2:amd64                     1.8.9-2                                 amd64        netfilter libip4tc library
ii  libip6tc2:amd64                     1.8.9-2                                 amd64        netfilter libip6tc library
ii  libnetfilter-conntrack3:amd64       1.0.9-3                                 amd64        Netfilter netlink-conntrack library
ii  libxtables12:amd64                  1.8.9-2                                 amd64        netfilter xtables library
ii  netfilter-persistent                1.0.20                                  all          boot-time loader for netfilter configuration

paquetes de host:

ii  lxc-pve                              5.0.2-4                             amd64        Linux containers userspace tools
ii  lxcfs                                5.0.3-pve3                          amd64        LXC userspace filesystem
ii  pve-lxc-syscalld                     1.3.0                               amd64        PVE LXC syscall daemon

El pequeño conjunto de reglas es:

# Generated by iptables-save v1.8.9 (nf_tables) on Fri Sep 15 08:57:48 2023
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:block_spam2 - [0:0]
:block_spam1 - [0:0]
:block_spam3 - [0:0]
:incoming_net - [0:0]
:sensitive_daemons - [0:0]
-A INPUT -j block_spam1
-A INPUT -j block_spam2
-A INPUT -j block_spam3
-A INPUT -j sensitive_daemons
-A INPUT -j incoming_net
-A INPUT -j sensitive_daemons
-A block_spam2 -s 1.0.1.0/24 -j DROP
-A block_spam2 -s 84.22.192.0/19 -j DROP
-A block_spam1 -s 103.39.156.0/22 -j DROP
-A block_spam1 -s 5.255.220.0/22 -j DROP
-A block_spam3 -s 87.245.234.136/32 -j DROP
-A block_spam3 -s 217.199.224.0/19 -j DROP
[...] 675 lines here : block_spam[1-3] with a uniq ip address [...]
-A incoming_net -d 192.168.1.248/29 -p tcp -m tcp --dport 80 -j ACCEPT
-A incoming_net -d 192.168.1.248/29 -p tcp -m tcp --dport 443 -j ACCEPT
-A incoming_net -d 192.168.1.248/29 -p tcp -j DROP
-A sensitive_daemons -s 192.168.1.248/29 -p tcp -m tcp --dport 22 -j DROP
-A sensitive_daemons -s 192.168.1.0/24 -d 192.168.1.24/32 -p tcp -m tcp --dport 22 -j ACCEPT
-A sensitive_daemons -p tcp -m tcp --dport 22 -j DROP
COMMIT
# Completed on Fri Sep 15 08:57:48 2023

Respuesta1

Debería considerar usar ipset para mantener las direcciones de host/red para las reglas block_spam* (y probablemente fusionarlas en un solo conjunto), esto sería más rápido. O simplemente pase a nftables y use conjuntos integrados.

Respuesta2

Si busca la página del manual sendmsg(), verá que en realidad no tiene una respuesta que indique que un mensaje era demasiado grande. Sin embargo, devuelve ENOBUFS si no hay suficiente espacio en el búfer de mensajes; es similar, pero no es lo mismo. Sospecho que eso es lo que está pasando aquí. Y se produce cuando nada vacía el búfer de mensajes: las comunicaciones del socket han fallado de alguna manera. ¿Por qué iptables-restore escribe en un socket? Lo más probable es que esté intentando escribir entradas de registro (o una grande), pero eso son principalmente conjeturas. En la mayoría de los Linux modernos, 'iptables-restore' es un enlace simbólico que apunta a una de varias implementaciones de herramientas de filtrado de paquetes.

Si iptables-restore -vfunciona, entonces tiene una solución alternativa; sin embargo, la razón más PROBABLE para tener muchas reglas de firewall es porque está agregando reglas sobre direcciones de clientes individuales directamente. Esto está bien para una pequeña cantidad de direcciones, pero NO ESCALA. Como dice @Tomek, usar ipsetes una solución mucho mejor (esto escala).

información relacionada