Skip to content
KitploitKITPLOIT
ツールエクスプロイトブログ
Log in
提出
ツールエクスプロイトブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

フィードお問い合わせプライバシー© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
NetworkSandboxEngine — nftablesルールをテストするための決定論的ネットワークサンドボックス。一時的なLinuxネットワーク名前空間(netns)とScapyを使用して、ファイアウォールロジックを安全に検証します。 | Kitploit
ツール/GitHubGitHub/onyks-os/networksandboxengine
防御ツールパケットスニッフィングと分析スクリプトと自動化構成監査ネットワークセキュリティDevSecOps
GitHubonyks-os/networksandboxengine

NetworkSandboxEngine

nftablesルールをテストするための決定論的ネットワークサンドボックス。一時的なLinuxネットワーク名前空間(netns)とScapyを使用して、ファイアウォールロジックを安全に検証します。

リポジトリを見る
6532日前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有
ウェブサイト

Network Sandbox Engine

分離されたネットワーク名前空間内で決定論的な nftables ファイアウォールテスト を行うための Linux エンジン。

Linux Python CI Status Documentation PyPI License

なぜ NSE なのか? • オラクル契約 • ワイヤ上でのアサーション • 機能 • 要件 • インストール • クイックスタート • 仕組み • プロジェクト構成

なぜ NSE なのか?

稼働中の Linux システム上でファイアウォールルールセットをテストすることには重大なリスクが伴います。不正なルールは SSH 管理セッションを切断したり、テスト中に平文トラフィックを漏洩させたり、ホスト上に孤立したファイアウォールテーブルを残したりする可能性があります。

Network Sandbox Engine (NSE) は、安全で再現可能なテストハーネスを提供します。一時的な Linux ネットワーク名前空間を作成し、仮想イーサネットペアを接続し、nftables ルールセットをコンパイルし、Scapy を使って合成のレイヤー2およびレイヤー3パケットを注入します。評価はすべてサンドボックス名前空間内で行われ、ホストのファイアウォール状態が変更されることは決してありません。

主要なアーキテクチャ上の特性:

  • ホストへの変更ゼロ: ルールセットは一時的なサンドボックス名前空間 (nse_<uuid>) にのみロードされ、ティアダウン時に完全に削除されます。
  • 自己検証型オラクル: 各実行では、テストパケットの前と後に カナリア パケットを注入し、両方についてカーネルトレースが観測された場合にのみ結果を報告します。オラクル契約 を参照してください。
  • デュアルスタックとトポロジ: IPv4 および IPv6 トラフィックをネイティブにサポートし、さらにルーター、NAT、フォワーディングのルールセット検証のためのマルチ名前空間ゲートウェイトポロジもサポートします。
  • 小さく監査可能な表面: 単一パッケージで、Web サーバーも JavaScript もありません。nse/ は約 1200 ステートメントで、テストカバレッジは 98% です。

root 権限が必要

NSE はネットワーク名前空間を作成し、nftables ルールセットをロードし、カーネルトレースイベントを読み取るため、root として実行されます。ソケット、ポート、RPC エンドポイントのいずれも開きません — これはあなたが呼び出すライブラリおよび CLI であり、特権を保持するのは実行期間中のみです。

バージョン 2.1.0 では、以前のリリースに同梱されていた FastAPI/Svelte の Web インターフェースが削除されました。このインターフェースは 2.0.0 以降、root としてインプロセスで動作しており、テストツールとしては大きな攻撃表面となっていました。必要であれば、コードはタグ v2.0.0 の git 履歴に残っています。


オラクル契約

ファイアウォールテストは否定アサーション — 「このパケットは通過しなかった」 — であり、否定アサーションは、計測器が正常に動作していることが判明していなければ何の価値もありません。カーネルに一度もアタッチしなかったトレースモニターと、すべてをブロックしたファイアウォールは、バイト単位で同一の出力を生成します。

したがって NSE は、測定したことを示せない判定を報告することを拒否します:

保証仕組み
モニターが最初のテストパケットの前に接続されていたレディネスキャナリアが注入され、そのカーネルトレースが観測されるまで再注入されます。観測がなければ実行しません。
モニターが最後のパケットの後もまだ接続されていた注入後にライブネスキャナリアが実行されます。これが見逃された場合、判定ストリームは切り詰められたと宣言されます。
パーサーがカーネルの発言を理解したどのパターンにも一致しないトレース行がカウントされ、カウントがゼロより大きい場合はデバッグログではなくエラーとなります。
モニターが静かに停止しなかった読み取りループは終了した理由(正常停止、予期しない EOF、タイムアウト、クラッシュ)を記録し、正常停止のみが許容されます。
判定の欠落は合格ではないCLI ランナーは、観測された判定の数が期待される数と異なる場合(どちらの方向でも)失敗します。

キャナリパケットはトレース ID によって結果から除外されるため、判定ストリームに現れることはありません。

スイートはこれを主張するのではなく証明します。make test-blind はパーサーに何も理解させないように強制し、ランナーが非ゼロで終了しない限りビルドは失敗します。このジョブは毎回のプッシュで CI 上で実行されます。


ワイヤ上でのアサーション

nft monitor trace はルールセットが決定した内容を報告します。ルールセットが一度もマッチしなかったインターフェースから何が出ていったかは報告できませんが、それこそがゼロリークの主張が実際に問うていることです。PCAPAsserter はこれをカバーします。指定されたインターフェース上でキャプチャし、フレームを返す AsyncSniffer ラッパーであり、テストが刺激によって何も生成されなかったことをアサートできるようにします。

