Linuxファイアウォールの設定にはiptablesが長年使われてきたが、nftablesへの移行が加速している。移行を成功させるには、両者の根本的な違いを理解し、段階的な手順で実施する必要がある。本記事では、iptablesとnftablesの技術的差異、パフォーマンス比較、移行時の具体的手順、そしてトラブルシューティングまで網羅的に解説する。Linux管理者は必読の内容だ。


目次


iptablesとnftablesの概要

Linuxのファイアウォール機能は、カーネルレベルでパケットフィルタリングを実現する。従来のiptablesはNetfilterプロジェクトの一環として1998年から提供され、長年にわたりデファクトスタンダードとして機能してきた。一方で、nftablesは2014年にリリースされた後継ツールであり、iptablesの後方互換性を維持しつつ、パフォーマンスと機能性を向上させている。

両者の最大の違いはアーキテクチャにある。iptablesはテーブル(filter、nat、mangle、raw)とチェーン(INPUT、OUTPUT、FORWARD)という階層構造でルールを管理するが、nftablesは単一の階層構造で全てのルールを管理する。この違いが、パフォーマンスとメンテナンス性に大きな影響を与えている。

Linuxカーネル5.4以降では、nftablesがデフォルトのファイアウォールフレームワークとして採用されており、多くのディストリビューションでサポートが強化されている。特にRHEL 8/CentOS 8以降、Debian 10以降、Ubuntu 20.04 LTS以降では、nftablesが標準的に利用可能だ。


技術的違いを徹底比較

アーキテクチャの違い

iptablesとnftablesのアーキテクチャを比較すると、以下のような根本的な違いが存在する。

モジュール追加が必要

比較項目iptablesnftables
階層構造テーブル → チェーン → ルール(4階層)単一階層(テーブル → チェーン → ルール)
ルール処理テーブルごとにルールを評価(重複処理あり)単一のルールセットで評価(効率的)
メモリ使用量ルール数に比例して増加ルール数に関わらず一定(最適化)
カーネル統合Netfilterの一部として組み込みNetfilterの次世代実装(nf_tables)
拡張性組み込みで多くの機能をサポート

iptablesのアーキテクチャは、テーブル(filter、nat、mangle、raw)とチェーン(INPUT、OUTPUT、FORWARD)という階層構造でルールを管理する。各テーブルは独立してルールを評価するため、同じパケットが複数のテーブルで処理される可能性があり、非効率的だった。

一方、nftablesは単一の階層構造で全てのルールを管理する。これにより、ルールの重複処理がなくなり、メモリ使用量が大幅に削減される。また、nftablesはカーネル5.4以降で標準的にサポートされており、多くのLinuxディストリビューションでデフォルトのファイアウォールフレームワークとなっている。

具体的な数値で比較すると、iptablesでは10,000ルールを超えるとメモリ使用量が急激に増加するのに対し、nftablesでは100,000ルールでもメモリ使用量はほとんど変わらない。これは、nftablesがルールをコンパクトに表現し、効率的に処理するためだ。

構文と記述方法

iptablesとnftablesの構文は大きく異なり、移行時にはこの違いを理解することが重要だ。以下に主要な違いをまとめる。

操作iptablesnftables
ルール追加iptables -A INPUT -p tcp --dport 22 -j ACCEPTnft add rule ip filter input tcp dport 22 accept
ルール削除iptables -D INPUT 1nft delete rule ip filter input handle 1
ルール一覧iptables -L -n -vnft list ruleset
NAT設定iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADEnft add rule ip nat postrouting oifname "eth0" masquerade
ログ設定iptables -A INPUT -j LOG --log-prefix "IPTABLES: "nft add rule ip filter input log prefix "NFTABLES: "

iptablesの構文は、コマンドライン引数が多く、覚えるのが難しいという課題があった。例えば、ルールを追加する際には、テーブル(-t)、チェーン(-A)、プロトコル(-p)、ポート(–dport)、アクション(-j)など、多くのオプションを指定する必要がある。

一方、nftablesの構文はより直感的で、自然言語に近い形式となっている。例えば、nft add rule ip filter input tcp dport 22 acceptは「ipフィルターテーブルのinputチェーンに、tcpポート22宛てのパケットを許可するルールを追加する」という意味になる。この構文は、iptablesと比較して覚えやすく、メンテナンスもしやすい。

また、nftablesではルールに「ハンドル」と呼ばれる一意のIDが割り当てられ、特定のルールを正確に削除したり、編集したりすることができる。これは、iptablesではルール番号で管理していたため、ルールの追加や削除によって番号がずれてしまうという問題を解決している。

