NC-NET-001

Management interfaces not internet-exposed

๐Ÿ”ด Critical ๐Ÿ”Œ Plugin Expanded ๐Ÿ“Š Contributes to expanded score

What this checks

Scans open ports for common management services SSH (22), Docker API (2375/2376), dev/admin servers (4000, 5000), HTTP proxy/admin (8080), HTTPS admin (8443), Jupyter/admin (8888), management consoles (9000), and Prometheus/admin (9090) to check whether they are bound to public interfaces rather than localhost. Management interfaces exposed to the internet are the primary vector for host-level compromise of self-hosted AI setups.

Why it matters

An unauthenticated Docker API on port 2375 gives an attacker full root access to the host. An SSH service with password auth on port 22 is scanned and brute-forced within minutes of exposure. An admin dashboard on port 8080 with no auth is an open door. These are not theoretical risks they are the most common cause of self-hosted server compromise.

How to fix it

SSH (port 22)

Restrict SSH to key-based auth only and consider changing to a non-standard port:

# /etc/ssh/sshd_config
PasswordAuthentication no
PubkeyAuthentication yes
# Optional: change port
Port 2222

Or, if you don't need remote SSH at all:

sudo systemctl stop ssh && sudo systemctl disable ssh   # Linux
sudo systemsetup -setremotelogin off                     # macOS

Docker API (port 2375/2376)

The Docker daemon should never listen on a TCP port unless you have a specific remote management need. Ensure /etc/docker/daemon.json does NOT contain "hosts": ["tcp://0.0.0.0:2375"]. If remote access is needed, use TLS mutual auth (port 2376) or tunnel over SSH instead:

export DOCKER_HOST=ssh://user@remote-host
docker ps   # Docker commands tunnel over SSH no exposed TCP port needed

Admin dashboards and dev servers (ports 8080, 8443, 8888, 9000, 9090, 4000, 5000, etc.)

Bind admin interfaces to localhost, then access via SSH port forwarding if needed remotely:

# Bind to localhost:
./dashboard --host 127.0.0.1 --port 8080

# Access remotely via SSH tunnel:
ssh -L 8080:localhost:8080 user@your-server
# Then open http://localhost:8080 in your browser

Technical details

FieldValue
Control IDNC-NET-001
DomainNETWORK
SeverityCritical
StatusExpanded (Plugin only)
Data sourcelsof -i :<port> -sTCP:LISTEN per port, with ss fallback on Linux
Ports checked22, 2375, 2376, 4000, 5000, 8080, 8443, 8888, 9000, 9090
ModeMode 2 (System-level requires plugin expanded mode)
Introduced inLibrary v0.2.0

False positive notes

SSH on port 22 is flagged only if accessible beyond localhost. If your setup uses a VPN or Tailscale for SSH access (not direct internet exposure), this may be a false positive exclude with a reason.

Suppress this finding

clawvitals exclude NC-NET-001 reason "SSH access via Tailscale only, not internet-exposed"

Custom port list

Add extra ports to scan

NC-NET-001 scans 10 default ports. To scan additional services on non-standard ports, add an extra_ports list to your plugin config. Extra ports are merged with the defaults they do not replace them.

Config file: ~/.openclaw/plugins/clawvitals/config.json

{
  "network": {
    "extra_ports": [
      { "port": 3001, "service": "Slack server" },
      { "port": 8888, "service": "Jupyter notebook" }
    ]
  }
}

After saving the config, run run clawvitals --expanded the extra ports will be included in the scan.