nftables 操作マニュアル

7 分で読了
このページの目次

規則の存在・一致・最終許可は別。input・forward・output と table の管理主体を先に確認する。例は教材で、Docker 等と共有する host ruleset の置換用ではない。

やりたいこと参照先
accept でも通らない経路と verdict
設定の繰返し読込atomic batch と置換
一致規則の特定counter と trace
転送・NAT変換と許可

hook を特定してから規則順を読む

表の所有者と hook を先に確認する

# family と table を列挙して管理対象を確認する
sudo nft list tables

inet/ip/ip6 は対象範囲が異なる。Docker/VPN 管理の表は今回の編集に含めない。

# 全 chain の hook・priority・policy・handle を読む
sudo nft -a list ruleset

-a は厳密な変更に使う handle を表示する。全体を見るのは後続 drop を調べるためで、全体置換の範囲ではない。

# 自分が管理する filter table に絞る
sudo nft list table inet ops_filter

初回前の NotFound は想定内。既存なら全体をこのファイルで管理してよいか確認する。

パケットの想定経路を確認する

# 宛先の出口・次ホップ・送信元を確認する
ip route get 192.0.2.10

実宛先を使う。ローカル検索であり、全転送パケットの送信元・mark を再現しない。

# ローカルの対象ポートが待ち受けているか確認する
ss -lntup

accept はサービスを作らない。別ホスト宛の転送なら対象側で確認する。

図を準備しています
accept 後に別 chain で drop される理由

同じ input hook の早い accept は最終許可ではなく後 chain が drop し得る。forward/output はこの input chain を通らない。

外部から本機は input、通過は forward、本機発は output。小さい priority が先で同値の順序に依存しない。accept 後も別 base chain で drop され得る。通常 chain は名前だけで hook に接続されない。

一括処理は旧規則削除を意味しない

nft -f は batch 処理で add だけなら規則が増え得る。所有する table と置換範囲を決める。次は accept policy の独立 table 構造例で、完全な防御設定や他 table の上書きではない。

table inet ops_filter {
    set admin4 {
        type ipv4_addr
        flags interval
        elements = { 192.0.2.0/24 }
    }
    chain input {
        type filter hook input priority 10; policy accept;
        ct state established,related counter accept
        iifname "lo" counter accept
        meta l4proto ipv6-icmp counter accept
        ip saddr @admin4 tcp dport 22 counter accept
    }
}

初回読込:ファイル・検証・反映・通信確認

完全な例を ./ops-filter.nft に保存し admin4 を置き換え、対象表がないことを確認する。この表だけを管理し、既存の自主管理設定と独立した接続を保存する。

# 現在の状態で batch を受理できるか検証する
sudo nft -c -f ./ops-filter.nft

-c は規則を変更しない。構文・参照・カーネル対応のエラーを先に直す。SSH 到達性は検証しない。

# 確認・検証済みの batch を一度反映する
sudo nft -f ./ops-filter.nft

失敗時はエラーと再一覧を読む。検証成功と読込成功は別。

# 反映された規則・集合・handle を確認する
sudo nft -a list table inet ops_filter

独立クライアントから新しい SSH・業務接続と counter を確認する。永続化は nftables.service の実読込先を確認して行い、配布版で同じパスと仮定しない。

初回は table 不在を確認する。全体を所有する既存 table なら同じファイルに delete と完全な再定義を入れて検査・読込する。delete は存在が前提で無条件冪等ではない。共有 host で flush ruleset を使わず、別接続で到達性も確認する。

handle で指定し狭い条件で trace

行番号ではなく handle で変更する

# 現在の chain と handle を読み直す
sudo nft -a list chain inet ops_filter input

42 は確認した handle に置き換える。変更後は再読込し、古い番号を使い回さない。

# 送信元・ポートを限定した例を末尾へ追加する
sudo nft add rule inet ops_filter input ip saddr 198.51.100.10 tcp dport 443 counter accept

add は末尾、insert は既定で先頭。先行する終端判定を確認する。policy accept の例では主に counter 観測用で、他の送信元を禁止しない。

# 確認済み handle の規則を同じ位置で置き換える
sudo nft replace rule inet ops_filter input handle 42 ip saddr 198.51.100.10 tcp dport 8443 counter accept

既存規則の変更で、add の直後に機械的に続けない。新接続と一覧で変更を確認し、設定ファイルも更新する。

# 不要と確認した規則を削除する
sudo nft delete rule inet ops_filter input handle 42

削除後に再一覧。実験なら元設定を復元して通信を確認する。

集合要素の追加と撤去を分ける

# 確認した管理アドレスを集合に追加する
sudo nft 'add element inet ops_filter admin4 { 198.51.100.10 }'

引用符で波括弧を nft 構文として渡す。list set で確認し、既存区間に含まれる場合は先に集合を読む。

# 不要になった管理アドレスを集合から外す
sudo nft 'delete element inet ops_filter admin4 { 198.51.100.10 }'

後で行う撤去で、追加と同時には実行しない。共有集合全体は削除しない。

trace:印を付けて再現し、片付ける

自主管理表に新規 trace_input を作り、指定元から本機 TCP 443 への通信だけを追跡する。より前の hook で破棄されたものは見えない。

# 通常の input より前に一時追跡 chain を作る
sudo nft 'add chain inet ops_filter trace_input { type filter hook input priority -301; policy accept; }'
# 選んだテスト通信だけ nftrace を有効にする
sudo nft add rule inet ops_filter trace_input ip saddr 198.51.100.10 tcp dport 443 meta nftrace set 1
# この端末で追跡し、別クライアントで再現する
sudo nft monitor trace

同じ trace ID の chain と判定をたどる。出なければ印を付ける規則に到達するか確認する。Ctrl-C は表示停止だけ。

# テスト後、この専用一時 chain だけを空にする
sudo nft flush chain inet ops_filter trace_input

今回の規則だけと確認してから空にし、その後削除する。

# 空になった一時追跡 chain を削除する
sudo nft delete chain inet ops_filter trace_input

table を再一覧して片付けを確認する。他の chain や ruleset は消さない。

削除・replace 前に現在の handle を読む。行番号とは別。counter のない規則にはその計数がない。monitor trace は nftrace 済みの packet を見るだけ。所有する早期 chain に宛先・port 等を絞った一時規則を置き、再現後に handle で除去する。

DNAT は宛先変換で転送許可ではない

層必要条件
Routing転送有効、往路と復路がある
DNAT外来は通常 prerouting、本機発は output を考える
Forward filter変換後の実際の address・port 等で必要な転送を許可
SNAT / masquerade必要な出口と復路設計に限って使う
table ip ops_nat {
    chain prerouting {
        type nat hook prerouting priority dstnat; policy accept;
        iifname "wan0" ip daddr 192.0.2.20 tcp dport 8443 dnat to 10.0.0.10:443
    }
}

IPv4 片断で、管理する gateway・機器名・address・forward・復路が前提。既存接続の NAT は conntrack に残り得るため新接続で試す。iptables-nft と Docker native nftables は別方式。

Chain verdicts · Atomic replacement · NAT · Docker nftables