
LXC コンテナに大きな iptables ルール セットをロードしようとすると、奇妙な問題が発生します (仮想マシンでは正常に動作しています)。
コンテナは 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 行) をロードしようとすると、詳細モードかどうかに関係なく、常に「メッセージが長すぎます」というエラーが発生します。
すべての読み込みテストは仮想マシン (同じ OS) 上で正常に動作しています。
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
block_spam* ルールのホスト/ネットワーク アドレスを保持するには、ipset の使用を検討してください (おそらく 1 つのセットにマージされます)。この方が高速になります。または、nftables に移行して組み込みセットを使用します。
答え2
sendmsg() のマニュアル ページを調べると、メッセージが大きすぎることを示す応答が実際にはないことがわかります。ただし、メッセージ バッファーに十分なスペースがない場合は ENOBUFS が返されます。これは似ていますが、同じではありません。ここで起こっているのはそれだと思います。これは、メッセージ バッファーを空にするものが何もない場合に発生します。つまり、ソケット通信が何らかの方法で失敗したのです。iptables-restore がソケットに書き込むのはなぜでしょうか。おそらく、ログ エントリ (または 1 つの大きなエントリ) を書き込もうとしているのでしょうが、これはほとんど推測に過ぎません。最近の Linux のほとんどでは、「iptables-restore」は、パケット フィルタリング ツールのいくつかの実装の 1 つを指すシンボリック リンクです。
動作する場合iptables-restore -v
は回避策がありますが、ファイアウォール ルールが多数存在する最も可能性の高い理由は、個々のクライアント アドレスに関するルールを直接追加しているためです。アドレス数が少ない場合は問題ありませんが、拡張性はありません。@Tomek が言うように、 を使用する方がipset
はるかに優れたソリューションです (拡張性があります)。