How sam-raiden/rootcodesnmap works
Purpose and Entry Points
This repository is an asynchronous FastAPI microservice that exposes Nmap network scanning as a JSON API. The application entry point is app/main.py, typically served as uvicorn app.main:app. Its public control surface is defined in app/api/scan.py: POST /scan/network, plus health and version endpoints.
API and Schema Boundary
Request and response contracts isolate HTTP concerns from scanning internals. app/schemas/request.py defines the Pydantic scan request model and validator bindings; app/schemas/response.py defines the standardized scanner response, host, and port shapes. Route handlers in app/api/scan.py convert validated requests into service calls and map execution/parsing failures to HTTP responses.
Input Security Gate
Validation is the primary trust boundary before any subprocess invocation. app/utils/validator.py validates targets, CIDR/hostname forms, ports and scan types, and rejects CLI-injection-shaped input. Runtime policy such as scan timeout, allowed scan types, port bounds, and logging settings is centralized in app/config.py.
Command Construction
app/services/command_builder.py translates a validated ScanRequest into an argument vector for Nmap rather than composing a shell command. It selects scan flags, optional service and OS detection, port parameters, and XML-to-stdout output (-oX -). This preserves a strict boundary between user data and executable arguments.
Scan Execution Runtime
app/services/executor.py runs Nmap asynchronously through asyncio.create_subprocess_exec, captures stdout/stderr, and enforces configured timeouts. Nmap is an external host/container dependency and must be available on PATH. The executor returns raw scan output for parsing while surfacing timeout or process failures to the API layer.
XML Parsing and Response Formatting
The scan result pipeline is: Nmap XML stdout → structured host/port data → platform JSON response. app/services/parser.py uses lxml.etree to extract host status, address, hostname, OS guesses, and service/version information. app/services/formatter.py converts those parsed structures into the response schema, including scan duration and scanner identity.
Deployment and Privilege Boundary
The service is containerized by Dockerfile and runnable through docker-compose.yml. Nmap SYN scans and OS detection require raw sockets; the documented deployment model runs the container as root with narrowly granted NET_RAW and NET_ADMIN capabilities, not full privileged mode. The API server is therefore an execution boundary that should only be exposed to callers authorized to initiate network scans.
Observability and Verification
Application logging is provided through app/utils/logger.py, with output intended for container stdout. The architecture is verified at its major boundaries: request/API behavior, command safety, XML interpretation, and validation in tests/test_api.py, tests/test_command_builder.py, tests/test_parser.py, and tests/test_validator.py.
Main entry points: scan.py Scan routes · executor.py Async executor · command_builder.py Command builder · Dockerfile Container deployment
Components 15
HTTP API
- FastAPI app
app/main.py - Scan routes · Provides POST /scan/network plus health and version endpoints.
app/api/scan.py - Scan request
app/schemas/request.py - Input validator · Rejects invalid targets, ports, scan types, and injection-shaped input.
app/utils/validator.py - Runtime policy · Centralizes timeouts, allowed scan types, port bounds, and logging settings.
app/config.py - Scanner response
app/schemas/response.py - Application logging · Writes application logs to container stdout.
app/utils/logger.py
Scan pipeline
- Command builder · Builds an Nmap argument vector without a shell.
app/services/command_builder.py - Async executor · Runs Nmap, captures output, and enforces timeouts.
app/services/executor.py - Nmap · Must be available on PATH and emits XML to stdout.
- XML parser · Extracts hosts, ports, services, OS guesses, and status from Nmap XML.
app/services/parser.py - Response formatter · Adds scan duration and scanner identity to parsed results.
app/services/formatter.py
Deployment
- Container deployment · Runs with NET_RAW and NET_ADMIN capabilities rather than full privileged mode.
Dockerfile - Compose runtime
docker-compose.yml
Other components
- Authorized caller · Initiates network scans through the API.
Connections 19
- Authorized caller → FastAPI app: HTTP requests
- FastAPI app → Scan routes: registers
- Scan routes → Scan request: validates request
- Scan request → Input validator: validator bindings
- Scan routes → Runtime policy: reads policy
- Scan routes → Command builder: submits validated scan
- Command builder → Runtime policy: uses scan policy
- Command builder → Async executor: argument vector
- Async executor → Runtime policy: uses timeout
- Async executor → Nmap: executes
- Nmap → Async executor: XML stdout and stderr
- Async executor → XML parser: raw XML
- XML parser → Response formatter: structured scan data
- Response formatter → Scanner response: formats
- Scanner response → Scan routes: HTTP JSON
- Scan routes → Application logging: logs outcomes
- Compose runtime → Container deployment: runs
- Container deployment → FastAPI app: serves application
- Container deployment → Nmap: provides binary and capabilities