network-sandbox-engine 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. network_sandbox_engine-1.0.0/LICENSE +21 -0
  2. network_sandbox_engine-1.0.0/PKG-INFO +304 -0
  3. network_sandbox_engine-1.0.0/README.md +266 -0
  4. network_sandbox_engine-1.0.0/network_sandbox_engine.egg-info/PKG-INFO +304 -0
  5. network_sandbox_engine-1.0.0/network_sandbox_engine.egg-info/SOURCES.txt +23 -0
  6. network_sandbox_engine-1.0.0/network_sandbox_engine.egg-info/dependency_links.txt +1 -0
  7. network_sandbox_engine-1.0.0/network_sandbox_engine.egg-info/entry_points.txt +2 -0
  8. network_sandbox_engine-1.0.0/network_sandbox_engine.egg-info/requires.txt +16 -0
  9. network_sandbox_engine-1.0.0/network_sandbox_engine.egg-info/top_level.txt +1 -0
  10. network_sandbox_engine-1.0.0/nse/__init__.py +4 -0
  11. network_sandbox_engine-1.0.0/nse/cli/__init__.py +1 -0
  12. network_sandbox_engine-1.0.0/nse/cli/runner.py +218 -0
  13. network_sandbox_engine-1.0.0/nse/core/__init__.py +1 -0
  14. network_sandbox_engine-1.0.0/nse/core/netns_controller.py +618 -0
  15. network_sandbox_engine-1.0.0/nse/core/pipeline.py +400 -0
  16. network_sandbox_engine-1.0.0/nse/core/rule_engine.py +127 -0
  17. network_sandbox_engine-1.0.0/nse/core/scapy_injector.py +211 -0
  18. network_sandbox_engine-1.0.0/nse/core/sniffer.py +55 -0
  19. network_sandbox_engine-1.0.0/nse/models/__init__.py +1 -0
  20. network_sandbox_engine-1.0.0/nse/models/base.py +22 -0
  21. network_sandbox_engine-1.0.0/nse/models/test_request.py +117 -0
  22. network_sandbox_engine-1.0.0/nse/models/trace_event.py +93 -0
  23. network_sandbox_engine-1.0.0/pyproject.toml +66 -0
  24. network_sandbox_engine-1.0.0/setup.cfg +4 -0
  25. network_sandbox_engine-1.0.0/tests/test_netns.py +458 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 onyks
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,304 @@
1
+ Metadata-Version: 2.4
2
+ Name: network-sandbox-engine
3
+ Version: 1.0.0
4
+ Summary: Headless Python engine for isolated network namespace testing and PCAP assertions.
5
+ Author: onyks
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/onyks-os/NetworkSandboxEngine
8
+ Project-URL: Repository, https://github.com/onyks-os/NetworkSandboxEngine
9
+ Project-URL: Issues, https://github.com/onyks-os/NetworkSandboxEngine/issues
10
+ Keywords: networking,namespace,testing,nftables,pcap,scapy
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: POSIX :: Linux
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: System :: Networking
20
+ Classifier: Topic :: Software Development :: Testing
21
+ Requires-Python: >=3.10
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: scapy>=2.5.0
25
+ Provides-Extra: cli
26
+ Requires-Dist: pydantic>=2.0.0; extra == "cli"
27
+ Requires-Dist: pyyaml>=6.0; extra == "cli"
28
+ Provides-Extra: gui
29
+ Requires-Dist: fastapi>=0.111.0; extra == "gui"
30
+ Requires-Dist: uvicorn[standard]>=0.29.0; extra == "gui"
31
+ Requires-Dist: websockets>=12.0; extra == "gui"
32
+ Requires-Dist: pydantic>=2.0.0; extra == "gui"
33
+ Provides-Extra: dev
34
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
35
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
36
+ Requires-Dist: ruff; extra == "dev"
37
+ Dynamic: license-file
38
+
39
+ # Network Sandbox Engine (NSE)
40
+
41
+ A headless Python engine for deterministic, kernel-level `nftables` firewall testing, with an optional Svelte/FastAPI web GUI.
42
+
43
+ [![PyPI](https://img.shields.io/badge/PyPI-network--sandbox--engine-blue)](https://pypi.org/project/network-sandbox-engine/)
44
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/)
45
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
46
+ [![Linux only](https://img.shields.io/badge/OS-Linux%20only-lightgrey.svg)](https://kernel.org/)
47
+
48
+ 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.
49
+
50
+ ---
51
+
52
+ ## How It Works
53
+
54
+ ```text
55
+ [Library / CLI] [FastAPI Daemon (optional)] [Sandbox - Linux netns]
56
+ | | |
57
+ |-- run_test_pipeline() ------>| |
58
+ | (rules + packet sequence) |-- 1. Create topology ------->| (veth pair / gateway)
59
+ | |-- 2. Spawn mock listeners -->| (TCP/UDP echo daemons)
60
+ | |-- 3. Load nft rules -------->|
61
+ | |-- 4. Start nft monitor ----->| (trace harvester)
62
+ | |-- 5. Inject packets -------->| (Scapy L2/L3)
63
+ | |<- 6. Poll conntrack ---------| (/proc/net/nf_conntrack)
64
+ |<-- TraceEvent stream --------|-- 7. Stream verdicts ------->| (WebSocket or iterator)
65
+ | |-- 8. Teardown (GC) --------->| (namespace deleted)
66
+ ```
67
+
68
+ The host firewall is never modified. Rules are confined to the isolated sandbox namespace and are destroyed with it at teardown.
69
+
70
+ ---
71
+
72
+ ## Architecture Overview
73
+
74
+ | Component | Technology | Description |
75
+ | ---------------------- | ------------------------ | ----------------------------------------------------------------------------- |
76
+ | Headless Core | Python 3.10+ / Scapy | `NetnsController`, `PCAPAsserter`, `RuleEngine`, `ScapyInjector`, `Pipeline` |
77
+ | CLI Test Runner | `nse-runner` / YAML | Headless YAML test suite runner for CI/CD pipelines |
78
+ | GUI Daemon (optional) | FastAPI + Uvicorn | REST and WebSocket API streaming `TraceEvent` objects from the kernel |
79
+ | Frontend (optional) | Svelte + Vite | Rule editor, multi-packet crafter, animated trace visualizer, conntrack table |
80
+ | Packet Injection | Scapy (Layer 2/3) | IPv4 and IPv6, TCP with custom flags, UDP, ICMP, ICMPv6 |
81
+ | Mock Listeners | TCP/UDP echo sockets | Background listeners inside namespaces to complete handshakes |
82
+ | Conntrack Engine | `/proc/net/nf_conntrack` | Captures `ESTABLISHED`, `SYN_SENT`, `TIME_WAIT` states in real-time |
83
+
84
+ ---
85
+
86
+ ## Prerequisites
87
+
88
+ NSE requires Linux with kernel 5.4 or later (namespace and nftables trace support).
89
+
90
+ | Dependency | Purpose |
91
+ | ----------------- | ------------------------------------------ |
92
+ | Python 3.10+ | Core library, CLI, and optional GUI daemon |
93
+ | nftables (`nft`) | Compiles rules and generates trace events |
94
+ | iproute2 (`ip`) | Manages network namespaces and veth pairs |
95
+ | conntrack | Reads connection state from kernel tables |
96
+ | Node.js 18+ | Required only to build the Svelte frontend |
97
+
98
+ ```bash
99
+ # Debian / Ubuntu
100
+ sudo apt install nftables iproute2 python3-venv python3-pip conntrack
101
+ ```
102
+
103
+ ---
104
+
105
+ ## Quickstart
106
+
107
+ ### A. Headless library
108
+
109
+ ```bash
110
+ pip install network-sandbox-engine
111
+ ```
112
+
113
+ ```python
114
+ import asyncio
115
+ from nse.core.pipeline import run_test_pipeline
116
+ from nse.models.test_request import PacketSpec, TestRequest
117
+
118
+ async def main():
119
+ req = TestRequest(
120
+ rules="table ip filter { chain input { type filter hook input priority 0; tcp dport 22 accept; drop; } }",
121
+ packets=[PacketSpec(protocol="tcp", src_ip="10.0.0.1", dst_ip="10.0.0.2", dst_port=22)],
122
+ )
123
+ events = await run_test_pipeline(req)
124
+ for ev in events:
125
+ print(ev)
126
+
127
+ asyncio.run(main())
128
+ ```
129
+
130
+ ### B. CLI YAML runner
131
+
132
+ ```bash
133
+ pip install "network-sandbox-engine[cli]"
134
+ nse-runner --file my_tests.yaml
135
+ ```
136
+
137
+ ```yaml
138
+ # my_tests.yaml
139
+ - name: SSH accepted
140
+ rules: |
141
+ table ip filter {
142
+ chain input { type filter hook input priority 0; tcp dport 22 accept; drop; }
143
+ }
144
+ packets:
145
+ - protocol: tcp
146
+ src_ip: 10.0.0.1
147
+ dst_ip: 10.0.0.2
148
+ dst_port: 22
149
+ expect:
150
+ verdict: ACCEPT
151
+ ```
152
+
153
+ ### C. Full GUI (development mode)
154
+
155
+ ```bash
156
+ git clone https://github.com/onyks-os/NetworkSandboxEngine.git
157
+ cd NetworkSandboxEngine
158
+ make setup # bootstrap venv + npm install
159
+ make backend # starts FastAPI daemon (requires sudo -E)
160
+ make frontend # starts Vite dev server on port 5173
161
+ ```
162
+
163
+ Open `http://localhost:5173` in a browser.
164
+
165
+ ---
166
+
167
+ ## Repository Layout
168
+
169
+ ```
170
+ NetworkSandboxEngine/
171
+ |-- nse/ # PyPI package (pip install network-sandbox-engine)
172
+ | |-- __init__.py # Public API: NetnsController, PCAPAsserter
173
+ | |-- core/ # Kernel-level primitives
174
+ | | |-- netns_controller.py
175
+ | | |-- scapy_injector.py
176
+ | | |-- sniffer.py # PCAPAsserter
177
+ | | |-- pipeline.py # run_test_pipeline()
178
+ | | `-- rule_engine.py # nft load / validate
179
+ | |-- models/ # Pydantic models (lazy import via try/except)
180
+ | | |-- test_request.py # PacketSpec, TestRequest, TopologyType
181
+ | | `-- trace_event.py # TraceEvent
182
+ | `-- cli/
183
+ | `-- runner.py # nse-runner entrypoint
184
+ |
185
+ |-- gui/ # Not on PyPI - GUI daemon only
186
+ | |-- server.py # FastAPI + Uvicorn entrypoint
187
+ | |-- api/ # REST routes and WebSocket
188
+ | `-- daemon/ # trace_harvester, mock_listener
189
+ | `-- gui_svelte/ # Svelte + Vite frontend
190
+ |
191
+ |-- tests/
192
+ | `-- test_netns.py # 20 unit tests (2 skipped without root)
193
+ |
194
+ |-- pyproject.toml # Build config - packages only nse/
195
+ |-- Makefile # make setup | test | lint | release
196
+ `-- conftest.py # Root sys.path for pytest
197
+ ```
198
+
199
+ ---
200
+
201
+ ## Key Features
202
+
203
+ ### 1. Stateful Packet Sequences and Conntrack
204
+
205
+ 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.
206
+
207
+ ### 2. Automatic Mock Listeners
208
+
209
+ 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.
210
+
211
+ ### 3. Gateway Routing Topology
212
+
213
+ 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.
214
+
215
+ ### 4. Dual-Stack IPv4 and IPv6
216
+
217
+ ICMPv6 echo, dual-stack veth links, and DAD disabled for instant address availability inside namespaces.
218
+
219
+ ### 5. PCAP Assertions
220
+
221
+ `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.
222
+
223
+ ---
224
+
225
+ ## Testing
226
+
227
+ Unit tests (no root required):
228
+
229
+ ```bash
230
+ make test
231
+ # 20 passed, 2 skipped (root-only integration tests)
232
+ ```
233
+
234
+ Integration tests (root required):
235
+
236
+ ```bash
237
+ sudo -E .venv/bin/pytest tests/ -v
238
+ ```
239
+
240
+ CLI test suite (root required):
241
+
242
+ ```bash
243
+ sudo -E .venv/bin/python -m nse.cli.runner --file tests/fixtures/test_suite.yaml
244
+ ```
245
+
246
+ ---
247
+
248
+ ## Production Deployment
249
+
250
+ ### Package Extras
251
+
252
+ | Mode | Install command | Dependencies |
253
+ | :------------- | :------------------------------------------ | :--------------------- |
254
+ | Headless core | `pip install network-sandbox-engine` | `scapy` |
255
+ | With CLI runner | `pip install "network-sandbox-engine[cli]"` | + `pydantic`, `pyyaml` |
256
+
257
+ The GUI daemon is not distributed via PyPI. It is run from a repository clone.
258
+
259
+ ### Building Release Artifacts
260
+
261
+ ```bash
262
+ make release
263
+ ```
264
+
265
+ This target performs the following steps:
266
+
267
+ 1. Runs `make lint` and `make test`; fails on any error.
268
+ 2. Builds `.whl` and `.tar.gz` with `python -m build`.
269
+ 3. Copies `Dockerfile` and `scripts/nse.service` into `release/`.
270
+ 4. Generates `SHA256SUMS`.
271
+ 5. Signs `SHA256SUMS` with GPG, producing `SHA256SUMS.asc`. The signing key is auto-detected from the keyring; it can be overridden with `GPG_KEY_ID=<id>`.
272
+
273
+ Output in `release/`:
274
+
275
+ ```
276
+ release/
277
+ |-- network_sandbox_engine-1.0.0-py3-none-any.whl
278
+ |-- network_sandbox_engine-1.0.0.tar.gz
279
+ |-- Dockerfile
280
+ |-- nse.service
281
+ |-- SHA256SUMS
282
+ `-- SHA256SUMS.asc
283
+ ```
284
+
285
+ ### Native Installation with Systemd
286
+
287
+ ```bash
288
+ sudo pip install release/network_sandbox_engine-1.0.0-py3-none-any.whl
289
+ sudo cp release/nse.service /etc/systemd/system/
290
+ sudo systemctl daemon-reload && sudo systemctl enable --now nse
291
+ ```
292
+
293
+ ### Docker
294
+
295
+ ```bash
296
+ docker build -t nse -f release/Dockerfile .
297
+ docker run --privileged -p 8000:8000 -d --name nse-container nse
298
+ ```
299
+
300
+ ---
301
+
302
+ ## License
303
+
304
+ MIT. See [LICENSE](LICENSE).
@@ -0,0 +1,266 @@
1
+ # Network Sandbox Engine (NSE)
2
+
3
+ A headless Python engine for deterministic, kernel-level `nftables` firewall testing, with an optional Svelte/FastAPI web GUI.
4
+
5
+ [![PyPI](https://img.shields.io/badge/PyPI-network--sandbox--engine-blue)](https://pypi.org/project/network-sandbox-engine/)
6
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
8
+ [![Linux only](https://img.shields.io/badge/OS-Linux%20only-lightgrey.svg)](https://kernel.org/)
9
+
10
+ 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.
11
+
12
+ ---
13
+
14
+ ## How It Works
15
+
16
+ ```text
17
+ [Library / CLI] [FastAPI Daemon (optional)] [Sandbox - Linux netns]
18
+ | | |
19
+ |-- run_test_pipeline() ------>| |
20
+ | (rules + packet sequence) |-- 1. Create topology ------->| (veth pair / gateway)
21
+ | |-- 2. Spawn mock listeners -->| (TCP/UDP echo daemons)
22
+ | |-- 3. Load nft rules -------->|
23
+ | |-- 4. Start nft monitor ----->| (trace harvester)
24
+ | |-- 5. Inject packets -------->| (Scapy L2/L3)
25
+ | |<- 6. Poll conntrack ---------| (/proc/net/nf_conntrack)
26
+ |<-- TraceEvent stream --------|-- 7. Stream verdicts ------->| (WebSocket or iterator)
27
+ | |-- 8. Teardown (GC) --------->| (namespace deleted)
28
+ ```
29
+
30
+ The host firewall is never modified. Rules are confined to the isolated sandbox namespace and are destroyed with it at teardown.
31
+
32
+ ---
33
+
34
+ ## Architecture Overview
35
+
36
+ | Component | Technology | Description |
37
+ | ---------------------- | ------------------------ | ----------------------------------------------------------------------------- |
38
+ | Headless Core | Python 3.10+ / Scapy | `NetnsController`, `PCAPAsserter`, `RuleEngine`, `ScapyInjector`, `Pipeline` |
39
+ | CLI Test Runner | `nse-runner` / YAML | Headless YAML test suite runner for CI/CD pipelines |
40
+ | GUI Daemon (optional) | FastAPI + Uvicorn | REST and WebSocket API streaming `TraceEvent` objects from the kernel |
41
+ | Frontend (optional) | Svelte + Vite | Rule editor, multi-packet crafter, animated trace visualizer, conntrack table |
42
+ | Packet Injection | Scapy (Layer 2/3) | IPv4 and IPv6, TCP with custom flags, UDP, ICMP, ICMPv6 |
43
+ | Mock Listeners | TCP/UDP echo sockets | Background listeners inside namespaces to complete handshakes |
44
+ | Conntrack Engine | `/proc/net/nf_conntrack` | Captures `ESTABLISHED`, `SYN_SENT`, `TIME_WAIT` states in real-time |
45
+
46
+ ---
47
+
48
+ ## Prerequisites
49
+
50
+ NSE requires Linux with kernel 5.4 or later (namespace and nftables trace support).
51
+
52
+ | Dependency | Purpose |
53
+ | ----------------- | ------------------------------------------ |
54
+ | Python 3.10+ | Core library, CLI, and optional GUI daemon |
55
+ | nftables (`nft`) | Compiles rules and generates trace events |
56
+ | iproute2 (`ip`) | Manages network namespaces and veth pairs |
57
+ | conntrack | Reads connection state from kernel tables |
58
+ | Node.js 18+ | Required only to build the Svelte frontend |
59
+
60
+ ```bash
61
+ # Debian / Ubuntu
62
+ sudo apt install nftables iproute2 python3-venv python3-pip conntrack
63
+ ```
64
+
65
+ ---
66
+
67
+ ## Quickstart
68
+
69
+ ### A. Headless library
70
+
71
+ ```bash
72
+ pip install network-sandbox-engine
73
+ ```
74
+
75
+ ```python
76
+ import asyncio
77
+ from nse.core.pipeline import run_test_pipeline
78
+ from nse.models.test_request import PacketSpec, TestRequest
79
+
80
+ async def main():
81
+ req = TestRequest(
82
+ rules="table ip filter { chain input { type filter hook input priority 0; tcp dport 22 accept; drop; } }",
83
+ packets=[PacketSpec(protocol="tcp", src_ip="10.0.0.1", dst_ip="10.0.0.2", dst_port=22)],
84
+ )
85
+ events = await run_test_pipeline(req)
86
+ for ev in events:
87
+ print(ev)
88
+
89
+ asyncio.run(main())
90
+ ```
91
+
92
+ ### B. CLI YAML runner
93
+
94
+ ```bash
95
+ pip install "network-sandbox-engine[cli]"
96
+ nse-runner --file my_tests.yaml
97
+ ```
98
+
99
+ ```yaml
100
+ # my_tests.yaml
101
+ - name: SSH accepted
102
+ rules: |
103
+ table ip filter {
104
+ chain input { type filter hook input priority 0; tcp dport 22 accept; drop; }
105
+ }
106
+ packets:
107
+ - protocol: tcp
108
+ src_ip: 10.0.0.1
109
+ dst_ip: 10.0.0.2
110
+ dst_port: 22
111
+ expect:
112
+ verdict: ACCEPT
113
+ ```
114
+
115
+ ### C. Full GUI (development mode)
116
+
117
+ ```bash
118
+ git clone https://github.com/onyks-os/NetworkSandboxEngine.git
119
+ cd NetworkSandboxEngine
120
+ make setup # bootstrap venv + npm install
121
+ make backend # starts FastAPI daemon (requires sudo -E)
122
+ make frontend # starts Vite dev server on port 5173
123
+ ```
124
+
125
+ Open `http://localhost:5173` in a browser.
126
+
127
+ ---
128
+
129
+ ## Repository Layout
130
+
131
+ ```
132
+ NetworkSandboxEngine/
133
+ |-- nse/ # PyPI package (pip install network-sandbox-engine)
134
+ | |-- __init__.py # Public API: NetnsController, PCAPAsserter
135
+ | |-- core/ # Kernel-level primitives
136
+ | | |-- netns_controller.py
137
+ | | |-- scapy_injector.py
138
+ | | |-- sniffer.py # PCAPAsserter
139
+ | | |-- pipeline.py # run_test_pipeline()
140
+ | | `-- rule_engine.py # nft load / validate
141
+ | |-- models/ # Pydantic models (lazy import via try/except)
142
+ | | |-- test_request.py # PacketSpec, TestRequest, TopologyType
143
+ | | `-- trace_event.py # TraceEvent
144
+ | `-- cli/
145
+ | `-- runner.py # nse-runner entrypoint
146
+ |
147
+ |-- gui/ # Not on PyPI - GUI daemon only
148
+ | |-- server.py # FastAPI + Uvicorn entrypoint
149
+ | |-- api/ # REST routes and WebSocket
150
+ | `-- daemon/ # trace_harvester, mock_listener
151
+ | `-- gui_svelte/ # Svelte + Vite frontend
152
+ |
153
+ |-- tests/
154
+ | `-- test_netns.py # 20 unit tests (2 skipped without root)
155
+ |
156
+ |-- pyproject.toml # Build config - packages only nse/
157
+ |-- Makefile # make setup | test | lint | release
158
+ `-- conftest.py # Root sys.path for pytest
159
+ ```
160
+
161
+ ---
162
+
163
+ ## Key Features
164
+
165
+ ### 1. Stateful Packet Sequences and Conntrack
166
+
167
+ 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.
168
+
169
+ ### 2. Automatic Mock Listeners
170
+
171
+ 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.
172
+
173
+ ### 3. Gateway Routing Topology
174
+
175
+ 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.
176
+
177
+ ### 4. Dual-Stack IPv4 and IPv6
178
+
179
+ ICMPv6 echo, dual-stack veth links, and DAD disabled for instant address availability inside namespaces.
180
+
181
+ ### 5. PCAP Assertions
182
+
183
+ `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.
184
+
185
+ ---
186
+
187
+ ## Testing
188
+
189
+ Unit tests (no root required):
190
+
191
+ ```bash
192
+ make test
193
+ # 20 passed, 2 skipped (root-only integration tests)
194
+ ```
195
+
196
+ Integration tests (root required):
197
+
198
+ ```bash
199
+ sudo -E .venv/bin/pytest tests/ -v
200
+ ```
201
+
202
+ CLI test suite (root required):
203
+
204
+ ```bash
205
+ sudo -E .venv/bin/python -m nse.cli.runner --file tests/fixtures/test_suite.yaml
206
+ ```
207
+
208
+ ---
209
+
210
+ ## Production Deployment
211
+
212
+ ### Package Extras
213
+
214
+ | Mode | Install command | Dependencies |
215
+ | :------------- | :------------------------------------------ | :--------------------- |
216
+ | Headless core | `pip install network-sandbox-engine` | `scapy` |
217
+ | With CLI runner | `pip install "network-sandbox-engine[cli]"` | + `pydantic`, `pyyaml` |
218
+
219
+ The GUI daemon is not distributed via PyPI. It is run from a repository clone.
220
+
221
+ ### Building Release Artifacts
222
+
223
+ ```bash
224
+ make release
225
+ ```
226
+
227
+ This target performs the following steps:
228
+
229
+ 1. Runs `make lint` and `make test`; fails on any error.
230
+ 2. Builds `.whl` and `.tar.gz` with `python -m build`.
231
+ 3. Copies `Dockerfile` and `scripts/nse.service` into `release/`.
232
+ 4. Generates `SHA256SUMS`.
233
+ 5. Signs `SHA256SUMS` with GPG, producing `SHA256SUMS.asc`. The signing key is auto-detected from the keyring; it can be overridden with `GPG_KEY_ID=<id>`.
234
+
235
+ Output in `release/`:
236
+
237
+ ```
238
+ release/
239
+ |-- network_sandbox_engine-1.0.0-py3-none-any.whl
240
+ |-- network_sandbox_engine-1.0.0.tar.gz
241
+ |-- Dockerfile
242
+ |-- nse.service
243
+ |-- SHA256SUMS
244
+ `-- SHA256SUMS.asc
245
+ ```
246
+
247
+ ### Native Installation with Systemd
248
+
249
+ ```bash
250
+ sudo pip install release/network_sandbox_engine-1.0.0-py3-none-any.whl
251
+ sudo cp release/nse.service /etc/systemd/system/
252
+ sudo systemctl daemon-reload && sudo systemctl enable --now nse
253
+ ```
254
+
255
+ ### Docker
256
+
257
+ ```bash
258
+ docker build -t nse -f release/Dockerfile .
259
+ docker run --privileged -p 8000:8000 -d --name nse-container nse
260
+ ```
261
+
262
+ ---
263
+
264
+ ## License
265
+
266
+ MIT. See [LICENSE](LICENSE).