I'm a sysadmin / DevOps with little specific experience on server hardening. Can I use this tool?
Yes. For each finding you get a problem description in operational language and copy-paste-ready remediation for the config. The tool's logic mirrors that of the official tools (Mozilla SSL Configurator, OWASP Secure Headers Project): the same checks a cyber expert would run, automated. For aspects the linter does not cover (cert near expiry, intermediate certificate validation, runtime monitoring) use SSLLabs and Mozilla Observatory in parallel.
What does AST-based mean and why is it better than a regex linter?
AST = Abstract Syntax Tree: the config is parsed into a tree of blocks and directives with precise scope. The linter knows that add_header X-Frame-Options DENY inside location /admin does NOT apply to the rest of the site. A regex linter would see the string X-Frame-Options anywhere in the text and say "present". That false negative has practical consequences: the header is formally there but is not emitted on the responses it was meant to protect. Same reasoning for HSTS, CSP, and the Nginx add_header override rule.
Can I test a .htaccess or do I need the full VirtualHost?
Both work. A .htaccess is a partial Apache config (inherited from the parent vhost): the linter accepts bare directives at top-level. A complete VirtualHost adds context (SSL port, certificates). For accurate audit prefer the full vhost because some checks (HSTS scoped to the SSL vhost, listen 80 redirect) require the block. If you paste only a .htaccess, the linter cannot decide whether you are on HTTPS or HTTP.
Does the Apache sample pass with score 100? I want to understand it as baseline.
The Apache sample includes two vhosts: one HTTP->HTTPS redirect, one HTTPS with modern SSL/TLS, HSTS preload, CSP with report-uri, X-Frame, X-Content-Type, Referrer, Permissions, OCSP stapling, HTTP/2 (Protocols h2), AllowOverride None on Directory. Expected score: 90-100. Possible drop: mod_security not visible (info, -1), no explicit ServerTokens declared (info, -1).
Nginx add_header override semantics: how do I really fix it?
Three approaches. (1) Repeat headers in every location: more boilerplate but deterministic, any sysadmin reading the config will understand it. (2) Use more_set_headers from headers-more-nginx-module: NOT subject to the override rule, global set that also applies to locations. Requires custom build or official package (Debian: libnginx-mod-http-headers-more-filter). (3) Refactor the location structure: collapse similar locations into one with map or if, reducing override surface.
CSP with 'unsafe-inline': when can it be accepted?
Ideally never in new projects: nonce-based or hash-based CSP are the modern baseline. In legacy cases: (a) frontend with thousands of inline event handlers requiring long refactor, accept unsafe-inline for the moment but document it in the config commit message; (b) analytics tools injecting inline scripts (Google Tag Manager pre-2023, some A/B testing tools), unsafe-inline is the fastest way. Partial mitigation: add 'self' + nonce for your scripts and accept unsafe-inline only as fallback whitelist.
HSTS preload: is it worth signing up to Chrome's preload list?
Yes for any stable web-only domain. The preload list integrates the domain into Chromium code (and derived browsers): the first visit to the domain is already forced to HTTPS, eliminating the first-visit downgrade attack window. Trade-off: once enrolled, you only resi HTTPS (no quick rollback to HTTP). Procedure: max-age=31536000 minimum, includeSubDomains mandatory, preload mandatory, submit at hstspreload.org.
/server-status and /nginx_status: should they be disabled or just restricted?
Restricted, not disabled: useful for monitoring (Nagios, Zabbix, custom dashboards). Typical restriction: Apache <Location /server-status> Require local </Location> or Require ip 10.0.0.0/8. Nginx location /nginx_status { stub_status on; allow 127.0.0.1; allow 10.0.0.0/8; deny all; }. Publicly exposed they leak internal hostnames, per-vhost traffic, request rate: information leakage useful for fingerprinting and detecting attack waves.
TLSv1 and TLSv1.1: should they be entirely disabled or is it OK to negotiate them for compatibility?
Entirely disabled for any new project. PCI DSS 4.0 requires TLSv1.2 minimum from mid-2024. Browser support: TLSv1.2 is supported by IE 11 onwards (Win 7+), Android 5+, iOS 5+. Remaining clients requiring TLSv1/TLSv1.1 are esoteric legacy clients (vintage enterprise printers, SCADA systems): if you have them, isolate them on a separate endpoint and declare TLSv1.2+ everywhere.
Forward secrecy: how critical is it in practice?
Critical for long-life data. Without forward secrecy, future private key compromise (server breach, key theft, court order) allows decryption of ALL past intercepted TLS sessions (recorded by a passive adversary like ISP or nation-state actor). With forward secrecy, past sessions stay encrypted. ECDHE/DHE ciphers guarantee it, static RSA does not. Best practice: Mozilla Intermediate SSLCipherSuite guarantees it, migrate to that.
HTTP/2 vs HTTP/3: should I enable both?
HTTP/2 is modern baseline (mature deploys since 2018, ~99% browser support). HTTP/3 (over QUIC) is next-gen but non-trivial deploy: requires UDP open at firewall, Apache only supports it via experimental mod_http2, Nginx requires --with-http_v3_module (1.25+). Pragmatic roadmap: HTTP/2 always, HTTP/3 when you have a real use case (mobile-heavy, devices on lossy connections).
mod_security: is it worth enabling?
Yes, for any publicly exposed site. Cost: ~5-10% CPU overhead with standard CRS. Benefit: automatic block of SQLi, XSS, RCE, recognizable scanners (nikto, sqlmap, dirb), enumeration, plain-text attack patterns. Caveat: initial configuration requires tuning to reduce false positives on the specific app. Modern alternative: cloud WAF (Cloudflare, AWS WAF, Sucuri). Costs but eliminates tuning.
Can I audit configs that use Include / include against external files?
The tool only lints what you paste. Apache Include and Nginx include point to external files: the browser cannot resolve them. Workaround: manually concatenate the files of interest and paste the resulting blob, or lint files one by one. Full audit requires server filesystem access, out of scope for a browser-only tool.
Can I audit the main /etc/nginx/nginx.conf file?
Yes, the parser correctly supports events { }, http { }, nested server { }, upstream, top-level directives. Typical findings on main nginx.conf: server_tokens off at http level, global limit_req_zone, ssl session cache. Per-server findings will appear for every server { } included (also via manually resolved includes).
Privacy: is the pasted config stored or tracked?
No. The tool runs entirely in the browser. No network request with the config: parser, context-aware rules, value validators, rendering, report generation - all in local JavaScript. Verifiable by opening the DevTools Network panel during the lint: zero outgoing requests with config data. The config is not saved in localStorage nor tracked in analytics.
Can I integrate the linter into a CI/CD pipeline?
For CI/CD use dedicated tools: nginx-config-formatter + Nginx configtest, Apache apachectl configtest, gixy (Yandex, Python) for Nginx security audit, apache-config-lint Ruby. Our tool is browser-based: great for interactive reviews, sub-optimal for pipelines. Valid use case: PR code review of a config change, the developer pastes the diff and triages before push.