firewalld 2.0.1 の drop.xml のバグを回避する
Fedora 39 になって、firewalld が 2.0.1 になった。
だがしかし、巨大なゾーンファイルを利用すると最悪ではシステムフリーズを起こす問題が発生した。
そこで今回は、巨大なDROPゾーンをipsetを用いて回避する方法を説明する。
なぜ巨大なDROPゾーンが存在するのか
例えば有害な国からの通信を拒否したい場合などでは国全体をブロックする必要があり、そのためにDROPゾーンが巨大化していた。
本サイトでは有害な通信を行ってくる中国、韓国、オランダなどの通信は拒絶している。
結果として拒否リストだけでも数万行に達していた。
どのような問題が起こるのか
巨大なゾーンファイルを利用すると、firewalld 2.0.1 では初期化が終了せずにメモリ消費が無限に増加していく。
そのため全てのメモリを消費した後にスワップ領域まで消費し、スワップアウトが行えなくなってシステムが固まってしまった。
明確な発生条件は判明していないが、巨大なゾーンファイルを使用した場合は必ず発生していた。
Fedora 38 では発生していなかった問題なので、firewalld が 2.0 にアップグレードした時に混入したバグだと思われ、firewalld の GitHub に報告しておいたので、修正が待たれる状況である。
どの様に回避するのか
拒否リストを drop.xml (/etc/firewalld/zones/drop.xml) に直接記載しないで ipset に記載して間接的に制御させる。
/etc/firewalld/zones/drop.xml を退避する
# cp /etc/firewalld/zones/drop.xml /etc/firewalld/zones/drop.xml.org
/etc/firewalld/zones/drop.xml を変更する
内容を以下の様に変更
<?xml version="1.0" encoding="utf-8"?> <zone target="DROP"> <short>Drop</short> <description>Unsolicited incoming network packets are dropped. Incoming packets that are related to outgoing network connections are accepted. Outgoing network connections are allowed.</description> <source ipset="DROPLIST"/> <forward/> </zone>
「DROPLIST」は任意の名前でもOK
ただし、統一する必要がある。
/etc/firewalld/zones/drop.xml.org から /etc/firewalld/ipset/DROPLIST.xml を作る
エディターなどを用いて一括変換を行うと簡単。
「drop.xml」
<?xml version="1.0" encoding="utf-8"?> <zone target="DROP"> <short>Drop</short> <description>Unsolicited incoming network packets are dropped. Incoming packets that are related to outgoing network connections are accepted. Outgoing network connections are allowed.</description> <source address="1.192.0.0/16"/> <source address="1.193.0.0/16"/> <source address="1.194.0.0/16"/> <source address="1.195.0.0/16"/> <source address="1.196.0.0/16"/> <source address="1.197.0.0/16"/> <source address="1.198.0.0/16"/> <source address="1.199.0.0/16"/> </zone>
「DROPLIST.XML」
<?xml version="1.0" encoding="utf-8"?> <ipset type="hash:net"> <entry>1.192.0.0/16</entry> <entry>1.193.0.0/16</entry> <entry>1.194.0.0/16</entry> <entry>1.195.0.0/16</entry> <entry>1.196.0.0/16</entry> <entry>1.197.0.0/16</entry> <entry>1.198.0.0/16</entry> <entry>1.199.0.0/16</entry> </ipset>
確認
# firewall-cmd --reload success # firewall-cmd --permanent --ipset=DROPLIST --get-entries 1.192.0.0/16 1.193.0.0/16 1.194.0.0/16 1.195.0.0/16 1.196.0.0/16 1.197.0.0/16 1.198.0.0/16 1.199.0.0/16
firewalld の再起動
# systemctrl restart firewalld