Linux Config Auditor
Overview
Audits any Linux configuration file against security best practices, performance recommendations, and common compliance baselines (CIS, STIG-inspired). Outputs a structured findings report with severity ratings, explanations, and ready-to-apply fix snippets.
Language: Respond in the user's language. Config snippets always use the native config syntax.
When to Use
- User pastes or references a config file and wants it reviewed
- User asks "is my nginx config secure?", "check my sshd_config", "audit my firewall rules"
- User wants hardening recommendations for a specific service
- User wants to know why a service behaves unexpectedly (misconfiguration hunt)
- User asks for CIS benchmark or security best-practice review
When NOT to Use
- User wants a script to automate the fix → use /linux-shell-scriptor
- User wants to generate a config from scratch → generate directly without this skill
- User wants to harden the whole OS (not just one config) → use /linux-security-hardener
Supported Config Types
| Config File / Type |
What Gets Checked |
nginx.conf / vhost |
TLS versions, cipher suites, headers, rate limiting, open redirects, directory listing, worker tuning |
apache2.conf / .htaccess |
ServerTokens, TLS, headers, directory access, mod_security hints |
sshd_config |
PermitRootLogin, PasswordAuth, key algorithms, ciphers, idle timeout, AllowUsers/Groups |
systemd unit (.service, .timer, .socket) |
Sandboxing, privilege escalation, restart policy, resource limits |
iptables / nftables rules |
Default policies, open ports vs. need, stateful rules, loopback, anti-spoofing |
firewalld config |
Active zones, overly permissive services, rich rules |
fail2ban jail config |
Enabled jails, ban time, max retry, action severity |
sudoers / visudo |
NOPASSWD, wildcards, command scope, user/group grants |
sysctl.conf |
Network hardening params, kernel pointer restriction, core dump settings |
/etc/security/limits.conf |
Open file limits, process limits for services |
pg_hba.conf |
Peer/md5/scram auth methods, host access rules, trust entries |
mysql/my.cnf |
bind-address, skip-networking, max_connections, log_error, SSL settings |
redis.conf |
requirepass, bind, protected-mode, ACL, TLS, dangerous commands |
| Generic / unknown |
Best-effort structural review, flag obvious anti-patterns |
Audit Framework
Run findings through three lenses in order:
1. Security
Look for settings that increase attack surface, weaken encryption, allow privilege escalation, or violate least-privilege.
2. Performance
Look for settings that limit throughput, cause unnecessary latency, misuse resources, or have known bottleneck defaults.
3. Compliance / Best Practice
Check against CIS Benchmark guidance (where applicable), vendor hardening docs, and widely accepted defaults.
Output Format
Structure every audit as follows:
Summary Header
Config: <filename or type>
Findings: X critical · Y warnings · Z info · N passed
Findings Table
| Severity |
Setting / Line |
Issue |
Fix |
| 🔴 Critical |
PermitRootLogin yes |
Root login allowed over SSH |
Set to no or prohibit-password |
| 🟠 Warning |
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 |
TLS 1.0 and 1.1 are deprecated and vulnerable |
Remove TLS 1.0 and 1.1 |
| 🟡 Info |
worker_processes 1 |
Single worker — consider matching CPU count |
Set worker_processes auto; |
| ✅ OK |
PasswordAuthentication no |
Password auth disabled — good |
— |
Severity scale:
- 🔴 Critical — actively exploitable or violates fundamental security principle
- 🟠 Warning — weakens security posture or common attack vector
- 🟡 Info — performance gap, minor misconfiguration, or style deviation
- ✅ OK — explicitly confirmed as correct, shown for reassurance
What to include in the table:
- 🔴 Critical: always include every finding
- 🟠 Warning: always include every finding
- 🟡 Info: include only if 3 or more items; otherwise merge into summary
- ✅ OK: include 1–2 highlights only (the most important security settings that are correctly configured)
Fixed Config Snippet
After the table, output a corrected config snippet containing only the changed lines with brief inline comments:
# Fixed settings — replace in your config
ssl_protocols TLSv1.2 TLSv1.3; # Remove deprecated TLS 1.0/1.1
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
worker_processes auto;
Next Steps
Always close with:
Apply fixes: Review each change before applying — test in staging first
Full script: Use /linux-shell-scriptor to automate applying these changes
OS hardening: Use /linux-security-hardener for a full system-level review
Monitor: Use /linux-monitoring-setup to detect anomalies after reconfiguring
File Output
Write findings to ./audit/ in the current working directory:
audit/
report-<type>-<YYYY-MM-DD>.md ← full findings report
fixed-<filename> ← corrected config (changed lines only)
Print the findings table and corrected snippet directly in chat — they are concise and immediately useful. The full written report is for archiving and diffing over time.
Nginx-Specific Rules
Check all of the following when auditing any nginx config:
| Check |
Secure Value |
| TLS protocols |
TLSv1.2 TLSv1.3 only |
| TLS ciphers |
ECDHE + AES-GCM / CHACHA20 only; no RC4, DES, MD5, EXPORT |
| HSTS header |
Strict-Transport-Security with max-age ≥ 15768000 and includeSubDomains; add preload to register on the HSTS preload list |
server_tokens |
off |
X-Frame-Options |
SAMEORIGIN or DENY |
X-Content-Type-Options |
nosniff |
Content-Security-Policy |
Present (warn if missing) |
client_max_body_size |
Set explicitly (not unlimited) |
autoindex |
off |
worker_processes |
auto or matches CPU count |
keepalive_timeout |
65 or lower |
| Rate limiting |
limit_req_zone defined for public endpoints |
| Default server |
Catch-all returning 444 for unknown hostnames |
SSH-Specific Rules
| Check |
Secure Value |
PermitRootLogin |
no or prohibit-password |
PasswordAuthentication |
no |
PermitEmptyPasswords |
no |
PubkeyAuthentication |
yes |
X11Forwarding |
no |
AllowTcpForwarding |
no (unless needed) |
ClientAliveInterval |
300 or less |
ClientAliveCountMax |
2 or less |
MaxAuthTries |
4 or less |
LoginGraceTime |
30 or less |
Ciphers |
Only modern ciphers (no arcfour, blowfish, 3des) |
MACs |
Only SHA-2 MACs (no md5, sha1) |
AllowUsers / AllowGroups |
Defined to restrict access |
Port |
Non-default (advisory only) |
Systemd Unit Rules
| Check |
Recommendation |
NoNewPrivileges=yes |
Always set for non-root services |
PrivateTmp=yes |
Isolate /tmp access |
ProtectSystem=strict |
Prevent writes to system dirs |
ProtectHome=yes |
Block home directory access |
ReadOnlyPaths= |
Restrict filesystem to minimum needed |
CapabilityBoundingSet= |
Drop all capabilities not needed |
Restart= |
Set to on-failure for critical services |
RestartSec= |
Use with Restart= to avoid rapid respawn |
User= / Group= |
Never run as root unless absolutely required |
LimitNOFILE= |
Set for services that open many connections |
TimeoutStopSec= |
Set to avoid zombie services on shutdown |
Iptables / Nftables Rules
| Check |
Expected |
| Default INPUT policy |
DROP or REJECT |
| Default FORWARD policy |
DROP (unless routing) |
| Default OUTPUT policy |
ACCEPT (or DROP with explicit rules) |
| Loopback accepted |
ACCEPT for lo interface |
| Established/related |
ACCEPT for ESTABLISHED,RELATED |
| ICMP |
Limited — accept echo-request, drop rest |
| Anti-spoofing |
Drop packets from localhost arriving on external interface |
| Open ports |
Flag any port open that isn't clearly needed |
| Logging |
At least one LOG rule before the final DROP |
Security Checklist Reminders
Flag these patterns in any config type as 🔴 Critical:
- Hardcoded passwords, API keys, or tokens in config values
- World-readable permissions on config files with secrets (
chmod 644 on /etc/ssl/private/)
NOPASSWD: ALL in sudoers
- Wildcard (
*) in AllowUsers or command grants
- Empty or commented-out authentication requirements
Sudoers-specific critical patterns:
Cmnd_Alias containing /usr/bin/bash, /bin/sh, /bin/bash, sudoedit, su → shell escape for full root
%group ALL=(ALL) NOPASSWD: ALL on a broad group (e.g. %wheel, %sudo, %docker) → unrestricted group sudo
ALL=(ALL:ALL) NOPASSWD: /path/to/script * with wildcard arguments → argument injection
visudo not being used to edit sudoers (syntax errors in sudoers can lock out all sudo access)
1---2name: linux-config-auditor3description: Use when user wants to audit, review, analyze, or improve a Linux config file — nginx, Apache, sshd_config, systemd service/timer/socket units, iptables, nftables, firewalld, fail2ban, sudoers, /etc/security/limits.conf, sysctl.conf, or any server config — for security issues, misconfigurations, performance problems, or compliance gaps.4---56# Linux Config Auditor78## Overview910Audits any Linux configuration file against security best practices, performance recommendations, and common compliance baselines (CIS, STIG-inspired). Outputs a structured findings report with severity ratings, explanations, and ready-to-apply fix snippets.1112**Language:** Respond in the user's language. Config snippets always use the native config syntax.1314---1516## When to Use1718- User pastes or references a config file and wants it reviewed19- User asks "is my nginx config secure?", "check my sshd_config", "audit my firewall rules"20- User wants hardening recommendations for a specific service21- User wants to know why a service behaves unexpectedly (misconfiguration hunt)22- User asks for CIS benchmark or security best-practice review2324## When NOT to Use2526- User wants a script to automate the fix → use /linux-shell-scriptor27- User wants to generate a config from scratch → generate directly without this skill28- User wants to harden the whole OS (not just one config) → use /linux-security-hardener2930---3132## Supported Config Types3334| Config File / Type | What Gets Checked |35|-------------------|-------------------|36| `nginx.conf` / vhost | TLS versions, cipher suites, headers, rate limiting, open redirects, directory listing, worker tuning |37| `apache2.conf` / `.htaccess` | ServerTokens, TLS, headers, directory access, mod_security hints |38| `sshd_config` | PermitRootLogin, PasswordAuth, key algorithms, ciphers, idle timeout, AllowUsers/Groups |39| `systemd` unit (`.service`, `.timer`, `.socket`) | Sandboxing, privilege escalation, restart policy, resource limits |40| `iptables` / `nftables` rules | Default policies, open ports vs. need, stateful rules, loopback, anti-spoofing |41| `firewalld` config | Active zones, overly permissive services, rich rules |42| `fail2ban` jail config | Enabled jails, ban time, max retry, action severity |43| `sudoers` / `visudo` | NOPASSWD, wildcards, command scope, user/group grants |44| `sysctl.conf` | Network hardening params, kernel pointer restriction, core dump settings |45| `/etc/security/limits.conf` | Open file limits, process limits for services |46| `pg_hba.conf` | Peer/md5/scram auth methods, host access rules, trust entries |47| `mysql/my.cnf` | bind-address, skip-networking, max_connections, log_error, SSL settings |48| `redis.conf` | requirepass, bind, protected-mode, ACL, TLS, dangerous commands |49| Generic / unknown | Best-effort structural review, flag obvious anti-patterns |5051---5253## Audit Framework5455Run findings through three lenses in order:5657### 1. Security58Look for settings that increase attack surface, weaken encryption, allow privilege escalation, or violate least-privilege.5960### 2. Performance61Look for settings that limit throughput, cause unnecessary latency, misuse resources, or have known bottleneck defaults.6263### 3. Compliance / Best Practice64Check against CIS Benchmark guidance (where applicable), vendor hardening docs, and widely accepted defaults.6566---6768## Output Format6970Structure every audit as follows:7172### Summary Header73```74Config: <filename or type>75Findings: X critical · Y warnings · Z info · N passed76```7778### Findings Table7980| Severity | Setting / Line | Issue | Fix |81|----------|---------------|-------|-----|82| 🔴 Critical | `PermitRootLogin yes` | Root login allowed over SSH | Set to `no` or `prohibit-password` |83| 🟠 Warning | `ssl_protocols TLSv1 TLSv1.1 TLSv1.2` | TLS 1.0 and 1.1 are deprecated and vulnerable | Remove TLS 1.0 and 1.1 |84| 🟡 Info | `worker_processes 1` | Single worker — consider matching CPU count | Set `worker_processes auto;` |85| ✅ OK | `PasswordAuthentication no` | Password auth disabled — good | — |8687Severity scale:88- 🔴 **Critical** — actively exploitable or violates fundamental security principle89- 🟠 **Warning** — weakens security posture or common attack vector90- 🟡 **Info** — performance gap, minor misconfiguration, or style deviation91- ✅ **OK** — explicitly confirmed as correct, shown for reassurance9293**What to include in the table:**94- 🔴 Critical: always include every finding95- 🟠 Warning: always include every finding96- 🟡 Info: include only if 3 or more items; otherwise merge into summary97- ✅ OK: include 1–2 highlights only (the most important security settings that are correctly configured)9899### Fixed Config Snippet100101After the table, output a corrected config snippet containing **only the changed lines** with brief inline comments:102103```nginx104# Fixed settings — replace in your config105ssl_protocols TLSv1.2 TLSv1.3; # Remove deprecated TLS 1.0/1.1106ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';107add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;108worker_processes auto;109```110111### Next Steps112113Always close with:114> **Apply fixes:** Review each change before applying — test in staging first115> **Full script:** Use `/linux-shell-scriptor` to automate applying these changes116> **OS hardening:** Use `/linux-security-hardener` for a full system-level review117> **Monitor:** Use `/linux-monitoring-setup` to detect anomalies after reconfiguring118119---120121## File Output122123Write findings to `./audit/` in the current working directory:124125```126audit/127 report-<type>-<YYYY-MM-DD>.md ← full findings report128 fixed-<filename> ← corrected config (changed lines only)129```130131Print the findings table and corrected snippet **directly in chat** — they are concise and immediately useful. The full written report is for archiving and diffing over time.132133---134135## Nginx-Specific Rules136137Check all of the following when auditing any nginx config:138139| Check | Secure Value |140|-------|-------------|141| TLS protocols | `TLSv1.2 TLSv1.3` only |142| TLS ciphers | ECDHE + AES-GCM / CHACHA20 only; no RC4, DES, MD5, EXPORT |143| HSTS header | `Strict-Transport-Security` with `max-age` ≥ 15768000 and `includeSubDomains`; add `preload` to register on the HSTS preload list |144| `server_tokens` | `off` |145| `X-Frame-Options` | `SAMEORIGIN` or `DENY` |146| `X-Content-Type-Options` | `nosniff` |147| `Content-Security-Policy` | Present (warn if missing) |148| `client_max_body_size` | Set explicitly (not unlimited) |149| `autoindex` | `off` |150| `worker_processes` | `auto` or matches CPU count |151| `keepalive_timeout` | 65 or lower |152| Rate limiting | `limit_req_zone` defined for public endpoints |153| Default server | Catch-all returning 444 for unknown hostnames |154155---156157## SSH-Specific Rules158159| Check | Secure Value |160|-------|-------------|161| `PermitRootLogin` | `no` or `prohibit-password` |162| `PasswordAuthentication` | `no` |163| `PermitEmptyPasswords` | `no` |164| `PubkeyAuthentication` | `yes` |165| `X11Forwarding` | `no` |166| `AllowTcpForwarding` | `no` (unless needed) |167| `ClientAliveInterval` | 300 or less |168| `ClientAliveCountMax` | 2 or less |169| `MaxAuthTries` | 4 or less |170| `LoginGraceTime` | 30 or less |171| `Ciphers` | Only modern ciphers (no arcfour, blowfish, 3des) |172| `MACs` | Only SHA-2 MACs (no md5, sha1) |173| `AllowUsers` / `AllowGroups` | Defined to restrict access |174| `Port` | Non-default (advisory only) |175176---177178## Systemd Unit Rules179180| Check | Recommendation |181|-------|---------------|182| `NoNewPrivileges=yes` | Always set for non-root services |183| `PrivateTmp=yes` | Isolate /tmp access |184| `ProtectSystem=strict` | Prevent writes to system dirs |185| `ProtectHome=yes` | Block home directory access |186| `ReadOnlyPaths=` | Restrict filesystem to minimum needed |187| `CapabilityBoundingSet=` | Drop all capabilities not needed |188| `Restart=` | Set to `on-failure` for critical services |189| `RestartSec=` | Use with `Restart=` to avoid rapid respawn |190| `User=` / `Group=` | Never run as root unless absolutely required |191| `LimitNOFILE=` | Set for services that open many connections |192| `TimeoutStopSec=` | Set to avoid zombie services on shutdown |193194---195196## Iptables / Nftables Rules197198| Check | Expected |199|-------|---------|200| Default INPUT policy | `DROP` or `REJECT` |201| Default FORWARD policy | `DROP` (unless routing) |202| Default OUTPUT policy | `ACCEPT` (or `DROP` with explicit rules) |203| Loopback accepted | `ACCEPT` for `lo` interface |204| Established/related | `ACCEPT` for `ESTABLISHED,RELATED` |205| ICMP | Limited — accept echo-request, drop rest |206| Anti-spoofing | Drop packets from localhost arriving on external interface |207| Open ports | Flag any port open that isn't clearly needed |208| Logging | At least one LOG rule before the final DROP |209210---211212## Security Checklist Reminders213214Flag these patterns in any config type as 🔴 Critical:215216- Hardcoded passwords, API keys, or tokens in config values217- World-readable permissions on config files with secrets (`chmod 644` on `/etc/ssl/private/`)218- `NOPASSWD: ALL` in sudoers219- Wildcard (`*`) in AllowUsers or command grants220- Empty or commented-out authentication requirements221222**Sudoers-specific critical patterns:**223- `Cmnd_Alias` containing `/usr/bin/bash`, `/bin/sh`, `/bin/bash`, `sudoedit`, `su` → shell escape for full root224- `%group ALL=(ALL) NOPASSWD: ALL` on a broad group (e.g. `%wheel`, `%sudo`, `%docker`) → unrestricted group sudo225- `ALL=(ALL:ALL) NOPASSWD: /path/to/script *` with wildcard arguments → argument injection226- `visudo` not being used to edit sudoers (syntax errors in sudoers can lock out all sudo access)