
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.conf
pero 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 -v
funciona, 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 ipset
es una solución mucho mejor (esto escala).