A homelab-focused Docker container security auditor.
DocSec connects to a Docker instance via the Docker Engine API, enumerates running containers and images, detects common misconfigurations derived from the container security literature, checks for known CVEs via the OSV vulnerability database, and presents findings through a web-based dashboard. It supports both local Docker connections and secure remote connections to any Docker host on your network.
- Go 1.21 or newer (
go versionto check) - Docker running locally or accessible on your network
- Internet access during the scan (OSV CVE API at
osv.dev) curlfor downloading frontend assets
# Clone the repository
git clone https://github.com/RaptorCentauri/docsec
cd docsec
# Download vendored frontend assets (required before building)
curl -o assets/static/tailwind.min.css https://cdn.tailwindcss.com/3.4.1
curl -o assets/static/alpine.min.js https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js
# Fetch Go dependencies
go mod tidy
# Build the binary
go build -o docsec ../docsec --helpConnects to the Docker daemon on the same machine via the Unix socket.
# Start dashboard only (run a scan from the UI)
./docsec
# Run a scan on startup, then serve the dashboard
./docsec --scan
# Custom port
./docsec --port 9090
# Custom database path
./docsec --db /path/to/docsec.dbOpen http://localhost:8080 in your browser.
Connects to a remote Docker host over plain TCP. The Docker daemon on the remote host must be configured to accept TCP connections on port 2375.
Security warning: The unencrypted TCP API has no authentication. Anyone on your network can control the Docker daemon. Only use this on a trusted local network, and prefer TLS (see below).
./docsec --host tcp://192.168.1.50:2375 --scanEnabling the TCP API on the remote host (Linux):
Create or edit /etc/systemd/system/docker.service.d/override.conf:
[Service]
ExecStart=
ExecStart=/usr/bin/dockerdThen add to /etc/docker/daemon.json:
{
"hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2375"]
}Reload and restart:
systemctl daemon-reload
systemctl restart dockerConnects to a remote Docker host over TCP with mutual TLS authentication. Only clients with a valid certificate signed by your CA can connect. This is the recommended approach for multi-host homelab scanning.
./docsec \
--host tcp://192.168.1.50:2376 \
--tlsverify \
--tlscacert ~/.docker/certs/ca.pem \
--tlscert ~/.docker/certs/client-cert.pem \
--tlskey ~/.docker/certs/client-key.pem \
--scanYou need three certificate files on your client machine:
| File | Purpose |
|---|---|
ca.pem |
Certificate Authority — verifies the server |
client-cert.pem |
Client certificate — identifies your client |
client-key.pem |
Client private key — signs your client cert |
Run the following on the remote Docker host (requires openssl):
mkdir -p ~/.docker/certs && cd ~/.docker/certs
# 1. Generate the Certificate Authority
openssl genrsa -out ca-key.pem 4096
openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem -subj "/CN=docsec-ca"
# 2. Generate the server certificate (replace with your server's IP)
openssl genrsa -out server-key.pem 4096
openssl req -subj "/CN=192.168.1.50" -sha256 -new -key server-key.pem -out server.csr
echo subjectAltName = IP:192.168.1.50,IP:127.0.0.1 > extfile.cnf
openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile extfile.cnf
# 3. Generate the client certificate
openssl genrsa -out client-key.pem 4096
openssl req -subj '/CN=client' -new -key client-key.pem -out client.csr
echo extendedKeyUsage = clientAuth > extfile-client.cnf
openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem -extfile extfile-client.cnfCopy ca.pem, client-cert.pem, and client-key.pem to your client machine:
# Run from your client machine
mkdir -p ~/.docker/docsec-certs
scp -O [email protected]:~/.docker/certs/ca.pem ~/.docker/docsec-certs/
scp -O [email protected]:~/.docker/certs/client-cert.pem ~/.docker/docsec-certs/
scp -O [email protected]:~/.docker/certs/client-key.pem ~/.docker/docsec-certs/On the remote host, create /etc/systemd/system/docker.service.d/override.conf:
[Service]
ExecStart=
ExecStart=/usr/bin/dockerdAdd to /etc/docker/daemon.json (replace IP with your server's IP):
{
"tlsverify": true,
"tlscacert": "/root/.docker/certs/ca.pem",
"tlscert": "/root/.docker/certs/server-cert.pem",
"tlskey": "/root/.docker/certs/server-key.pem",
"hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2376"]
}Reload and restart:
systemctl daemon-reload
systemctl restart dockerVerify TLS is working from your client machine:
curl --tlsv1.2 \
--cacert ~/.docker/docsec-certs/ca.pem \
--cert ~/.docker/docsec-certs/client-cert.pem \
--key ~/.docker/docsec-certs/client-key.pem \
https://192.168.1.50:2376/versionCreate ~/.docsec/config.toml for persistent settings:
[docker]
host = "tcp://192.168.1.50:2376"
tls_verify = true
tls_ca_cert = "/home/user/.docker/docsec-certs/ca.pem"
tls_cert = "/home/user/.docker/docsec-certs/client-cert.pem"
tls_key = "/home/user/.docker/docsec-certs/client-key.pem"
[server]
port = 8080
[database]
path = "~/.docsec/docsec.db"
[scan]
enabled_checks = [
"MC-001", "MC-002", "MC-003", "MC-004",
"MC-005", "MC-006", "MC-007", "MC-008"
]CLI flags override config file values. Config file values override built-in defaults.
| Flag | Default | Description |
|---|---|---|
--host |
unix:///var/run/docker.sock |
Docker host URI |
--port |
8080 |
Dashboard port |
--db |
~/.docsec/docsec.db |
Database path |
--config |
~/.docsec/config.toml |
Config file path |
--scan |
false |
Run scan on startup |
--tlsverify |
false |
Enable TLS for remote connection |
--tlscacert |
— | Path to CA certificate |
--tlscert |
— | Path to client certificate |
--tlskey |
— | Path to client private key |
| ID | Check | Severity | Literature Source |
|---|---|---|---|
| MC-001 | Privileged mode enabled | CRITICAL | De Giorgi (2022), Mahajan & Mane (2022) |
| MC-002 | Docker socket mounted | CRITICAL | De Giorgi (2022), Rajyashree et al. (2024) |
| MC-003 | Container running as root | HIGH | De Giorgi (2022), Ahamed et al. (2021) |
| MC-004 | Excessive Linux capabilities | HIGH | De Giorgi (2022) |
| MC-005 | Sensitive ports exposed | MEDIUM | De Giorgi (2022) |
| MC-006 | No CPU resource limit | MEDIUM | De Giorgi (2022), Ahamed et al. (2021) |
| MC-007 | No memory resource limit | MEDIUM | De Giorgi (2022), Ahamed et al. (2021) |
| MC-008 | Unpinned image tag | LOW | De Giorgi (2022) |
docsec/
├── main.go # Entry point, wires components together
├── embed.go # Embeds assets/ directory into binary
├── internal/
│ ├── config/ # TOML + CLI flag configuration
│ ├── docker/ # Docker Engine API client (local + TLS remote)
│ ├── scanner/
│ │ ├── scanner.go # Scan orchestration
│ │ ├── misconfig/ # 8 misconfiguration check implementations
│ │ └── cve/ # CVE provider interface + OSV implementation
│ ├── db/ # SQLite persistence layer
│ └── web/ # HTTP server, handlers, templates
├── assets/
│ ├── templates/ # Go HTML templates (embedded in binary)
│ └── static/ # Alpine.js, Tailwind CSS (embedded in binary)
└── scripts/
└── testenv/ # Intentionally misconfigured test environment
Single binary. All assets are embedded at compile time via Go's embed package. No runtime filesystem dependencies — download and run.
Not containerized. DocSec requires access to /var/run/docker.sock. Running it as a Docker container would require mounting the socket, which is itself MC-002 — a critical misconfiguration DocSec is designed to detect.
TLS for remote connections. Remote Docker connections use mutual TLS on port 2376. Both client and server must present certificates signed by the same CA, preventing unauthorized access to the Docker API.
CVE provider pattern. CVE sources implement a common Provider interface. OSV is the default. Additional sources (NVD, GitHub Advisory) can be added by implementing the interface without modifying the scanner.
go test ./...Tests use in-memory SQLite and do not require a live Docker connection.
A Docker Compose file with intentionally misconfigured containers is provided:
cd scripts/testenv
docker compose up -d
cd ../..
./docsec --scanCVE data is sourced from OSV (Open Source Vulnerabilities), maintained by Google. OSV aggregates from NVD, GitHub Advisory, and 15+ ecosystem-specific sources. No API key is required.
The dashboard provides a JSON export of the most recent scan. Click Export JSON on the overview page, or access it directly at http://localhost:8080/export.
DocSec was developed as part of a research project examining container security in homelab and small-team environments. The tool demonstrates that a lightweight, accessible auditor built around the Docker API can surface critical vulnerabilities and misconfigurations without the overhead of enterprise tooling.