firewalld: FirewallBackend (2)

前回はFirewalldのBackendがiptablesからnftablesに変更になったため、direct rulesでACCEPTをしてもrich rulesやservicesの参照に進んでしまうため、Backendをiptablesに戻すことで対処した。Forwardを行う場合、rich rulesではACCEPTを行う方法が分からず、zoneのtargetをACCEPTに変えるのはInputチェインへの影響が大きかったためnftablesの使用を断念した。

今回はnftablesへの移行を行うためにdirect rulesとzone/rich rulesの使い分けを整理した。次の図は整理結果の模式図。

firewalldの整理

zoneは3種類用意することにした。LAN内はtrusted zoneで処理する方針にしたので、細かなルール設定は不要。LAN内に対しても通信制限をかける場合はtrusted zoneにdropのrich ruleを設定する予定。

  1. trusted zone :LAN内IPアドレス向け
    • –add-source=ipset:v4_private
    • –add-source=ipset:v6_private
  2. public zone :デフォルトゾーン。外部公開向け
    • –add-interface=eth0 (wan I/F)
  3. block zone :外部公開の対象外を設定する際に使用する
    • –add-source=ipset:v4_block_list
    • –add-source=ipset:v6_block_list
  4. pass zone :SSHやVPNを許可するIPアドレス向け
    • –add-source=ipset:v4_pass_global
    • –add-source=ipset:v6_pass_global

当初は4種類のzoneで運用しようと考えたが、block zoneとpass zoneのIPアドレスが重複する可能性があるため、pass zoneは廃止し、public zone内のrich rulusでSSHやVPNはsource IPアドレスを限定する方針に変更とした。

zone drifting (AllowZoneDrifting)はもともとがバグ挙動でdisableが推奨なのでpassで許可するServiceは基本的にPublicで許可するServiceを包含する方針となる。

設定完了後(firewall-cmd –reload)に動作を確認し、問題なければFirewallBackendをnftablesに変更する。

# FirewallBackend
# Selects the firewall backend implementation.
# Choices are:
# - nftables (default)
# - iptables (iptables, ip6tables, ebtables and ipset)
#FirewallBackend=iptables
FirewallBackend=nftables

尚、zoneのtargetをdefaultとするかrejectとするかでは挙動が異なるので注意が必要。issueに違いがまとめられている。特に気を付けるのはrejectではipv6-icmpを許可する設定が入っていないのでIPv6のneighbor solicitationあたりがrejectされてしまう点。backendがiptablesであれば次のコマンドで確認ができる。

# ip6tables -L -n -v
Chain IN_pass_global (1 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 IN_pass_global_log  all      *      *       ::/0                 ::/0
    0     0 IN_pass_global_deny  all      *      *       ::/0                 ::/0
    0     0 IN_pass_global_allow  all      *      *       ::/0                 ::/0
    0     0 REJECT     all      *      *       ::/0                 ::/0                 reject-with icmp6-adm-prohibited

Chain IN_public (2 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 IN_public_log  all      *      *       ::/0                 ::/0
    0     0 IN_public_deny  all      *      *       ::/0                 ::/0
    0     0 IN_public_allow  all      *      *       ::/0                 ::/0
    0     0 ACCEPT     icmpv6    *      *       ::/0                 ::/0

targetがdefaultになっているpublicではicmpv6をACCEPTする設定が入っているが、targetをrejectで作成したpass_globalには入っていない。

defaultを使えばよいが、rejectを使いたい場合は次のように設定を足しておく必要がある。(backendがiptablesであればdirect rulesでACCEPTしておいても良い)

# firewall-cmd --permanent --zone=pass_global --add-protocol ipv6-icmp

より細かく制御したければicmp typeを確認して許可したいものだけrich ruleを作成すればよい。

# firewall-cmd --get-icmptypes
address-unreachable bad-header beyond-scope communication-prohibited destination-unreachable echo-reply echo-request failed-policy fragmentation-needed host-precedence-violation host-prohibited host-redirect host-unknown host-unreachable ip-header-bad neighbour-advertisement neighbour-solicitation network-prohibited network-redirect network-unknown network-unreachable no-route packet-too-big parameter-problem port-unreachable precedence-cutoff protocol-unreachable redirect reject-route required-option-missing router-advertisement router-solicitation source-quench source-route-failed time-exceeded timestamp-reply timestamp-request tos-host-redirect tos-host-unreachable tos-network-redirect tos-network-unreachable ttl-zero-during-reassembly ttl-zero-during-transit unknown-header-type unknown-option
firewall-cmd --permanent --add-rich-rule='rule icmp-type name="neighbor-solicitation" accept' --zone=pass_global

targetがdefaultかrejectかはforwardの挙動にも違いが出ると記載されているので何時かのために頭の片隅で覚えておきたい。FirewalldはForwardしないなら思った通りに動くんですけどね・・・

今回使う各zoneのtargetは初期設定から変更せずに使うのでrejectで動かすものは無い。

  • trusted : accept
  • public : default
  • drop : drop

追記:恐らくこちらのバグでnftablesをbackendにした際にipsetが設定できない状態になっているのでbackendはiptablesに戻しを行った。