from nse import PCAPAsserter

asserter = PCAPAsserter(iface="veth-host")
await asserter.start()
# ... send the stimulus ...
leaked = await asserter.stop()
assert not leaked, leaked

トレースオラクルと同じルールが適用され、それを強制するのは呼び出し側の責任である。一度もアタッチしなかったスニファーも、すべてをブロックしたファイアウォールも、どちらも空のリストを返す。ルールセットをフラッシュした状態で刺激を一度キャプチャし、そのフレームが観測されたことを確認してから、その不在を主張すること。

デフォルトフィルターはリンクローカルのノイズのみを抑制し、それ以外は何も抑制しない。 DEFAULT_FILTER は ARP と ICMPv6 タイプ 133-137(Neighbour Discovery)を除外する。これはホップリミット 255 を持ち、リモートの観測者には到達できない。それ以外はすべてキャプチャされ、グローバルにルーティング可能なアドレスへの ICMPv6 エコーも含まれる。filter 引数はそのデフォルトと組み合わされる。replace_default_filter=True を指定すると、自分のフィルターのみが使用される。このエスケープハッチが存在するのは、フィルターが BPF にコンパイルされカーネル内で評価されるためである。除外されたパケットはユーザースペースに決して到達しないため、下流のどのコンシューマーもそれを復元できない。2.1.2 まで、デフォルトは not arp and not icmp6 であり、ルーティング可能な ICMPv6 も破棄していた。詳細は issue #14 を参照。


機能

  • インプロセスエンジン: 直接の Python API(run_test_pipeline)が構造化された Pydantic モデル(TestRequest、TraceEvent)を返す。
  • Scapy パケットインジェクション: 任意の TCP(カスタム SYN、ACK、FIN、RST フラグ付き)、UDP、ICMP、ICMPv6 パケットを生成する。
  • 分離されたトポロジー:
    • Simple: 単一のサンドボックス名前空間(nse_<id>)をホストに直接接続。
    • Gateway: ルーター(nse_router_<id>)とサーバー(nse_server_<id>)のチェーンによるフォワーディングと NAT のテスト。
  • ワイヤレベルのリークアサーション: PCAPAsserter が指定したインターフェース上でキャプチャするため、テストは刺激がフレームをまったく生成しなかったことをアサートできる。ワイヤ上でのアサートを参照。
  • 自動クリーンアップ: 起動時のスイープが、以前の中止された実行から残った名前空間と veth ペアを検出して削除する。ティアダウンには指数バックオフのリトライが含まれる。
  • CLI YAML テストランナー: 自動化された CI/CD パイプライン向けに宣言的な YAML テストスイートを実行する(nse-runner)。誤った判定および観測に失敗した判定のいずれでも非ゼロで終了する。
  • 厳格な品質基準: 完全な静的型チェック(mypy --strict)、アーキテクチャ境界の強制(import-linter)、ruff フォーマット、カバレッジラチェット(make coverage、下限 98%)。

要件

  • Linux OS(ネットワーク名前空間と nftables をサポートするカーネル 5.4 以降)
  • Python 3.10+
  • nftables(nft)
  • iproute2(ip)
  • root 権限(ip netns およびカーネルトレース操作に必要)

Debian または Ubuntu システムの場合:

sudo apt update && sudo apt install -y nftables iproute2 conntrack

インストール

1. PyPI パッケージ(推奨)

CLI サポート付きのコアエンジンをインストールします:

pip install "network-sandbox-engine[cli]"

2. 手動ソースインストール

ローカル開発の場合:

git clone https://github.com/onyks-os/NetworkSandboxEngine.git
cd NetworkSandboxEngine
make setup

クイックスタート

1. ヘッドレス Python ライブラリ

import asyncio
from nse.core.netns_controller import NetnsController
from nse.core.pipeline import run_test_pipeline
from nse.models.test_request import TestRequest, PacketSpec

rules = """
table ip filter {
    chain input {
        type filter hook input priority 0; policy drop;
        tcp dport 80 accept
    }
}
"""

request = TestRequest(
    rules=rules,
    packets=[
        PacketSpec(protocol="tcp", src_ip="10.0.0.1", dst_ip="10.0.0.2", dst_port=80),
        PacketSpec(protocol="tcp", src_ip="10.0.0.1", dst_ip="10.0.0.2", dst_port=22),
    ],
)


async def main():
    controller = NetnsController()
    events = await run_test_pipeline(request=request, controller=controller)
    for evt in events:
        if evt.verdict:
            print(f"[{evt.chain}] Verdict: {evt.verdict}")


asyncio.run(main())

2. YAMLテストスイートランナー (CLI)

テストファイル firewall_test.yaml を作成します:

tests:
  - name: "Allow HTTP Port 80, Drop SSH Port 22"
    topology: simple
    rules: |
      table ip filter {
        chain input {
          type filter hook input priority 0; policy drop;
          tcp dport 80 accept
        }
      }
    packets:
      - protocol: tcp
        src_ip: 10.0.0.1
        dst_ip: 10.0.0.2
        dst_port: 80
        expected_verdict: ACCEPT
      - protocol: tcp
        src_ip: 10.0.0.1
        dst_ip: 10.0.0.2
        dst_port: 22
        expected_verdict: DROP

expected_verdict はパケットごとに指定します。未知のキーはデフォルト値で処理されるのではなく拒否されるため、タイプミスは、書いてもいない期待値に静かに置き換わるのではなく、スイートを失敗させます。

スイートを root 権限で実行します:

sudo nse-runner --file firewall_test.yaml
ツールをダウンロード