本ページの位置づけ
姉妹ページ「Firewalldとnftablesの構造」がアーキテクチャの全体像を解説するのに対し、本ページは日々の運用実務(ゾーン設計・変更管理・トラブルシューティング)と、カーネル関数レベルまで踏み込んだより詳細な内部構造を扱います。第4章の例は、現行のネットワーク構成(Caddy=DMZセグメント 172.16.1.18、Headscale稼働ホスト=SERVERセグメントのAlmaLinux 9 192.168.2.3)に合わせて更新しています。
目次
第1部:構築・運用実務編
- 第1章:設計思想とホスト境界防御
- 第2章:ゾーン設計基準と優先順位
- 第3章:設定ファイル構造と永続化
- 第4章:リッチルールによるマイクロセグメンテーション
- 第5章:NAT・マスカレード連携設計
- 第6章:コンテナ(Podman/Docker)ネットワーク統合
- 第7章:変更管理・バックアップ・性能監視
- 第8章:Firewalld × SELinux 多層防御
- 第9章:実践トラブルシューティング
第2部:Linuxカーネル内部構造編
第1部:Firewalld 構築・運用実務編
第1章:Firewalldの設計思想とホスト境界防御の全体像
1-1. 設計の基本概念:Firewalldはパケットを処理しない「設定管理ツール」
ホストOSのネットワーク防御を理解する上で、最初に明確に区別すべきなのは、「ポリシーを管理するユーザー空間ツール」と「実際にカーネル空間でパケットを判定するエンジン」の違いです。
Firewalld自体はパケットを処理しません。ユーザーが管理しやすい「ゾーン」や「サービス」という概念をXMLファイルで保存し、カーネルの判定エンジン(nftables)に対してNetlinkメッセージを介して設定を送り届ける、ユーザー空間の「ポリシー管理フロントエンド(設定ツール)」です。
[ ユーザー操作 ] : firewall-cmd --zone=public --add-service=https
│
▼ (D-Bus通信)
[ Firewalld デーモン ] : XMLファイルの管理、論理構成の組み立て
│
▼ (libnftables API 呼び出し) : 構成要素を「Netlinkトランザクション」へ変換
│ ※ 例:「httpsサービスを追加」という指示を
│ 「tcp dport 443 accept」というバイトコード命令に変換する
│
▼ (Netlinkソケット経由:AF_NETLINK)
[ nftables (VM) ] : カーネル空間でバイトコード命令をレジスタ上で評価
│
▼ (フックバインド)
[ Netfilter ] : カーネル最深部における物理パケットの割り込み・処理
- Firewalld = ポリシー管理:構成定義の管理、XMLファイル(/etc/firewalld/)の永続化、ゾーンやサービスの抽象化。
- nftables = パケット判定エンジン:仮想マシンのバイトコード命令を実行し、レジスタ上で合否を判定。
- Netfilter = カーネルのフック機構:ネットワークスタックの特定フックポイントでパケットを割り込み(Hook)処理。
第2章:ゾーン(Zone)設計基準とインターフェースマッピングの優先順位
Firewalldは、ホストに届いたパケットを「ゾーン(Zone)」という論理グループで定義し、仕分けます。
2-1. パケット流入時の所属ゾーン判定優先順位
ホストに到達したパケットは、以下の順番で評価され、最初にマッチしたゾーンのポリシーが適用されます。
- 優先順位1:送信元IP(Source)によるバインド — パケットの送信元IPアドレスが、特定のゾーン(例:trustedゾーン等)に定義されているか?
- 優先順位2:インターフェース(Interface)によるバインド — パケットが流入した物理/仮想NIC(例:ens160, wg0等)が特定のゾーンにバインドされているか?
- 優先順位3:システムデフォルトゾーン(Default Zone) — 上記1、2のバインドがない場合、システムに設定された「デフォルトゾーン(初期状態はpublic)」を強制適用
2-2. 標準提供されている9つのゾーンの設計基準
| ゾーン名 | デフォルトのターゲット | 想定されるシステム設計・適用領域 |
|---|---|---|
drop | DROP | すべての受信パケットを無条件で破棄。応答パケット(ICMP等)も返さない。攻撃対象外のポートを完全に隠蔽。 |
block | REJECT | すべての受信接続を拒否。送信元にはポートが閉じていることを示す拒否パケット(ICMP Destination Unreachable)を返す。 |
public | default | 外部の信頼できないインターネットセグメント向け。明示的に許可したサービス(sshやhttpsなど)のみを受理。 |
external | default | ルーターやゲートウェイとして使用する外部NIC向け。自動的にIPv4のマスカレード(NAT)機能が有効になる。 |
dmz | default | 公開Webサーバーなど、内部ネットワークから隔離されたセグメントのホスト向け。アクセス許可を最小限に設定。 |
work | default | 業務セグメントなど、ある程度信頼できるネットワーク向け。一般的なオフィス環境で使用されるサービスの許可を想定。 |
home | default | 家庭内ネットワーク向け。隣接する他のPCを信頼し、共有しやすくするための緩やかなサービス許可設定。 |
internal | default | 内部プライベートネットワーク向け。信頼されたローカルホスト間での自由な通信をある程度許可する。 |
trusted | ACCEPT | 完全に信頼されたセグメント向け。このゾーンにバインドされた通信は、ファイアウォールを完全にスルーしてすべて許可される。 |
第3章:Firewalld設定ファイル構造(XML定義)と永続化(Runtime vs Permanent)
3-1. 設定ファイル群のディレクトリ構成
/etc/firewalld/ → 管理者によるカスタム設定ディレクトリ(優先度:高)
├── firewalld.conf → ファイアウォール全体の設定ファイル
├── ipsets/ → 動的IPリスト(Fail2ban等と連携するメモリリスト定義)
├── zones/ → カスタムされたゾーンのXML定義(例:public.xml)
│ └── public.xml
├── services/ → カスタム定義されたサービス定義(独自定義ポート等)
└── policies/ → ゾーン間のフォワーディング等を定義するカスタムポリシーファイル
/usr/lib/firewalld/ → OSインストール時に提供されるシステムデフォルト(優先度:低、直接編集厳禁)
├── zones/ → システム標準提供のゾーン初期定義(dmz.xml, public.xmlなど)
└── services/ → 標準登録済みの既知のサービス定義群(ssh.xml, http.xmlなど)
3-2. 永続化設計(Runtime と Permanent の挙動原理)
Firewalld最大の特徴は、メモリ上で即座にパケット判定を変える「Runtime設定」と、ディスク上のXMLに保存する「Permanent設定」の完全な分離です。
[ ユーザーのコマンド実行 ]
│
├─ 1. 「--permanent」なしで実行 : firewall-cmd --add-port=8080/tcp
│ │
│ ▼
│ [ Runtime(動作中のメモリ空間)に即座に反映 ]
│ ※カーネル上のnftablesルールを書き換えるが、サービス再起動やOS再起動時に設定は消える。
│
└─ 2. 「--permanent」付きで実行 : firewall-cmd --add-port=8080/tcp --permanent
│
▼
[ Permanent(/etc/firewalld/ 以下のXMLファイル)に書き込み ]
※ディスクに保存するだけで、動作中のメモリ空間(カーネル)にはまだ反映されない。
│
▼ ユーザーが [ firewall-cmd --reload ] を実行
[ XMLファイルを解析し、メモリ上のRuntime領域に一括で再適用 ]
3-2-1. 実務上のベストプラクティスコマンド
動作中の確認済みテスト設定を、安全に永続設定として固定化する手順です。
# メモリ上の確認済みRuntime設定を、すべて永続ファイル(XML)に同期して書き出す
sudo firewall-cmd --runtime-to-permanent
# ディスク上の永続設定ファイルを再読み込みし、接続を切断せずに現在のファイアウォールルールを更新
sudo firewall-cmd --reload
第4章:リッチルール(Rich Rules)によるマイクロセグメンテーション設計
ゼロトラストアーキテクチャの基本設計である「マイクロセグメンテーション(Micro-segmentation)」を、Firewalldのゾーンおよびリッチルールを用いてホスト単位で適用します。
4-1. ゾーン境界を用いたマイクロセグメント化
同じネットワークセグメント内に存在する複数のサーバーやコンテナであっても、無条件の通信(Any-to-Any)を排し、個別に設定した信頼ルールに基づいて通信を制御します。
現行構成に合わせた例
元資料の例(Caddy・Headscaleが同一の192.168.1.0/24セグメント上)は、現在の実際の構成(Caddy=DMZセグメント 172.16.1.18、Headscale稼働ホスト=SERVERセグメントのAlmaLinux 9 192.168.2.3)とは異なるため、下記は現行構成に沿って書き換えています。
[ 192.168.2.0/24 SERVERセグメント(内部管理基盤) ]
│
├─► [ 172.16.1.18: Caddy(DMZセグメント・リバースプロキシ) ]
│ │ HTTPS/8080リクエスト転送(FortiGateのDMZ-SERVER間 最小例外許可経由)
│ ▼
├─► [ 192.168.2.3: AlmaLinux 9(Headscale稼働ホスト) ]
│ └─► Firewalldによる受信判定 (Zone: internal)
│ ├─► Source IP = 172.16.1.18 AND Port = 8080 → 【 許可 】
│ └─► Source IP = その他すべてのホスト(同一セグメント内含む) → 【 拒否 】
│
└─► [ 192.168.2.50: 同一セグメント内の侵害された端末(例) ]
└─► ポート8080をスキャン → Firewalldリッチルールによって即座に【 ドロップ 】
リッチルールを使用して、「信頼する通信元のIP(Caddy)」と「許可するポート(8080)」をピンポイントでバインドすることで、同じセグメント内で横方向の攻撃(ラテラルムーブメント)が発生した場合の拡散を自動的に封じ込めます。
第5章:NAT・マスカレード連携設計
Firewalldは、ゲートウェイサーバーやルーター構成の構築において必要となるアドレス変換(NAT)処理を、ゾーンの構成オプションおよびポリシー定義によって自動化します。
5-1. NAT処理(SNATとDNAT)のフローとタイミング
[ 外部からのパケット流入 ]
│
▼
┌──────────────────────┐
│ PREROUTING Hook (宛先IP変換:DNAT) │ → 外部からDMZコンテナ等へポート転送する際に実行
└───────┬──────────────┘
│
├─► [ ローカルプロセスへのINPUT ]
│
▼ [ フォワーディング:FORWARD ]
┌───────────────────────┐
│ POSTROUTING Hook (送信元IP変換:SNAT) │ → ホスト外へ出ていくパケットの送信元IPを書き換え
└───────────────────────┘
マスカレード(Masquerade)の適用
マスカレードは動的な送信元NAT(SNAT)の一種です。Firewalldでは、特定の外部接続用ネットワークインターフェースが属するゾーン(例:external)においてマスカレードを有効化するだけで、そのホストを経由して外部に発信されるパケットの送信元IPアドレスが自動的に物理NICの外部IPへと書き換えられます。
# 特定のゾーンでマスカレード(SNAT)を有効化
sudo firewall-cmd --zone=external --add-masquerade --permanent
sudo firewall-cmd --reload
第6章:コンテナ時代(Podman / Docker)のネットワーク統合設計
現代のLinux(Rocky Linux 9等)では、コンテナエンジン(PodmanやDocker等)とFirewalldの協調動作は必須の要件です。
6-1. コンテナネットワークとFirewalldのパケットフォワーディング
[ コンテナ (container_t) ] → [ 仮想ブリッジ (podman0 / cni-podman0) ]
│ パケット転送要求
▼
[ Firewalld / FORWARDチェーン ]
├─► 1. マスカレード評価 (外部への通信をSNAT)
└─► 2. ゾーン間のポリシー評価 (コンテナ → 外部)
- コンテナブリッジの検出:Podmanがネットワークを作成すると、ホスト上にはpodmanXなどの仮想ネットワークインターフェースが生成されます。
- FORWARDチェーンによる転送制御:Firewalldはデフォルトでフォワーディングを制御(フィルタリング)します。コンテナが外部インターネットと通信するためには、Firewalld側で「コンテナインターフェースからのトラフィックのフォワーディング」が許可されており、かつ外部NICゾーンでマスカレードが動作している必要があります。
- セキュリティ隔離:同一コンテナネットワーク内のコンテナ間通信は、Firewalldではなくコンテナブリッジ内で処理されます。一方、異なるコンテナネットワーク間やホストローカルネットワークとの通信は、Firewalldのルール制御下に置かれ、厳格なポリシー制限を受けます。
第7章:変更管理、バックアップ、および性能監視実務
本番環境の長期運用において、ファイアウォールシステムの安定稼働を確保し、不慮のトラブルを未然に防ぐための実務リファレンスです。
7-1. バックアップと復元(Backup & Restore)
# /etc/firewalld 以下のポリシーファイルを圧縮して一括退避
sudo tar -cvf /backup/firewalld_backup_$(date +%Y%m%d).tar -C /etc/firewalld .
# 復元手順:ファイルを展開し、firewalldサービスを再起動
sudo tar -xvf /backup/firewalld_backup_YYYYMMDD.tar -C /etc/firewalld/
sudo systemctl restart firewalld
7-2. 変更管理プロセス(Change Management Protocol)
本番環境における安全なルール追加手順の標準運用プロトコルです。
現在の有効な設定状況を完全に把握する
sudo firewall-cmd --get-active-zones
sudo firewall-cmd --zone=public --list-all
永続化せず、メモリ上にのみ一時的に新規追加ルールをテスト適用する
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.50" port port="80" protocol="tcp" accept'
接続テストを実行。疎通確認を行い、正常にパケットが通過するか監視する
sudo nft monitor trace
- 接続テスト成功時 → 永続設定に同期保存:
sudo firewall-cmd --runtime-to-permanent - 通信トラブルや不具合発生時 → メモリ再ロードを実行し、テストルールを一瞬で完全破棄(元の安全な状態にロールバック):
sudo firewall-cmd --reload
7-3. 性能監視とカーネルチューニング
大規模Webサーバーなどでは、同時接続数が急増するとConntrackの追跡テーブルが満杯になり、それ以上の新規パケットをすべてドロップしてしまう状態(Conntrack溢れ)が発生します。
# 現在の conntrack 登録数を確認
sysctl net.netfilter.nf_conntrack_count
# ホストが保持できる conntrack の最大限界数を確認
sysctl net.netfilter.nf_conntrack_max
# [チューニング:限界値の上限開放] conntrack の上限値を 262,144 に拡張設定
sudo sysctl -w net.netfilter.nf_conntrack_max=262144
7-4. 緊急時リカバリ(Emergency Recovery Procedure)
SSH接続ルールを削除してしまい、管理コンソールから締め出された場合の救済フロー
リロード設定ミス等で、SSH(22番ポート)のアクセス許可を塞いでしまい、外部からの接続が完全にタイムアウトしてログインできなくなった場合の緊急対処プロセスです。
- 【コンソール接続の確立】サーバーの物理コンソール(またはハイパーバイザー経由のVNC/シリアルコンソール等)にログイン。物理接続経由(ローカルホスト内)であれば、外部ネットワークのファイアウォール遮断ルールに影響されずにログイン可能です。
- 【緊急通信遮断回避コマンドの実行】ファイアウォールサービスを完全に一時停止させ、すべての通信ポート制限を一時的に全開放します:
sudo systemctl stop firewalld - 【永続設定ポリシーの緊急点検と修正】XMLファイル内のルールを手動で修正:
sudo vi /etc/firewalld/zones/public.xml(XML内で<service name="ssh"/>の定義行が欠落していないか確認・修復) - 【検証および再起動】ファイルを保存後、再度firewalldを起動し、SSH接続が正常に戻ったかを確認します:
sudo systemctl start firewalld
第8章:ホスト内部多層防御:Firewalldと SELinuxの協調設計
ゼロトラストの多層防御を実現するためには、ネットワーク境界を守るFirewalldと、OS内部のリソース保護を受け持つSELinuxが協調して動作する必要があります。侵入経路の詳しい図解は「Firewalldとnftablesの構造」第10章をご参照ください。ここでは要点となる比較マトリクスのみ掲載します。
| 項目 | Firewalld(バックエンド: nftables) | SELinux(LSM) |
|---|---|---|
| 防御レイヤー | ネットワークパケット(L3/L4) | システムコール(カーネル空間) |
| 動作場所 | Netfilter フレームワーク | Linux Security Module (LSM) フック |
| 判断基準 | 送信元/送信先IP、ポート番号、プロトコル、状態(State) | プロセスおよびリソースに付与された「セキュリティコンテキスト(ラベル)」 |
| 防御目的 | ホストへの「到達制御」不要な通信を境界で排除する。 | 到達後の「権限制御」侵入されたことを前提に、被害の横移動を阻止する。 |
| 主なコマンド | firewall-cmd / nft | semanage / restorecon / setsebool |
第9章:実践トラブルシューティング:通信障害時の段階的デバッグフロー
「パケットがどこかで遮断され、通信が確立できない」という問題が発生した際、確認すべき診断パスとコマンド制御フローです。
9-1. 障害切り分けのための通信診断フローチャート
通信が遮断され、接続できない
│
▼
tcpdump -i any port <Port> によるパケット受信状態チェック
│
┌────┴────┐
▼(NICに届いていない) ▼(NICに届いている)
【ホスト外部の障害】 ss -antp | grep <Port> を実行
・ルーターや境界FWでのドロップ │
・DNSの設定不良や経路障害 ┌────┴────┐
▼(Listenしていない) ▼(Listenしている)
【アプリケーション障害】 nft monitor trace を実行
・サービスが未起動 │
・設定ミス、バインド等 ┌────┴────┐
▼(DROPされる) ▼(通過している)
【FWの設定】 【ホストOS内部のアクセス制御】
・Firewalld ・SELinux (AVC)ルール違反
ルール違反 ・OS標準DAC (rwx権限など)
9-2. 各種診断・監視ツールの特徴と活用一覧
| コマンド | 調査対象レイヤー | 具体的なデバッグ・診断方法 |
|---|---|---|
tcpdump -i any | L2/L3/L4 パケット受信 | 「そもそもネットワークカードにパケットが届いているか?」を実機上で一番最初に検証する。 |
ss -antp | L4 ソケット受信待ち | 「アプリケーションが指定ポート(8080等)で正常にListen状態になっているか?」を確認。 |
conntrack -L | カーネル追跡ステート | 現在の通信セッションの状態(SYN_RECV, ESTABLISHED等)や、Conntrackテーブルの詰まりを分析。 |
nft monitor | nftables 全体イベント | カーネル空間でルール追加、セットへのIP登録、テーブル解放等のイベントをリアルタイムにストリーミング監視。 |
nft monitor trace | パケットマッチング軌跡 | 最も重要なトレースツール。指定パケットがどのルールの何行目でマッチし、ACCEPTまたはDROPされたかを1行ずつ追跡可能。 |
nft list ruleset | 生のルール構造 | Firewalldによって抽象化され、最終的にカーネル内に展開された生のnftablesルールデータベースを完全出力。 |
journalctl -u firewalld | ユーザー空間設定ログ | 設定ファイルの構文エラー(XML破損など)や、firewalldサービス自体の起動エラーログを確認。 |
第2部:Linuxカーネル内部構造編
第10章:カーネルパケットパスとNetfilterフックフレームワークの対応
10-1. 各Netfilter Hookの正確な実行タイミング
[ 物理NICからパケット流入 ] ─► [ Driver (NAPIポーリング等) ] ─► [ sk_buff(共通構造体)の生成 ]
│
▼ ip_rcv()
┌────────────────────────────────────┐
│ 1. PREROUTING Hook (宛先アドレス変換 / 判定前のメタデータ割り当て等) │
└──────────────────┬─────────────────┘
│
▼ [ Routing Decision(宛先IPによる分岐)]
├─► (自ホスト宛)
│ ▼ ip_local_deliver()
│ ┌─────────────────┐
│ │ 2. INPUT Hook (受信パケットのフィルタ) │
│ └──────┬─────────┘
│ ▼ Local Deliver
│ [ TCP/UDP処理 / Socket Buffer / アプリ ]
│
└─► (他ホスト宛)
▼ ip_forward()
┌───────────────────┐
│ 3. FORWARD Hook (転送パケットのフィルタ) │
└─────────┬──────────┘
▼ ip_forward_finish()
┌───────────────────────────┴──┐
▼(自ホスト内プロセスから送信) ▼
ip_queue_xmit() ┌──────────────┐
│ │ 4. OUTPUT Hook │
└──────────────────────────┴──────┬───────┘
▼
┌──────────────┐
│ 5. POSTROUTING Hook (送信元変換等) │
└──────┬───────┘
▼ [ 物理NICから送出 ]
10-2. フック実行に伴うカーネルメモリ(sk_buff)の内部ハンドリング
パケット情報が渡されると、Netfilterエンジンはnf_hook_entryリストを走査してフックにバインドされた関数を実行します。
[ パケットパース (ip_rcv) ] ──► [ nf_hook_thresh() 呼び出し ] ──► [ nft_do_chain() ] ──► [ ルール・式評価 ] ──► [ verdict 結果返却 ]
評価がACCEPTであれば次のフックまたはプロトコルスタックにポインタが渡され、DROPであればメモリバッファ(sk_buff)ごと解放(kfree_skb())されてパケットは完全に消滅します。
第11章:Connection Tracking (conntrack) とFirewalld状態遷移の実体
Conntrackによるパケット追跡レコードは、カーネルメモリ空間においてstruct nf_connという構造体で保持されます。
11-1. struct nf_conn 構造体の定義
struct nf_conn {
struct nf_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX]; // 往路・復路の5つ組識別子
unsigned long timeout; // レコードの有効期限タイマー
u_int32_t status; // ステータス([ASSURED], [UNTRACKED]など)
struct nf_conn_help *helper; // 動的ポート追跡ヘルパー
u_int32_t mark; // パケットに付与するメタデータマーク
u_int16_t zone; // Conntrackを分離する論理ゾーン
};
11-2. パケットの状態分類と双方向トラフィック処理ライフサイクル
[ 外部クライアント (NEW:SYNパケット) ]
│
▼ 1. Conntrackに「NEW」として登録
[ INPUTフックを通過 ] ──► Firewalldルール評価 (443/tcp 許可)
│
▼ 2. 通信が成立
[ 接続ステータス: ESTABLISHED 状態へ遷移 ] (Conntrackテーブル上で[ASSURED]化)
│
▼ 3. 戻りパケットの送信
[ 戻りパケット (REPLY方向) 到着 ]
│
▼ 4. Conntrackにより即時に「ESTABLISHED」とマッチング判定
[ 優先ルール:ct state established,related accept ] ──► ポートチェックをバイパスして【 即時許可 】
第12章:Flowtable技術による高速フォワーディング(Fast Path)挙動
12-1. Flowtable適用時のパケット高速転送経路
[ パケットがNICに到着 ]
│
▼
┌──────────────────────────────────────┐
│ Flowtable 検索 (Flow lookup) │ → 既存の登録済みフローを検索
└────────────────┬─────────────────────┘
│
├─ [ ミス ] ──► [ 標準の Netfilter パケット判定パス ]
│ ・Conntrack 状態監視(SYNなどの接続開始チェック)
│ ・通常ルールセットの線形・多次元評価の実施
│ ・接続が ESTABLISHED になった時点で Flowtable への登録命令をセット
│
└─ [ ヒット ] ──► [ Fast Forward(高速バイパス経路) ]
・通常のフィルタチェーンの評価を省略して高速転送経路に入る
・ルーティング処理やConntrackの状態再計算をショートカット
・即座に該当インターフェース/ソケット受信キューへ中継
第13章:nftables 仮想マシンの内部構造とVM命令列の解析
nftablesの実体は、ユーザーから渡された抽象的なファイアウォールルールを、カーネル内で実行可能なバイトコード命令列に翻訳して実行する仮想マシン(VM)です。
13-1. レジスタを用いたバイトコード評価プロセス
例えば、ip daddr 192.168.1.1 tcp dport 80 accept というルールを評価する際、仮想マシン(VM)の内部では以下のような命令(アセンブリ表現)が実行されます。
1. [ payload load 4b @ network header +16 => reg 1 ]
・ネットワークヘッダの宛先IP(16バイト目から4バイト)をパースし、仮想レジスタ1に読み込む。
reg1 = [ 192.168.1.1 ]
2. [ cmp eq reg 1 192.168.1.1 ]
・レジスタ1の値が「192.168.1.1」に等しいか検証する。不一致なら即座にこのルールの評価をスキップ。
3. [ payload load 2b @ transport header +2 => reg 2 ]
・トランスポートヘッダ(TCP)の宛先ポート(2バイト目から2バイト)を取得し、仮想レジスタ2に展開。
reg2 = [ 80 ]
4. [ cmp eq reg 2 80 ]
・レジスタ2の値が「80(HTTP)」に等しいか検証。不一致なら評価をスキップ。
5. [ immediate accept ]
・すべての比較が成立したため、パケットの処理(verdict)としてACCEPTを確定させ、結果特殊レジスタに格納。
第14章:nftables 基本データ構造 ── Set と Map の全機能解剖
14-1. Set、Map、および Verdict Map の構造定義と動作
■ Set(IP等の存在確認:Membership Check)
[ IP: 192.168.1.50 ] ──► [ Set: @blocked_ips ] ──► (存在する?) ──► YES ──► DROP
※計算量:平均O(1)ハッシュテーブル。存在確認のみに使用する最もシンプルな構造。
■ Map(キーと値のマッピング:Key-Value Mapping)
[ 送信元IP: 192.168.1.50 ] ──► [ Map: @client_limit ] ──(高速ハッシュ検索)──► [ 192.168.1.50 → 20M ] → メタマーク領域に「20M」を適用
※IP等をキーにして、対応する別の値(帯域マークやタグ情報)を取り出すマッピング。
■ Verdict Map(キーと挙動のマッピング:Action Mapping)
[ 宛先Port: 80 ] ──► [ Verdict Map: @port_policy ] ──(高速ハッシュ検索)──►
[ 80 → accept ] ──► 即座に【 許可 (ACCEPT) 】
[ 22 → jump ssh_chain ] ──► 専用チェーンへ【 ジャンプ 】
[ 23 → drop ] ──► 即座に【 ドロップ (DROP) 】
※IPやポートをキーに検索し、適用すべきアクション(verdict)を直接返します。
第15章:nftablesの更新方式とアトミックトランザクション
15-1. 更新プロセスの比較
① iptables(非アトミック更新:パケットドロップのリスク)
iptablesは、テーブル全体のルールを一度に上書きして更新します。カーネルから全ルールをユーザー空間へダウンロードし、そこで1行ルールを変更した上で再度全体をカーネルに一括アップロードします。この切り替え処理の瞬間、パケット処理エンジンは一時的に中断されるか不整合な状態となり、パケットの取りこぼし(ドロップ)や競合状態によるエラーが発生するリスクがあります。
② nftables(トランザクションコミット + ポインタスワップ)
nftablesはルールを変更する際、変更命令をトランザクション(Netlinkメッセージ)として一括でカーネルに送信します。カーネルはこれをメモリ上の別のステージング領域に構築し、不整合がないか事前検証を完了させます。
[ ステージング領域(検証完了・構築済み新ルール) ]
│
▼ (コミットシグナル) → メモリポインタのスワップ(Pointer Swap)
┌────────────────────────────────────────────────────────┐
│ 一瞬でポインタ参照を新テーブル側へ切り替え(アトミック) │
└──────────────────────────┬─────────────────────────────┘
│ (一瞬で切り替え)
▼
[ アクティブなパケット処理エンジン (このポインタスワップは完全一瞬で行われる) ]
切り替えは、カーネル内の参照ポインタをスワップするだけなので、パケット処理の停止時間を限りなくゼロ(アトミック更新)に抑え、パケットの取りこぼしや不整合によるセキュリティホールを完全に回避します。
付録A:実践インフラ設計例(各種サービス用ファイアウォール設計マトリクス)
実務構築において、各標準的なコンポーネントおよび外部への公開ポートなどを想定した実務設計定義マトリクスです。
| サービス名 | ポート定義 | 対象ゾーン | 接続元制限 | 設定方式・備考 |
|---|---|---|---|---|
| Webサービス(Caddyプロキシ) | 80/tcp, 443/tcp | public | any(全開放) | 全世界に向けて暗号化ポートを公開。firewall-cmd --zone=public --add-service=http --add-service=https |
| 管理者SSH接続 | 22/tcp | trusted / public | 管理者作業用PC(管理端末のIP) | 一般回線からのアクセスを禁止し、管理者端末に限定。firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="<管理端末のIP>" port port="22" protocol="tcp" accept' |
| Headscale(VPN認証・管理) | 8080/tcp | public | Caddy自身のIP(172.16.1.18) | 外部インターネットへの直接公開を禁止。DMZのプロキシ(Caddy)からの通信のみを受理するマイクロセグメント。firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="172.16.1.18" port port="8080" protocol="tcp" accept' |
| Authentik(OIDC/MFA認証) | 9000/tcp | public | Caddy自身のIP(172.16.1.18) | 認証エンジンもプロキシからの通信に限定。firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="172.16.1.18" port port="9000" protocol="tcp" accept' |
| MariaDB / PostgreSQL | 3306/tcp, 5432/tcp | internal | 各アプリケーションのコンテナセグメント | 外部インターフェースにデータベースポートを露出させず、内部ネットワークインターフェースにのみ限定バインド。 |
| DNSサービス | 53/tcp, 53/udp | internal | 内部セグメント全域 | 内部の名前解決要求を処理。firewall-cmd --zone=internal --add-service=dns |
| Prometheus / Grafana | 9090/tcp, 3000/tcp | internal | 監視サーバーIP | メトリクス収集用ポートを一般に公開せず、監視用セグメントからのみスクレイプ可能にする。firewall-cmd --zone=internal --add-port=9090/tcp |
| WireGuard / SoftEther | 51820/udp | public | any(全開放) | 外部からのVPN受け入れポート。firewall-cmd --zone=public --add-port=51820/udp |
付録B:実機で確認する生のnftables ruleset実例
Firewalldで Web(HTTPS)およびSSHサービスを有効にした際、カーネル空間に展開される生のnftablesルールセット(抜粋)の実構成です。
# sudo nft list ruleset コマンドの出力例
table inet firewalld {
chain filter_INPUT {
type filter hook input priority filter + 10; policy accept;
# 確立済みの通信(ESTABLISHED)はポートスキャンを介さず最速でACCEPT
ct state established,related accept
iifname "lo" accept
# ゾーン選別チェーンへのジャンプ
jump filter_INPUT_ZONES
}
chain filter_INPUT_ZONES {
# 物理ネットワークカード (ens160等) から入ってきた通信を、publicゾーン用の評価チェーンへ goto 送出
iifname "ens160" goto filter_IN_public
}
chain filter_IN_public {
# 状態監視と個別ポートの受け入れ規則
tcp dport 22 accept
tcp dport 443 accept
# 明示的に許可されていない通信は、エラー(ICMP Admin Prohibited)を伴いREJECT
reject with icmpx type admin-prohibited
}
}
付録C:実務用 Firewalld コマンドチートシート
日常の運用監視、検証、変更作業時に使用するコマンド一覧です。
C-1. 現在のステータス・情報確認
# ファイアウォールサービスが起動しているかの確認
firewall-cmd --state
# 現在アクティブにインターフェース等に紐づいているゾーンの一覧表示
firewall-cmd --get-active-zones
# システムでサポートされている全ゾーンの一覧表示
firewall-cmd --get-zones
# 現在デフォルトに設定されているゾーン(public等)の表示
firewall-cmd --get-default-zone
# 現在デフォルトゾーンに適用されているすべてのルール情報の表示
firewall-cmd --list-all
# 特定のゾーン(dmzなど)に適用されているルールを詳細に表示
firewall-cmd --zone=dmz --list-all
C-2. サービス・ルールの追加と削除(Runtime & Permanent 応用)
# 【一時テスト】publicゾーンにHTTPS(443/tcp)を一時的に追加(Runtime:再起動で消える)
sudo firewall-cmd --zone=public --add-service=https
# 【永続追加】publicゾーンにHTTPSを永続追加(Permanent:reload後に反映)
sudo firewall-cmd --zone=public --add-service=https --permanent
# 永続設定ファイルを動作中のメモリ空間へ同期リロード
sudo firewall-cmd --reload
# 現在の検証完了したRuntime設定を、すべて永続ファイル(XML)に上書きして固定化
sudo firewall-cmd --runtime-to-permanent
C-3. 緊急制御コマンド(Panic & Lockdown)
# 【緊急:通信完全全閉鎖】パニックモードを有効にし、すべてのインバウンド・アウトバウンド通信を遮断する
sudo firewall-cmd --panic-on
# パニックモードをオフに戻し、通信を復旧
sudo firewall-cmd --panic-off
# パニックモードが有効になっているかの確認
firewall-cmd --query-panic
# 【緊急:ロックダウン】ポリシー変更の操作を制限する(他ユーザーやスクリプトによる設定書き換えをロック)
sudo firewall-cmd --lockdown-on
# ロックダウンの解除
sudo firewall-cmd --lockdown-off
C-4. nftables 関連コマンド(デバッグ時)
# ホストに展開されている生のルールセット全体を表示
sudo nft list ruleset
# リアルタイムにカーネル内でのルール変更や追加イベントをトレース監視する
sudo nft monitor
# パケットがルールの何行目でどのようにマッチしたかを完全に追跡
sudo nft monitor trace
ゼロトラスト設計思想との対応マッピングについて
本ガイドの原則(最小権限・侵害前提・明示的な検証・動的防御)とFirewalld/nftables機能との対応表は「Firewalldとnftablesの構造」最終確認に掲載している内容と同一のため、そちらをご参照ください。
Firewalld運用実務からカーネル内部構造まで整理完了 🎉
ゾーン設計・変更管理・トラブルシューティングの実務知識と、nftables VM・Conntrack・Flowtableのカーネル内部動作を一通り確認しました。アーキテクチャの全体像は「Firewalldとnftablesの構造」もあわせてご参照ください。