O contêiner LXC não consegue carregar grandes regras de iptables

O contêiner LXC não consegue carregar grandes regras de iptables

Estou enfrentando um problema estranho quando tento carregar um grande conjunto de regras do iptables em um contêiner LXC (está funcionando bem em uma máquina virtual).

O contêiner está executando o bookworm Linux Debian 12.

Consigo configurar as regras e salvá-las com:

 /usr/sbin/netfilter-persistent save

No entanto, se eu tentar carregá-los, recebo esta mensagem de erro (o arquivo tem 694 caracteres)

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

O que é estranho é que se eu adicionar o modo detalhado, ele estará funcionando bem

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

Porém, se tento carregar um arquivo grande (33.750 linhas), sempre recebo o erro "Mensagem muito longa", no modo detalhado ou não.

Todos os testes de carregamento estão funcionando bem em uma máquina virtual (mesmo sistema operacional).

Então, estou me perguntando se existe um limite de linha ou limite de memória em algum lugar do LXC? Tentei brincar, limits.confmas ainda não mudou nada.

Qualquer ideia ?

EDITARAqui estão mais informações para reproduzir esse comportamento:

Versão do kernel:

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

Versão de alguns pacotes (contêiner convidado):

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

pacotes 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

O pequeno conjunto de regras é:

# 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

Responder1

Você deve considerar usar ipset para manter endereços de host/rede para regras block_spam* (e provavelmente mesclá-los em apenas um conjunto), isso seria mais rápido. Ou simplesmente mude para nftables e use conjuntos integrados.

Responder2

Se você consultar a página de manual sendmsg(), verá que na verdade ela não possui uma resposta indicando que a mensagem era muito grande. No entanto, ele retorna ENOBUFS se não houver espaço suficiente no buffer de mensagens - semelhante, mas não a mesma coisa. Suspeito que é isso que está acontecendo aqui. E é causado quando nada está esvaziando o buffer de mensagens - as comunicações do soquete falharam de alguma forma. Por que o iptables-restore está gravando em um soquete? O mais provável é que você esteja tentando escrever entradas de log (ou uma grande), mas isso é principalmente suposição. Na maioria dos Linux modernos, 'iptables-restore' é um link simbólico apontando para uma das várias implementações de ferramentas de filtragem de pacotes.

Se iptables-restore -vfuncionar, então você tem uma solução alternativa, no entanto, o motivo mais PROVÁVEL para ter muitas regras de firewall é porque você está adicionando regras diretamente sobre endereços de clientes individuais. Isso é adequado para pequenos números de endereços, mas NÃO ESCALA. Como diz @Tomek, usar ipseté uma solução muito melhor (isso é escalonável).

informação relacionada