Server Hardening Audit - sshd, nginx, Docker, Kubernetes
Pricing
from $28.00 / 1,000 config auditeds
Server Hardening Audit - sshd, nginx, Docker, Kubernetes
Audit server and container configs against hardening baselines. 9 formats, 74 checks. Catches insecure implicit defaults other linters miss. No network access - analyses only the text you supply.
Pricing
from $28.00 / 1,000 config auditeds
Rating
0.0
(0)
Developer
John J. K. Omolo
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Server Hardening Audit — sshd, nginx, Docker, ufw
Paste a config file. Get back every hardening failure, ranked by severity, with the exact line to change.
Built for the moment an AI coding agent has just written an sshd_config, a Dockerfile or a docker-compose.yml and nobody has checked whether it is safe to deploy. One call in, a graded finding list out.
No network access. No scanning. This Actor reads only the text you pass it. It never connects to a host, never probes a port and never touches a machine you do not control. That is a deliberate design choice, not a missing feature.
Why this is not another linter
Most config checkers grade what is written in the file. That means an empty sshd_config scores 100% — while the daemon it describes is quietly accepting password logins from the entire internet.
This Actor evaluates implicit defaults. When a directive is absent, it is checked against the value the daemon actually uses, and the finding is tagged source: implicit-default so you can tell the two apart.
Three examples of what that catches:
| Finding | Why other tools miss it |
|---|---|
ClientAliveInterval absent | Defaults to 0 — the session never times out |
PermitRootLogin absent | Defaults to prohibit-password — key-based root login is still open |
add_header inside a location block | nginx does not merge headers across scopes. One add_header in a nested block silently discards every security header set at server or http level. Config looks right, headers ship missing. |
Supported formats
Auto-detected from the content — you do not need to say which is which.
sshd_config— 20 checks. Correctly models sshd's first-value-wins precedence and flagsMatchblocks that re-enable password auth or root login.nginx.conf— 10 checks. TLS versions, cipher suites (understands OpenSSL!exclusion syntax), security headers, header-inheritance footgun.Dockerfile— 7 checks. Root execution, floating tags, secrets baked into layers,curl | sh, remoteADD.docker-compose.yml— 9 checks.privileged, Docker socket mounts, host namespaces, capabilities, datastore ports published to0.0.0.0.ufw status verbose— 4 checks. Default policy, exposed datastore ports, unlimited SSH.
Input
Single file:
{"configText": "PermitRootLogin yes\nPasswordAuthentication yes\n"}
Batch — one run, one call, billed per config:
{"configs": [{ "name": "web-01 sshd", "content": "..." },{ "name": "web-01 nginx", "content": "..." },{ "name": "api compose", "content": "..." }],"minSeverity": "medium"}
Output
One dataset item per config:
{"name": "web-01 sshd","config_type": "sshd","score": 43,"grade": "D","counts": { "critical": 1, "high": 2, "medium": 3, "low": 1, "info": 0 },"findings": [{"rule_id": "SSH-001","title": "Root login over SSH","severity": "critical","status": "fail","source": "explicit","line": 2,"observed": "yes","rationale": "Direct root login removes per-user accountability...","fix": "PermitRootLogin no","ref": "CIS Distribution Independent Linux 5.2"}]}
A SUMMARY record in the key-value store aggregates the run: average score, total counts, and the top ten critical and high findings across every config as priority_actions.
Scoring: starts at 100, minus 25 per critical, 12 per high, 5 per medium, 2 per low. Info findings cost nothing. A → 90+, B → 75+, C → 60+, D → 40+, F below.
Redaction
Detected credentials are never echoed back. A hardcoded password is reported as POSTGRES_PASSWORD=<redacted, 18 chars> — enough to locate it, not enough to leak it into your logs, your dataset or your agent's context window.
Calling it from an agent
Available through the Apify MCP server, so Claude, Cursor and any MCP-speaking client can call it as a tool. Ask it to audit a config and it will route here.
Pricing
Billed per config audited, not per run. Batch as many files as you like into a single call — the batch costs the same as running them separately, but finishes in one round trip.
Limits and honest caveats
- 512 KB per config.
nginxparsing handlesincludedirectives as opaque — files you do not paste are not analysed.- This grades configuration. It says nothing about unpatched packages, running processes or kernel version.
- A clean score means the config passes these checks. It is not a certification, and it is not a substitute for a penetration test.
SSH-017reports a non-default SSH port as informational only. Moving the port reduces log noise from untargeted scanners; it is not a security control and is scored as zero.
Local use
pip install -r requirements.txtpython -m src.main path/to/sshd_config path/to/docker-compose.yml
Prints the same JSON structure to stdout, no Apify account needed.