このページの目次

Netfilter と BPF/XDP

カバー範囲: Netfilterフック → iptables/nftables → conntrack → NAT/マスカレード → XDP → BPF/cBPF/eBPF → TC BPF カーネルバージョン: 2.6 ~ 6.x

概要

Netfilter は Linux のパケットフィルタリング/変更エンジンであり、iptables(旧)および nftables(新)の基盤を提供します。XDP/eBPF は、より新しいパラダイムを表しており、カーネルの最も早い受信ポイント(NICドライバ層)でユーザー提供プログラムを実行し、高性能なパケット処理を実現します。

Netfilterフック

// include/uapi/linux/netfilter.h
// 5つのフックポイント(IPv4を例とする):

enum nf_inet_hooks {
    NF_INET_PRE_ROUTING,   // パケット到着時、ルーティング前
    NF_INET_LOCAL_IN,      // 本体宛のパケット、ルーティング後
    NF_INET_FORWARD,       // フォワードされるパケット
    NF_INET_LOCAL_OUT,     // 本体から送信されるパケット、ルーティング前
    NF_INET_POST_ROUTING,  // 送信される全パケット、ルーティング後
};

// 各フックポイント: 登録されたフック関数が優先度順に呼び出される
// 戻り値:
//   NF_ACCEPT:  パケット通過(正常)
//   NF_DROP:    破棄(送信者に通知しない)
//   NF_STOLEN:  パケットがフックによって奪われる
//   NF_QUEUE:   パケットをユーザー空間キューに追加(nfnetlink_queue)

iptables(旧、xtablesベース)

// net/ipv4/netfilter/ip_tables.c
// filterテーブル(デフォルト):
//   INPUT:   本体宛のパケット
//   OUTPUT:  本体から送信されるパケット
//   FORWARD: フォワードされるパケット

// natテーブル:
//   PREROUTING  (DNAT)
//   INPUT       (本体宛DNAT)
//   OUTPUT      (本体宛DNAT)
//   POSTROUTING (SNAT/MASQUERADE)

// mangleテーブル: TOS/TTL/MARKの変更
// rawテーブル:    NOTRACK(conntrackをスキップ)

nftables(新、iptablesの代替)

// net/netfilter/nf_tables_api.c
// nftはルールを実行するために仮想マシンを使用する(iptablesの線形マッチングではない)
// より柔軟: set, map, concatenationをネイティブサポート
// より高速: 複数テーブルの複数回走査に代わり、ルールを1回だけ走査

// nft list ruleset
// table inet filter {
//     chain input { type filter hook input priority 0; policy drop;
//         ct state established,related accept
//         iif lo accept
//         tcp dport 22 accept
//     }
// }

接続追跡(conntrack)

// net/netfilter/nf_conntrack_core.c
// conntrackは各接続(フロー)の状態を追跡する
//   → NATはこれに依存する(戻りパケットがどのフローに属するかを知るため)
//   → iptablesのstateマッチはこれに依存する

// conntrackテーブル:
//   各接続に1つのnf_conn → ハッシュテーブル
//   最大エントリ数: /proc/sys/net/netfilter/nf_conntrack_max
//   タイムアウト: プロトコルごとに独立したタイムアウト(TCP: ESTABLISHEDで432000秒 ≈ 5日)

// 注意! NATゲートウェイでは、conntrackテーブルがいっぱいになる可能性がある
//   → パケットドロップ → 新規接続の失敗
//   → nf_conntrack_maxを増やすか、タイムアウトを短くする

NAT / MASQUERADE

SNAT(ソースNAT):
  ソースIP:portを出口IP:新しいportに変更
  conntrack記録: orig_src:port → reply_dst:port → 返信パケットの逆変換

MASQUERADE:
  動的SNAT — 出口インターフェースの現在のIPを自動で使用
  適している場面: DHCPクライアント(出口IPが変化する)

DNAT(宛先NAT):
  宛先IP:portを内部サーバーに変更
  → ポートフォワーディング

XDP: eXpress Data Path

// net/core/filter.c + drivers/net/*_xdp.c
// XDP: NICドライバのNAPI poll内、sk_buff割り当て前にBPFプログラムを実行
//   非常に早い処理ポイント → 極めて高いPPS(Mppsレベル)
//   可能な操作: DROP(最速)、TX(転送)、PASS(プロトコルスタックへ)、REDIRECT(別NICへ)

// BPFプログラムの戻り値:
enum xdp_action {
    XDP_DROP,       // 破棄(DDoSフィルタリングなど)
    XDP_PASS,       // プロトコルスタックへ渡す(通常フロー)
    XDP_TX,         // このNICから送信(ヘアピン)
    XDP_REDIRECT,   // 別のNICまたはCPUへリダイレクト
};

// ローディング: bpftoolまたはip link set dev eth0 xdp obj prog.o sec xdp経由

eBPFプログラムタイプ

種類フックポイント用途
XDPNICドライバ(最も早期)DDoSフィルタリング、ロードバランシング
TC(トラフィックコントロール)qdisc(ingress/egress)ファイアウォール、ポリシールーティング
cgroup skbcgroupソケットコンテナネットワークポリシー(Cilium)
socket filterソケット作成時SO_ATTACH_BPF
kprobe/tracepointカーネル関数エントリ/tracepoint観測性

参考

  • ソースコード⁠: net/netfilter/, net/core/filter.c, kernel/bpf/
  • カーネルドキュメント⁠: Documentation/networking/filter.rst, Documentation/bpf/
  • LWN: 「XDP and the packet processing revolution」

キーワード: netfilter, iptables, nftables, conntrack, NAT, XDP, BPF, eBPF, TC BPF