iptablesからnftablesへの移行:なぜSysAdminにとって必須のステップなのか?

Security tutorial - IT technology blog
Security tutorial - IT technology blog

長年愛用したiptablesとの決別を決めた理由

かつて私は、2,000以上のiptablesルールを持つサーバークラスターを管理していました。設定を更新するたびに、システムはリスト全体を再読み込みする必要があり、ボトルネックが発生してCPUリソースを大幅に消費していました。また、iptables (IPv4) と ip6tables (IPv6) の間で設定がバラバラになる「あちらを立てればこちらが立たず」の状態は、管理をまさに悪夢に変えていました。

Debian 11やUbuntu 22.04以降, 私は完全にnftablesに移行しました。これは単に新しいテクノロジーを追いかけているわけではありません。nftablesは、すべてのプロトコルを単一の管理フレームワークに統合することで、断片化の問題を根本的に解決します。カーネル内で動作する仮想マシン(VM)メカニズムのおかげで、パケット処理速度は前身のiptablesよりも大幅に向上しています。

実務における違い:iptables vs nftables

もし移行すべきか迷っているなら、以下の数値と構造の違いを確認してみてください:

  • 検索パフォーマンス: iptablesはルールを逐次的に(O(n))スキャンします。もし一致するルールが1,000行のリストの最後にある場合、パケットの待機時間は長くなります。対してnftablesは、ディクショナリ(dictionaries)やセット(sets)を使用するため、O(1)またはO(log n)という極めて高速な計算量で検索が可能です。
  • 構文: -A INPUT -p tcp --dport 22 -j ACCEPT のような煩雑な記述の代わりに、nftablesは明確な階層構造を採用しています。これはNginxやJuniperの設定ファイルの書き方に非常に似ています。
  • 集中管理: IPv4とIPv6のために2〜3の異なるツールを使い分ける必要はもうありません。単一の inet テーブルですべてを処理できます。
  • アトミック性(Atomicity): 何百もの変更を一度に適用できます。システムは「すべて適用される」か「何も変わらない」かのどちらかを保証するため、更新中に一時的にセキュリティが脆弱になるリスクを完全に排除します。

安全な移行ロードマップ

稼働中の本番サーバーでいきなり作り直すのはやめましょう。私の推奨するプロセスは、以下の4つのステップに集約されます:

  1. 自動ツールを使用して、iptablesのロジックをnftablesに変換する。
  2. 設定ファイルを最適化する(ポートの統合、セットの使用)。
  3. Lab環境またはステージング環境で入念にテストする。
  4. サービスを切り替え、ログを監視する。

実践的なnftables導入ガイド

1. 簡単なインストール

ほとんどのモダンなディストリビューションにはnftablesが組み込まれています。もしサーバーに入っていない場合は、以下のコマンドでインストールしてください:

# Debian/Ubuntu
sudo apt update && sudo apt install nftables -y

# RHEL/CentOS/AlmaLinux
sudo dnf install nftables -y

sudo nft list ruleset と入力して確認します。何も表示されない場合、サーバーは完全に「開放」されているか、まだ古いファイアウォールを使用しています。

2. ルールを素早く変換するコツ

iptables-translate ツールは、iptablesに慣れ親しんだ人にとっての救世主です。例えば、ポート80を開放するルールを変換するには:

iptables-translate -A INPUT -p tcp --dport 80 -j ACCEPT
# 結果: nft add rule ip filter INPUT tcp dport 80 counter accept

3. 標準ルールセット(テンプレート)の構築

個別のコマンドを入力するのではなく、/etc/nftables.conf ファイルに直接記述することをお勧めします。以下は、モダンなWebサーバーで私がよく使用する設定です:

#!/usr/sbin/nft -f

flush ruleset

table inet server_firewall {
    chain inbound {
        type filter hook input priority 0; policy drop;

        # 既存の接続を維持(SSHから切断されないために非常に重要)
        ct state established,related accept

        # ループバックを許可
        iif "lo" accept

        # Pingを許可(フラッド防止のため10パケット/秒に制限)
        ip protocol icmp limit rate 10/second accept
        ip6 nexthdr icmpv6 accept

        # ポートの一括管理
        tcp dport 22 accept
        tcp dport { 80, 443, 8080 } accept

        # 不審なアクセスをログに記録してドロップ
        limit rate 5/minute log prefix "FIREWALL_DROP: "
    }
}

この設定の優れた点:

  • flush ruleset: 読み込むたびにルールセットをクリアし、古いルールが重複しないようにします。
  • tcp dport { 80, 443 }: これこそがnftablesの強みです。複数のポートを単一のルールにまとめることで、1行ずつ分けるよりもカーネルの処理速度が向上します。
  • ct state established,related: このルールにより、ファイアウォールをリロードしても実行中の接続が途切れることはありません。

4. 有効化とテスト

新しい設定を適用するには、以下を実行します:

sudo nft -f /etc/nftables.conf

構文エラーがなければ、起動時にファイアウォールが自動実行されるように設定します:

sudo systemctl enable --now nftables

教訓:自分自身を締め出さないこと

最もよくある失敗は、SSHポート(22)を許可する前に drop ルールを適用してしまうことです。私もかつて、一瞬の不注意でプロバイダーのKVMコンソールに泣きつく羽目になったことがあります。

小技: 新しい設定を試す前に、5分後にファイアウォールを自動停止するコマンドを仕込んでおきましょう:

echo "systemctl stop nftables" | at now + 5 minutes

万が一SSHをブロックしてしまっても、5分待てばシステムが自動的に開放してくれます。問題がなければ、atrm を使ってそのコマンドを削除してください。

まとめ

nftablesへの移行は、構文に慣れるために少し時間がかかるかもしれません。しかし、長期的にはサーバーの動作がスムーズになり、設定ファイルが整理され、セキュリティが向上するという大きなメリットがあります。新しいサーバーを構築するなら、最初から nftables を標準として選ぶことを強くお勧めします。

Share: