Headless Python engine for isolated network namespace testing and PCAP assertions.
Project description
Network Sandbox Engine (NSE)
A headless Python engine for deterministic, kernel-level nftables firewall testing, with an optional Svelte/FastAPI web GUI.
NSE uses ephemeral Linux network namespaces and Scapy to validate firewall logic. Rules are executed by the actual kernel: no userspace simulation, no host pollution.
How It Works
[Library / CLI] [FastAPI Daemon (optional)] [Sandbox - Linux netns]
| | |
|-- run_test_pipeline() ------>| |
| (rules + packet sequence) |-- 1. Create topology ------->| (veth pair / gateway)
| |-- 2. Spawn mock listeners -->| (TCP/UDP echo daemons)
| |-- 3. Load nft rules -------->|
| |-- 4. Start nft monitor ----->| (trace harvester)
| |-- 5. Inject packets -------->| (Scapy L2/L3)
| |<- 6. Poll conntrack ---------| (/proc/net/nf_conntrack)
|<-- TraceEvent stream --------|-- 7. Stream verdicts ------->| (WebSocket or iterator)
| |-- 8. Teardown (GC) --------->| (namespace deleted)
The host firewall is never modified. Rules are confined to the isolated sandbox namespace and are destroyed with it at teardown.
Architecture Overview
| Component | Technology | Description |
|---|---|---|
| Headless Core | Python 3.10+ / Scapy | NetnsController, PCAPAsserter, RuleEngine, ScapyInjector, Pipeline |
| CLI Test Runner | nse-runner / YAML |
Headless YAML test suite runner for CI/CD pipelines |
| GUI Daemon (optional) | FastAPI + Uvicorn | REST and WebSocket API streaming TraceEvent objects from the kernel |
| Frontend (optional) | Svelte + Vite | Rule editor, multi-packet crafter, animated trace visualizer, conntrack table |
| Packet Injection | Scapy (Layer 2/3) | IPv4 and IPv6, TCP with custom flags, UDP, ICMP, ICMPv6 |
| Mock Listeners | TCP/UDP echo sockets | Background listeners inside namespaces to complete handshakes |
| Conntrack Engine | /proc/net/nf_conntrack |
Captures ESTABLISHED, SYN_SENT, TIME_WAIT states in real-time |
Prerequisites
NSE requires Linux with kernel 5.4 or later (namespace and nftables trace support).
| Dependency | Purpose |
|---|---|
| Python 3.10+ | Core library, CLI, and optional GUI daemon |
nftables (nft) |
Compiles rules and generates trace events |
iproute2 (ip) |
Manages network namespaces and veth pairs |
| conntrack | Reads connection state from kernel tables |
| Node.js 18+ | Required only to build the Svelte frontend |
# Debian / Ubuntu
sudo apt install nftables iproute2 python3-venv python3-pip conntrack
Quickstart
A. Headless library
pip install network-sandbox-engine
import asyncio
from nse.core.pipeline import run_test_pipeline
from nse.models.test_request import PacketSpec, TestRequest
async def main():
req = TestRequest(
rules="table ip filter { chain input { type filter hook input priority 0; tcp dport 22 accept; drop; } }",
packets=[PacketSpec(protocol="tcp", src_ip="10.0.0.1", dst_ip="10.0.0.2", dst_port=22)],
)
events = await run_test_pipeline(req)
for ev in events:
print(ev)
asyncio.run(main())
B. CLI YAML runner
pip install "network-sandbox-engine[cli]"
nse-runner --file my_tests.yaml
# my_tests.yaml
- name: SSH accepted
rules: |
table ip filter {
chain input { type filter hook input priority 0; tcp dport 22 accept; drop; }
}
packets:
- protocol: tcp
src_ip: 10.0.0.1
dst_ip: 10.0.0.2
dst_port: 22
expect:
verdict: ACCEPT
C. Full GUI (development mode)
git clone https://github.com/onyks-os/NetworkSandboxEngine.git
cd NetworkSandboxEngine
make setup # bootstrap venv + npm install
make backend # starts FastAPI daemon (requires sudo -E)
make frontend # starts Vite dev server on port 5173
Open http://localhost:5173 in a browser.
Repository Layout
NetworkSandboxEngine/
|-- nse/ # PyPI package (pip install network-sandbox-engine)
| |-- __init__.py # Public API: NetnsController, PCAPAsserter
| |-- core/ # Kernel-level primitives
| | |-- netns_controller.py
| | |-- scapy_injector.py
| | |-- sniffer.py # PCAPAsserter
| | |-- pipeline.py # run_test_pipeline()
| | `-- rule_engine.py # nft load / validate
| |-- models/ # Pydantic models (lazy import via try/except)
| | |-- test_request.py # PacketSpec, TestRequest, TopologyType
| | `-- trace_event.py # TraceEvent
| `-- cli/
| `-- runner.py # nse-runner entrypoint
|
|-- gui/ # Not on PyPI - GUI daemon only
| |-- server.py # FastAPI + Uvicorn entrypoint
| |-- api/ # REST routes and WebSocket
| `-- daemon/ # trace_harvester, mock_listener
| `-- gui_svelte/ # Svelte + Vite frontend
|
|-- tests/
| `-- test_netns.py # 20 unit tests (2 skipped without root)
|
|-- pyproject.toml # Build config - packages only nse/
|-- Makefile # make setup | test | lint | release
`-- conftest.py # Root sys.path for pytest
Key Features
1. Stateful Packet Sequences and Conntrack
Ordered lists of packets simulate TCP flows. NSE polls /proc/net/nf_conntrack and streams live connection states (SYN_SENT, ESTABLISHED, TIME_WAIT) after each injection.
2. Automatic Mock Listeners
Destination ports in incoming packets receive a background echo listener spawned inside the namespace, completing TCP handshakes and generating valid conntrack entries without manual setup.
3. Gateway Routing Topology
The Gateway Topology spawns a three-namespace chain: Host - Router - Server. Rules are loaded into the Router namespace to test forward chain hooks, routing decisions, and NAT.
4. Dual-Stack IPv4 and IPv6
ICMPv6 echo, dual-stack veth links, and DAD disabled for instant address availability inside namespaces.
5. PCAP Assertions
PCAPAsserter wraps Scapy's AsyncSniffer to arm a BPF filter on a veth interface and assert captured packets. It is usable independently of the full pipeline.
Testing
Unit tests (no root required):
make test
# 20 passed, 2 skipped (root-only integration tests)
Integration tests (root required):
sudo -E .venv/bin/pytest tests/ -v
CLI test suite (root required):
sudo -E .venv/bin/python -m nse.cli.runner --file tests/fixtures/test_suite.yaml
Production Deployment
Package Extras
| Mode | Install command | Dependencies |
|---|---|---|
| Headless core | pip install network-sandbox-engine |
scapy |
| With CLI runner | pip install "network-sandbox-engine[cli]" |
+ pydantic, pyyaml |
The GUI daemon is not distributed via PyPI. It is run from a repository clone.
Building Release Artifacts
make release
This target performs the following steps:
- Runs
make lintandmake test; fails on any error. - Builds
.whland.tar.gzwithpython -m build. - Copies
Dockerfileandscripts/nse.serviceintorelease/. - Generates
SHA256SUMS. - Signs
SHA256SUMSwith GPG, producingSHA256SUMS.asc. The signing key is auto-detected from the keyring; it can be overridden withGPG_KEY_ID=<id>.
Output in release/:
release/
|-- network_sandbox_engine-1.0.0-py3-none-any.whl
|-- network_sandbox_engine-1.0.0.tar.gz
|-- Dockerfile
|-- nse.service
|-- SHA256SUMS
`-- SHA256SUMS.asc
Native Installation with Systemd
sudo pip install release/network_sandbox_engine-1.0.0-py3-none-any.whl
sudo cp release/nse.service /etc/systemd/system/
sudo systemctl daemon-reload && sudo systemctl enable --now nse
Docker
docker build -t nse -f release/Dockerfile .
docker run --privileged -p 8000:8000 -d --name nse-container nse
License
MIT. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file network_sandbox_engine-1.0.0.tar.gz.
File metadata
- Download URL: network_sandbox_engine-1.0.0.tar.gz
- Upload date:
- Size: 24.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
594907417beab0ef720e2712ceebe01e65899b24dc099df5837be352a274c0ca
|
|
| MD5 |
ddf92aca357b525534fca69ef1f9c411
|
|
| BLAKE2b-256 |
0cc5071a050c20012387c465ed09bcd010b8452e0547b951cd13a4f5cf7bebaf
|
File details
Details for the file network_sandbox_engine-1.0.0-py3-none-any.whl.
File metadata
- Download URL: network_sandbox_engine-1.0.0-py3-none-any.whl
- Upload date:
- Size: 24.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
62414916a3a5fed6e5ff6664d6eb63a10c35c824dccf19c489b75c2e628bef12
|
|
| MD5 |
de2436a9cf606018dd922a6730f8f00d
|
|
| BLAKE2b-256 |
6b3ddbbc09f1842d47447fd91c320002a93b1045eec8f62658af9834ed8a8b5c
|