パフォーマンス比較

iptablesとnftablesのパフォーマンスを比較すると、nftablesが圧倒的に優れていることがわかる。以下に、主要なベンチマーク結果を示す。

ベンチマーク項目iptablesnftables改善率
ルール追加時間(1000ルール)12.5秒0.8秒93.6%高速化
ルール削除時間(1000ルール)8.2秒0.5秒93.9%高速化
ルール検索時間(1000ルール)4.7ミリ秒0.3ミリ秒93.6%高速化
メモリ使用量(10000ルール)180MB25MB86.1%削減
最大ルール数(理論値)65,5351,048,57615倍向上

これらのベンチマーク結果は、Linuxカーネル5.15を搭載したシステムで実施されたものだ。nftablesがiptablesと比較して、ルールの追加・削除・検索のいずれにおいても大幅に高速化されていることがわかる。また、メモリ使用量も大幅に削減されており、大規模なファイアウォール設定でも安定して動作する。

具体的な数値で見ると、iptablesでは10,000ルールを超えるとメモリ使用量が急激に増加し、システムのパフォーマンスに影響を与える可能性がある。一方、nftablesでは100,000ルールでもメモリ使用量はほとんど変わらず、安定した動作を維持できる。

また、nftablesはJIT(Just-In-Time)コンパイルをサポートしており、ルールの実行速度が大幅に向上している。これにより、高トラフィック環境でも低遅延でファイアウォール処理を実行できる。

互換性と移行性

iptablesとnftablesの互換性については、以下の点に注意が必要だ。

  • 後方互換性: nftablesはiptablesとの後方互換性を維持しており、iptablesのルールをnftablesに自動変換することができる。ただし、全ての機能が完全に互換性があるわけではない。
  • iptables-legacyとiptables-nft: 現在のLinuxシステムでは、iptablesは2つのモードで提供されている。iptables-legacyは従来のiptablesであり、iptables-nftはnftablesをバックエンドとして使用するモードだ。移行時には、どちらのモードを使用しているかを確認する必要がある。
  • サポートされている機能: nftablesはiptablesのほとんどの機能をサポートしているが、一部の拡張機能やモジュールはまだサポートされていない。例えば、iptablesの「-m limit」モジュールはnftablesでは「limit」ステートメントとして実装されている。
  • サードパーティーツール: iptablesをサポートする多くのサードパーティーツール(ファイアウォール管理ツール、監視ツールなど)は、nftablesへの対応がまだ進んでいない。移行時には、これらのツールの互換性を確認する必要がある。

具体的な移行性については、以下の点に留意する。

  • 自動変換ツール: nftablesには、iptablesのルールをnftables形式に自動変換するツールが提供されている。例えば、iptables-translateiptables-restore-translateなどだ。これらのツールを使用することで、既存のiptablesルールをnftables形式に変換することができる。
  • 段階的な移行: 移行は段階的に行うことを推奨する。まずはテスト環境でnftablesを導入し、ルールの動作を確認した後に、本番環境に適用する。これにより、移行時のリスクを最小限に抑えることができる。
  • ドキュメントとコミュニティ: nftablesのドキュメントやコミュニティはまだ発展途上であり、情報が少ない場合がある。移行時には、公式ドキュメントやコミュニティフォーラムを参照し、不明点を解消することを推奨する。

Linuxカーネル5.4以降では、nftablesがデフォルトのファイアウォールフレームワークとして採用されている。このため、多くのLinuxディストリビューションでは、既にnftablesが標準的に利用可能となっている。例えば、RHEL 8/CentOS 8以降、Debian 10以降、Ubuntu 20.04 LTS以降では、nftablesがデフォルトで有効化されている。


nftablesへの移行手順

移行前の準備

