CentOS Stream 9 で nftables を使いこなす:iptables からの移行でファイアウォール性能を最適化

CentOS tutorial - IT technology blog
CentOS tutorial - IT technology blog

もし iptables -L -n コマンドがこの 10 年間、脊髄反射のように身についているなら、CentOS Stream 9 へのアップグレードは大きな転換点となるでしょう。このバージョンから、nftables が長年使われてきた iptables に代わり、デフォルトのファイアウォール管理ツールとして正式に採用されました。

この記事では、CentOS 7 から RHEL 9 系へシステムを移行した際の実体験に基づき、nftables の使い方をまとめました。nftables は決して難しくありません。むしろ、従来の方法よりも論理的でスッキリしていることに気づくはずです。

なぜ今すぐ iptables を卒業すべきなのか?

旧来のサーバークラスターを管理する上での最大の悩みは、iptables (IPv4)、ip6tables (IPv6)、さらに arptablesebtables を同時に管理しなければならないことでした。これらは目的が似ているにもかかわらず、それぞれ独自の構文を持っていました。

nftables は、統合されたフレームワークによってこの断片化を根本的に解決します。主な利点は以下の通りです:

  • デュアルスタック対応: inet ファミリーを通じて、IPv4 と IPv6 の両方を単一のコマンドで処理できます。
  • 圧倒的なスピード: 各行を順次スキャンする (O(n)) 代わりに、nftables は Sets データ構造を使用して定数時間 (O(1)) で検索を行います。10,000 個のブロック IP リストがあっても、CPU 負荷への影響はほとんどありません。
  • 柔軟な構造: テーブルやチェインを必要に応じて自分で定義でき、固定されたデフォルトテーブルに縛られることがありません。

コアアーキテクチャ:Table、Chain、Rule

コマンドを打ち始める前に、nftables の階層構造をイメージしてみましょう。iptables とは異なり、nftables は「白紙の状態」から始まります:

  1. Tables (テーブル): チェインを格納する最上位のコンテナです。作成時に「ファミリー」(ip、ip6、inet など)を選択する必要があります。
  2. Chains (チェイン): ルールを格納する場所です。チェインは kernel の input、output、forward といった「フック」に関連付けられます。
  3. Rules (ルール): パケットの運命(accept、drop、reject)を決定するコマンドラインです。

CentOS Stream 9 での実装

通常、CentOS Stream 9 には nftables がプリインストールされています。Minimal 版を使用している場合は、dnf でインストールしてください。

# サービスのインストールと有効化
sudo dnf install nftables -y
sudo systemctl enable --now nftables

注意: 設定の競合を避けるため、firewalld は停止してください。2 つのファイアウォールサービスを同時に実行すると、デバッグが困難なネットワークエラーの原因になります。

1. 設定の初期化

不要なルールが残らないよう、既存の設定をすべて消去します:

sudo nft flush ruleset

2. テーブルとベースチェインの作成

inet ファミリーを使用する my_filter テーブルを作成します。その後、受信 (input)、送信 (output)、転送 (forward) のための基本的なチェインを設定します。

# テーブルの作成
sudo nft add table inet my_filter

# INPUT チェインの作成(セキュリティのためデフォルトですべて拒否)
sudo nft add chain inet my_filter input { type filter hook input priority 0 \; policy drop \; }

# FORWARD と OUTPUT チェインの作成
sudo nft add chain inet my_filter forward { type filter hook forward priority 0 \; policy drop \; }
sudo nft add chain inet my_filter output { type filter hook output priority 0 \; policy accept \; }

3. 必須ルールの設定 (SSH, Loopback)

この手順を忘れないでください。忘れると、上記の policy drop により即座にサーバーからロックアウトされます。

# ローカルループバックを許可
sudo nft add rule inet my_filter input iif lo accept

# 確立済みの接続を維持 (established/related)
sudo nft add rule inet my_filter input ct state established,related accept

# SSH ポート (22) を開放
sudo nft add rule inet my_filter input tcp dport 22 accept

高度な機能:Sets と Verdict Maps

これらは、パフォーマンスとコードの美しさの両面で nftables が iptables を凌駕する秘密兵器です。

Sets による IP の一括ブロック

100 個の IP をブロックするために 100 個のルールを作る代わりに、それらを 1 つの Set にまとめることができます。

# ブラックリストの作成
sudo nft add set inet my_filter blackhole { type ipv4_addr \; }

# 違反 IP の追加
sudo nft add element inet my_filter blackhole { 192.168.1.100, 10.0.0.5, 172.16.0.10 }

# リスト全体をブロックする単一のルール
sudo nft insert rule inet my_filter input ip saddr @blackhole drop

Verdict Maps によるトラフィックの振り分け

Verdict Maps を使用すると、1 行のコマンドで複数の条件を処理できます。例えば、ポート 80 と 443 は許可し、ポート 23 (Telnet) は即座に破棄するといった具合です。

sudo nft add rule inet my_filter input tcp dport vmap { 80 : accept, 443 : accept, 23 : drop }

この構文により、設定ファイルが大幅に短く、読みやすくなります。

設定の永続化

これまで入力した nft コマンドはすべて RAM 上にあります。サーバーを再起動すると設定は消えてしまいます。起動時に自動的に読み込まれるよう、システムファイルに保存しましょう。

# 設定をシステム定義ファイルに書き出す
sudo nft list ruleset | sudo tee /etc/sysconfig/nftables.conf

# 再起動して確認
sudo systemctl restart nftables

私からのアドバイス:大きな変更を加える前には、必ず nftables.conf のバックアップを取ってください。万が一設定ミスでネットワークが切断されても、データセンターの技術者に依頼して数秒で旧バージョンを復元できます。

監視とデバッグ

実行中のルールを識別子 (handle) 付きで確認するには、以下を使用します:

sudo nft list ruleset -a

handle は、長い内容を再入力せずに特定のルールを削除したい場合に非常に便利です:

# input チェイン内の handle 番号 5 のルールを削除
sudo nft delete rule inet my_filter input handle 5

まとめ

CentOS Stream 9 ででの nftables への移行は、最初は構文に戸惑うかもしれません。しかし、Table や Set という考え方をマスターすれば、強力で洗練された、高パフォーマンスなファイアウォールシステムを手に入れることができます。

もしあなたの組織が RHEL 9 や同等のディストリビューションへのアップグレードを計画しているなら、ぜひ積極的に nftables を採用してください。これは単なる技術的な変更ではなく、現代の Linux システム管理を最適化するための新しい標準なのです。

Share: