Rootless (or Almost) Network Scans in Containers
Fix raw-socket "Operation not permitted" without --privileged
Least-privilege setup for running Nmap, MASSCAN, or ZMap inside Docker/Podman/Kubernetes. Solves "requires root privileges" and "Operation not permitted" failures without reaching for --privileged. Includes fallbacks when raw sockets are unavailable.
INGREDIENTS
PROMPT
Create a skill called "Rootless Scanner Runner". Inputs I will provide: - Target scope (CIDRs/hosts) - Allowed scan types (SYN vs TCP connect), and whether I'm allowed to run containers with NET_RAW/NET_ADMIN - Output directory path Task: 1) Decide whether raw sockets are required for my goal. 2) Generate the safest commands that meet the goal: - Prefer TCP connect (`nmap -sT`) when acceptable. - Use least-privilege caps (`--cap-add=NET_RAW` and only add `NET_ADMIN` if needed). - Always set conservative rate limits for high-speed tools. 3) Provide troubleshooting paths for the most common errors (Operation not permitted, requires root). 4) Output should include: commands to run, expected outputs, and a short "audit note" summarizing why these caps were required.
What this fixes
Many high-value scan modes (SYN scanning, OS detection, packet-capture workflows)
require raw sockets or interface capabilities. In hardened container runtimes those
capabilities are commonly dropped, so tools fail even when you are "root" inside the
container.
This recipe gives you a decision tree:
- Prefer least privilege — grant NET_RAW/NET_ADMIN only when needed
- Fallback to connect()-based scans (TCP connect, HTTP probing) when raw sockets
are unavailable
- Document which capabilities were required, for auditability
Prerequisites
- Written authorization and an explicit target scope (CIDRs/hosts)
- Docker or Podman installed on the scanning host
- A container image that includes your scanner(s) (or bind-mount binaries)
- If using Linux file capabilities: `libcap2-bin` / `setcap` available
Steps and commands
- Decide if you truly need raw sockets.
- Only need open TCP ports from the current host → start with TCP connect scanning.
- Need SYN scans, OS detection, or packet crafting → you need raw sockets/caps.
- Run Nmap with least-privilege capabilities (Docker):
- Minimal caps for most raw scans:
`docker run --rm -it --cap-add=NET_RAW --cap-add=NET_ADMIN instrumentisto/nmap -sS -Pn -n -p 1-1000
- If your environment forbids NET_ADMIN, use a non-raw fallback:
`docker run --rm -it instrumentisto/nmap -sT -Pn -n -p 1-1000
- Run MASSCAN/ZMap with explicit rate limits and the same capability pattern:
- MASSCAN (discovery only; follow with verification):
`docker run --rm -it --cap-add=NET_RAW --cap-add=NET_ADMIN -v "$PWD/out:/out" kalilinux/kali-rolling bash -lc "apt-get update && apt-get install -y masscan && masscan
- If a distro sets file capabilities that break in containers, reduce them during image build:
- Inspect:
`getcap -r /usr/lib/nmap/nmap /usr/bin/nmap 2>/dev/null || true`
- Reduce to what's needed:
`setcap cap_net_raw,cap_net_bind_service+eip /usr/lib/nmap/nmap`
- Document your final choice:
- Capabilities granted (NET_RAW / NET_ADMIN / none)
- Scan mode used (-sS vs -sT)
- Rate limit and timing settings
Expected outputs
- Successful Nmap run prints discovered hosts/ports and (optionally) service/version info.
- MASSCAN outputs a JSON/XML/grepable file you can post-process and verify.
Common errors and troubleshooting
- "Couldn't open a raw socket. Error: Operation not permitted"
- Container lacks CAP_NET_RAW and/or CAP_NET_ADMIN.
- Add `--cap-add=NET_RAW` (and sometimes `--cap-add=NET_ADMIN`) or switch to `nmap -sT`.
- "You requested a scan type which requires root privileges"
- You selected a scan mode that requires raw sockets (e.g., SYN scan `-sS`).
- Use `sudo` on bare metal, set file caps on the binary, or switch to `-sT`.
- Kali container: `nmap -v` fails with "Operation not permitted"
- Some builds set `cap_net_admin` on the binary; containers without NET_ADMIN will fail.
- Reduce file capabilities to only what you need (Step 4) or add NET_ADMIN.
- Rootless Docker/Podman
- Rootless mode restricts adding some capabilities.
- Use a rootful runtime for the scanner container or run scans on the host.
References
- https://nmap.org/book/man-misc-options.html
- https://man7.org/linux/man-pages/man7/capabilities.7.html
- https://bugs.kali.org/view.php?id=9085
- https://serverfault.com/questions/1056213/run-nmap-in-a-docker-container-as-a-non-admin-user
- https://github.com/zmap/zmap/issues/781
Example inputs
- `
`: 10.10.10.10 - `
`: 10.10.0.0/16 - Ports: `1-1000` or `80,443,8080`