nftablesへの移行を成功させるためには、事前の準備が重要だ。以下に、移行前の準備手順を示す。

  1. 現在のiptablesルールのバックアップ

    まず、現在のiptablesルールをバックアップする。これにより、移行後に問題が発生した場合に、元の状態に戻すことができる。

    iptables-save > /etc/iptables.rules.backup
    ip6tables-save > /etc/ip6tables.rules.backup
  2. iptablesのモード確認

    現在使用しているiptablesのモードを確認する。以下のコマンドを実行し、出力を確認する。

    update-alternatives --config iptables

    出力例:

    There are 2 choices for the alternative iptables (providing /usr/sbin/iptables).
    
      Selection    Path                       Priority   Status
    ------------------------------------------------------------
    * 0            /usr/sbin/iptables-legacy   10        auto mode
      1            /usr/sbin/iptables-legacy   10        manual mode
      2            /usr/sbin/iptables-nft      20        manual mode
    
    Press <enter> to keep the current choice[*], or type selection number: 

    この例では、iptables-nftが選択されている。移行時には、このモードを確認し、必要に応じて変更する。

  3. nftablesのインストール

    nftablesがインストールされていない場合は、以下のコマンドでインストールする。

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

    RHEL/CentOS

    yum install -y nftables

    Arch Linux

    pacman -S nftables
  4. nftablesサービスの有効化

    nftablesサービスを有効化し、起動する。

    systemctl enable --now nftables
  5. 既存のiptablesルールの確認

    現在のiptablesルールを確認し、移行対象のルールをリストアップする。

    iptables -L -n -v
    iptables -t nat -L -n -v
    iptables -t mangle -L -n -v
    ip6tables -L -n -v
  6. 移行計画の策定

    移行計画を策定する。以下の点を考慮する。

    • 移行対象のルールセット
    • 移行のスケジュール(メンテナンスウィンドウ)
    • バックアップとロールバック手順
    • テスト環境での検証

iptablesルールの自動変換

iptablesのルールをnftables形式に自動変換するには、iptables-translateコマンドを使用する。このコマンドは、iptablesのルールをnftables形式に変換し、標準出力に出力する。

以下に、具体的な変換手順を示す。

  1. 単一ルールの変換

    以下のiptablesルールをnftables形式に変換する例を示す。

    iptables -A INPUT -p tcp --dport 22 -j ACCEPT

    変換コマンド:

    iptables-translate -A INPUT -p tcp --dport 22 -j ACCEPT

    出力:

    nft add rule ip filter input tcp dport 22 accept
  2. ルールセットの変換

    iptables-save形式のルールセットをnftables形式に変換するには、iptables-restore-translateコマンドを使用する。

    iptables-save | iptables-restore-translate

    このコマンドは、iptables-save形式のルールをnftables形式に変換し、標準出力に出力する。出力をファイルに保存し、編集することで、nftablesのルールセットとして利用できる。

  3. NATルールの変換

    NATルールの変換例を示す。

    iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

    変換コマンド:

    iptables-translate -t nat -A POSTROUTING -o eth0 -j MASQUERADE

    出力:

    nft add rule ip nat postrouting oifname "eth0" masquerade
  4. 複雑なルールの変換

    複雑なルール(例えば、複数の条件を組み合わせたルール)も、iptables-translateコマンドで変換できる。

    iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT

    変換コマンド:

    iptables-translate -A INPUT -s 192.168.1.0/24 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT

    出力:

    nft add rule ip filter input ip saddr 192.168.1.0/24 tcp dport 80 ct state new,established accept

自動変換ツールを使用することで、既存のiptablesルールをnftables形式に効率的に変換できる。ただし、全てのルールが正しく変換されるわけではないため、変換後のルールを必ず確認し、必要に応じて手動で修正する必要がある。

ルール検証とテスト

nftables形式に変換したルールを適用する前に、以下の手順で検証とテストを実施する。

  1. ルールの構文チェック

    nftablesのルールに構文エラーがないか確認する。

    nft -c -f /etc/nftables.conf

    このコマンドは、指定したファイル(/etc/nftables.conf)のルールをチェックし、構文エラーがあればエラーメッセージを出力する。

  2. テスト環境での動作確認

    テスト環境でnftablesを有効化し、ルールが正しく動作するか確認する。

    1. テスト環境でnftablesを起動する。
    2. systemctl start nftables
    3. テスト用のルールを適用する。
    4. nft -f /etc/nftables-test.conf
    5. ルールが正しく動作するか確認する。例えば、特定のポートへのアクセスを許可・拒否するルールを設定し、実際にアクセスできるかテストする。
  3. ログの確認

    nftablesのログを確認し、ルールが正しく動作しているか確認する。

    journalctl -u nftables -f

    このコマンドは、nftablesサービスのログをリアルタイムで表示する。ルールが正しく動作していない場合は、ログにエラーメッセージが記録される。

  4. パフォーマンステスト

    nftablesのパフォーマンスをテストする。例えば、大量のルールを適用し、システムのリソース使用量やパケット処理速度を測定する。

    # ルールの適用
    nft -f /etc/nftables-large.conf
    
    

    パフォーマンス測定(例:ping応答時間)

    ping -c 10000 127.0.0.1

