firewalld か iptables か — Rocky Linux 9 のファイアウォール、結局どっち?

padlock on laptop with light trails

サーバを立てるたびに地味に迷うのが「ファイアウォールを firewalld で管理するか、iptables で直接書くか」。Rocky Linux には最初から firewalld が入っていますが、正直に言うと私は iptables の方が好きです。一覧でルールがどう効いているか見やすいし、昔から触っているので手に馴染んでいる。

ただ Rocky Linux 9 をしばらく触って、この「好み」の話には一つ大事な前提が抜けがちだと気づきました。この記事では両者を公平に比べたうえで、最後にその前提(=ちょっとした種明かし)まで書きます。

前提条件
  • Rocky Linux 9.x が動作するサーバ
  • sudo 権限
  • SSH 公開鍵認証など基本設定が済んでいると望ましい

1. firewalld の良いところ

Rocky 9 では firewalld が最初から起動しているのが何より楽です。「ゾーン」という単位でルールをまとめ、サービス名で開け閉めできます。

bash
# いま開いているサービスを確認
sudo firewall-cmd --list-all

# HTTP / HTTPS を恒久的に開ける
sudo firewall-cmd --add-service=https --permanent
sudo firewall-cmd --reload

ポート番号を覚えなくても --add-service=https で済むのが firewalld の思想です。新規構築で「必要なサービスだけ開ける」用途では、これが一番ストレスがありません。

ヒント

firewall-cmd --get-services で、名前で開けられるサービスの一覧が出ます(http https ssh postgresql など数百種類)。自作アプリは --add-port=8080/tcp でポート指定も可能。

ポートフォワードも、実は firewalld でできます(「iptables だけの特権」ではありません)。

bash
sudo firewall-cmd --add-masquerade --permanent
sudo firewall-cmd --add-forward-port=port=80:proto=tcp:toport=8080 --permanent
sudo firewall-cmd --reload

2. iptables 流(直接制御)の良いところ

一方で、ルールを直接書く流儀にも根強い良さがあります。私が好きな理由はこのあたり。

  • 一覧でどう制御されているかが見やすい(完全に個人の感覚ですが)
bash
# 設定中のルールをそのまま列挙
sudo iptables -S

# パケットカウンタ付きで確認
sudo iptables -L -n -v
  • fail2ban の jail がチェインと対応していて、どこでブロックしているか追いやすい

fail2ban は失敗回数の多い IP を自動でブロックしますが、その「結果」がルールの一覧にそのまま現れます。「いまどの IP を、どの jail が弾いているのか」を 1 コマンドで突き合わせられるのは、運用していて安心感があります(fail2ban 自体の設定は SSH をブルートフォースから守る記事 を参照)。

  • 古くから使っていて、頭の中にモデルがある

これは技術的優位というより「慣れ」ですが、トラブル時に手が勝手に動くのは実務では立派な武器です。

注意

firewalld と iptables を同時に手で触るのは避けてください。 firewalld は reload のたびに自分のルールセットを再適用するため、手書きの iptables ルールが消える・衝突するといった事故が起きます。「どちらかに寄せる」のが鉄則です。

3. よくある誤解 ——「iptables は古い」のか?

ここからが本題の種明かしです。「firewalld は新しい、iptables は古い」というイメージは、Rocky Linux 9 では正確ではありません

RHEL 8 以降、Linux のパケットフィルタは nftables に一本化されました。Rocky 9 でも事情は同じで、firewall-cmdiptables コマンドも、最終的には同じ nftables を操作しています。

flowchart TD
    A["firewall-cmd"] --> FD["firewalld"]
    B["iptables コマンド"] --> NFT_SHIM["iptables-nft<br/>(nft への翻訳シム)"]
    FD --> NFT["nftables<br/>(カーネルの実体)"]
    NFT_SHIM --> NFT
    NFT --> K["パケットの許可 / 遮断"]

つまり Rocky 9 では:

  • iptables コマンドは本物の iptables ではなく iptables-nft。打ったルールは内部で nftables に翻訳される
  • firewalld もデフォルトで nftables バックエンドで動いている
  • どちらを使っても、最終的に効いているのは nftables の同じルールセット

実際に確認できます。

bash
# "(nf_tables)" と出れば、その iptables は nft の皮をかぶった姿
sudo iptables --version

# 本当の実体はこちらで全部見える
sudo nft list ruleset
text
iptables v1.8.x (nf_tables)
ノート

firewalld のバックエンドは /etc/firewalld/firewalld.confFirewallBackend=nftables で確認できます。Rocky 9 標準ではこれが既定値です。

だから「firewalld vs iptables」は、Rocky 9 においては どちらも下は nftables、上に被せるフロントエンドの好みの違いでしかありません。宗教戦争にする必要はないわけです。

4. 三者を並べて比較

観点firewalldiptables(=iptables-nft)nftables 直
初期状態最初から起動サービスは別途有効化別途有効化
サービス単位の制御--add-service で楽ポート/IP を手書き手書き
ルールの可視性--list-all(抽象的)-S が素朴で見やすいnft list ruleset(実体そのもの)
fail2ban との相性ipset/rich-rule 経由でやや見えにくいjail と対応が追いやすい追える(要 nft 知識)
ポートフォワードできるできるできる
実体nftablesnftablesnftables(そのもの)
学習コスト低い中(既存知識が活きる)中〜高
将来性△(翻訳シム頼み)◎(EL の本命)

5. 結局、どっちを選ぶか

私の落とし所はこうです。

新規構築・サービス単位で開け閉めしたい → firewalld

最初から動いていて、--add-service の抽象化が効く。素直に楽。Web サーバや一般的な公開サーバはこれで十分。

どこで何を弾いているか追いたい → iptables(nft) 流も正解

fail2ban と組み合わせて「いま誰をブロックしているか」を一覧で把握したい運用者には、直接制御の見やすさが効く。好みとして完全に筋が通っている。

これから低レベルを学ぶなら → nft ネイティブ

iptables 構文は翻訳シム頼り。新しく覚えるなら、EL の本命である nft の文法を学ぶ方が将来性がある。

そして繰り返しになりますが、firewalld と手書きルールの混在だけは避ける。これさえ守れば、あとは好みで選んで問題ありません。

こう整理した上で、自分はというと——正直、ルールの一覧をぱっと見渡せる安心感がやっぱり捨てがたいんですよね。新規構築の開け閉めは素直に firewalld を使うものの、fail2ban まわりで「いまどの IP を弾いているか」を追うときは、つい iptables -Snft list ruleset で実体を覗きに行く癖が抜けません。古い好みと言われればそれまでですが、見やすさという理由がある以上、この選び方は自分なりに筋が通っていると思っています。同じ理由で iptables 流が手に馴染んでいる人は、無理に firewalld へ寄せなくてもいいんじゃないでしょうか。

まとめ

  • Rocky 9 では firewalld も iptables も下は同じ nftables。対立構造は実は薄い
  • firewalld = サービス単位で楽 / 直接制御 = 可視性が高い、という棲み分け
  • iptables --version(nf_tables) を返すのが「古くない」証拠
  • 迷ったら firewalld、慣れているなら nft。ただし混在は厳禁