
Я столкнулся со странной проблемой при попытке загрузить большой набор правил iptables в контейнер LXC (на виртуальной машине все работает нормально).
Контейнер работает под управлением Linux Debian 12 bookworm.
Я могу настроить правила и сохранить их с помощью:
/usr/sbin/netfilter-persistent save
Однако, если я попытаюсь загрузить их, я получу это сообщение об ошибке (длина файла составляет 694 символа)
$ sudo iptables-restore < /etc/iptables/rules.v4
sendmsg() failed: Message too long
iptables-restore: line 692 failed: Message too long.
Странно, что если я добавляю подробный режим, то все работает нормально.
$ sudo iptables-restore -v < /etc/iptables/rules.v4 && echo ok
(...)
# Completed on Fri Sep 15 08:57:48 2023
ok
Однако если я пытаюсь загрузить большой файл (33750 строк), я всегда получаю ошибку «Слишком длинное сообщение» — как в подробном режиме, так и в обычном.
Все нагрузочные тесты отлично работают на виртуальной машине (та же ОС).
Так что мне интересно, есть ли где-то в LXC ограничение по строкам или памяти? Я пробовал поиграться, limits.conf
но пока ничего не изменилось.
Есть идеи ?
РЕДАКТИРОВАТЬВот дополнительная информация по воспроизведению этого поведения:
Версия ядра:
Linux xxxxxx 6.2.16-10-pve #1 SMP PREEMPT_DYNAMIC PMX 6.2.16-10 (2023-08-18T11:42Z) x86_64 GNU/Linux
Некоторые версии пакетов (гостевой контейнер):
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
Пакеты хоста:
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
Небольшой набор правил таков:
# 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
решение1
Вам следует рассмотреть возможность использования ipset для сохранения адресов хостов/сетей для правил block_spam* (и, вероятно, объединить их в один набор), это будет быстрее. Или просто перейдите на nftables и используйте встроенные наборы.
решение2
Если вы посмотрите на страницу руководства sendmsg(), то увидите, что на самом деле у нее нет ответа, указывающего на то, что сообщение слишком большое. Однако она возвращает ENOBUFS, если в буфере сообщений недостаточно места — похоже, но не то же самое. Я подозреваю, что именно это здесь и происходит. И происходит, когда ничто не очищает буфер сообщений — каким-то образом произошел сбой связи сокета. Почему iptables-restore пишет в сокет? Скорее всего, он пытается записать записи журнала (или одну большую), но это в основном догадки. В большинстве современных Linux 'iptables-restore' — это символическая ссылка, указывающая на одну из нескольких реализаций инструментов фильтрации пакетов.
Если iptables-restore -v
работает, то у вас есть обходной путь, однако наиболее ВЕРОЯТНАЯ причина наличия большого количества правил брандмауэра заключается в том, что вы добавляете правила об отдельных клиентских адресах напрямую. Это нормально для небольшого количества адресов, НО НЕ МАСШТАБИРУЕТСЯ. Как говорит @Tomek, использование ipset
— гораздо лучшее решение (это масштабируется).