1/16 (木)
[Linux] firewall-cmd --direct がエラー
Linux で firewalld を使う場合、firewall-cmd コマンドを使ってゾーン(zone)を単位としたアクセス制御ルールを行うが、それよりも細かい制御を行いたい場合には firewall-cmd --direct を使うことで firewalld のバックエンドとなっている iptables を制御することができる。
Docker システムに複数の bridge ネットワークを作成した場合、bridge ネットワーク1と bridge ネットワーク2の間にあるコンテナ間では通信ができない。 これを許可するための細かなアクセス制御は firewalld レベルではできず、iptables での制御が必要となる。
そこで firewall-cmd ---direct を使って iptables に対するルールを追加するのだが、
/usr/bin/firewall-cmd --direct --add-rule ipv4 filter DOCKER-USER 0 -p tcp ! -i br-9b6523115ab2 -o br-9b6523115ab2 -s 172.18.0.0/16 -d 172.19.0.5 --dport 8443 -j DROP
を実行したら Error: COMMAND_FAILED: '/usr/sbin/iptables-restore -w -n' failed: iptables-restore: line 3 failed というエラーが出てしまう。
追記: 1/26(木)
上記のエラーを解決するには、firewalld の IndividualCalls という設定を変えればよいと分かる。
# IndividualCalls # Do not use combined -restore calls, but individual calls. This increases the # time that is needed to apply changes and to start the daemon, but is good for # debugging. # Default: no # この行をコメントアウト # IndividualCalls=no # この行を追加 IndividualCalls=yes
ただし表示は変わったが、という Error: COMMAND_FAILED: '/usr/sbin/iptables -w10 -t filter -I DOCKER-USER 1 -p tcp ! -i br-9b6523115ab2 -o br-9b6523115ab2 -s 172.18.0.0/16 -d 172.19.0.5 --dport 8443 -j DROP' failed: iptables: No chain/target/match by that name. という別のエラーが出てしまう。
追記: 1/27(金)
解決した。
原因はシステムを動かしている Rocky Linux 8 が、firewalld のバックエンドとして iptables ではなく nftables を使うように切り替えていたのが原因のようだ。 /etc/firewalld/firewalld.conf の FirewallBackend を変更して iptables を使うようになると、firewall-cmd ---direct は無事成功した。
# FirewallBackend # Selects the firewall backend implementation. # Choices are: # - nftables (default) # - iptables (iptables, ip6tables, ebtables and ipset) # この行をコメントアウト # FirewallBackend=nftables # この行を追加 FirewallBackend=iptables
Rocky Linux 8 の初期設定でも firewall-cmd ---direct が成功したことがあったはず。 どこかで挙動が変わったのか…