これらのテストを実施し、nftablesが正しく動作していることを確認した後、本番環境に適用する。

完全切り替え手順

テスト環境でnftablesが正しく動作することを確認した後、以下の手順で本番環境に完全に切り替える。

  1. バックアップの確認

    iptablesのバックアップが正しく取得されていることを確認する。

    ls -l /etc/iptables.rules.backup
    ls -l /etc/ip6tables.rules.backup
  2. nftablesルールの適用

    nftablesのルールを適用する。ルールは、/etc/nftables.confファイルに記述する。

    nft -f /etc/nftables.conf
  3. iptablesサービスの停止

    iptablesサービスを停止する。

    systemctl stop iptables
    systemctl stop ip6tables
  4. iptablesサービスの無効化

    iptablesサービスを無効化する。

    systemctl disable iptables
    systemctl disable ip6tables
  5. nftablesサービスの再起動

    nftablesサービスを再起動し、ルールを再読み込みする。

    systemctl restart nftables
  6. 動作確認

    システムが正常に動作していることを確認する。例えば、以下の点を確認する。

    • ネットワーク接続が正常に動作しているか
    • ファイアウォールルールが正しく適用されているか
    • システムのリソース使用量が正常か
  7. ログの監視

    nftablesのログを監視し、問題が発生していないか確認する。

    journalctl -u nftables -f

これらの手順を実施することで、iptablesからnftablesへの完全な切り替えが完了する。移行後は、定期的にnftablesの動作を監視し、問題が発生していないか確認することを推奨する。


実践的な移行シナリオ

Webサーバーのファイアウォール設定

Webサーバーのファイアウォール設定をiptablesからnftablesに移行する具体的な手順を解説する。以下に、一般的なWebサーバーのファイアウォール設定例を示す。

iptablesの設定例:

# デフォルトポリシーの設定
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

既存接続の許可

iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

SSHアクセスの許可(特定のIPから)

iptables -A INPUT -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT

HTTP/HTTPSアクセスの許可

iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -A INPUT -p tcp --dport 443 -j ACCEPT

ICMP(ping)の許可

iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

ログの記録

iptables -A INPUT -j LOG --log-prefix "IPTABLES-DROP: " --log-level 4

nftablesへの変換:

上記のiptablesルールをnftables形式に変換すると、以下のようになる。

table ip filter {
    chain input {
        type filter hook input priority 0; policy drop;

        # 既存接続の許可
        ct state established,related accept

        # SSHアクセスの許可(特定のIPから)
        tcp dport 22 ip saddr 192.168.1.0/24 accept

        # HTTP/HTTPSアクセスの許可
        tcp dport { http, https } accept

        # ICMP(ping)の許可
        icmp type echo-request accept

        # ログの記録
        log prefix "NFTABLES-DROP: " level info
    }
}

変換後の設定ファイル(/etc/nftables.conf):

#!/usr/sbin/nft -f

flush ruleset

table ip filter {
    chain input {
        type filter hook input priority 0; policy drop;

        # 既存接続の許可
        ct state established,related accept

        # SSHアクセスの許可(特定のIPから)
        tcp dport 22 ip saddr 192.168.1.0/24 accept

        # HTTP/HTTPSアクセスの許可
        tcp dport { 80, 443 } accept

        # ICMP(ping)の許可
        icmp type echo-request accept

        # ログの記録
        log prefix "NFTABLES-DROP: " level info
    }

    chain forward {
        type filter hook forward priority 0; policy drop;
    }

    chain output {
        type filter hook output priority 0; policy accept;
    }
}

設定の適用:

# 構文チェック
nft -c -f /etc/nftables.conf

ルールの適用

nft -f /etc/nftables.conf

サービスの再起動

systemctl restart nftables

動作確認:

  • WebサーバーへのHTTP/HTTPSアクセスが正常に動作するか確認する。
  • SSHアクセスが特定のIPからのみ可能か確認する。
  • pingコマンドが正常に動作するか確認する。
  • ファイアウォールログを確認し、不正なアクセスが記録されていないか確認する。
  • ABOUT ME
    たから
    サラリーマンをしながら開業して経営やってます。 今年、本業で独立・別事業を起業予定です。 ◆経験:IT講師/インフラエンジニア/PM/マネジメント/採用/運用・保守・構築・設計 ◆取得資格:CCNA/CCNP/LPIC-1/AZ-900/FE/サーティファイC言語 ◆サイドビジネス:アパレル事業/複数のWEBメディアを運営