Skip to content

feat(lab11): hardened nginx + WAF sidecar#1567

Open
semyonnadutkin wants to merge 1 commit into
inno-devops-labs:mainfrom
semyonnadutkin:feature/lab11
Open

feat(lab11): hardened nginx + WAF sidecar#1567
semyonnadutkin wants to merge 1 commit into
inno-devops-labs:mainfrom
semyonnadutkin:feature/lab11

Conversation

@semyonnadutkin

Copy link
Copy Markdown

Goal

Deliver a hardened Nginx reverse proxy for Juice Shop with TLS 1.3, security headers, abuse controls, production certificate guidance, and a ModSecurity v3 WAF using OWASP CRS 4.25.1.

Changes

  • Added a ModSecurity v3 WAF service with OWASP CRS 4.25.1, paranoia level 1, blocking mode, and audit logging.
  • Added runtime verification artifacts for TLS, headers, rate limiting, timeouts, cipher negotiation, and WAF blocking.
  • Added submissions/lab11.md with verification evidence, header explanations, certificate rotation runbook, OCSP analysis, and WAF tradeoff analysis.
  • Modified labs/lab11/reverse-proxy/nginx.conf to enforce TLS 1.3, hardened cipher suites, X25519, secure session settings, connection limiting, and two-year HSTS.
  • Removed support for TLS 1.2 and insecure or unnecessary legacy TLS configuration.

Testing

Verified the Nginx configuration, HTTP-to-HTTPS redirect, TLS protocol restrictions, all required security headers, rate limiting, slow-request timeout, cipher suite and key exchange, and OWASP CRS attack blocking. The final stack passed nginx -t; TLS 1.2 was rejected; the SQL injection payload passed through plain Nginx to the application but was blocked by the WAF with rule 942100.

Commands executed:

docker compose -f docker-compose.yml -f waf/docker-compose.override.yml up -d
docker compose -f docker-compose.yml -f waf/docker-compose.override.yml ps
docker compose exec nginx nginx -t

curl -sI http://localhost
echo | openssl s_client -connect localhost:443 -tls1_3 -brief
curl -skI https://localhost

seq 1 60 | xargs -P 30 -I{} curl -sk -X POST \
  -H 'Content-Type: application/json' \
  -d '{"email":"lab11@example.invalid","password":"invalid"}' \
  -o /dev/null -w '%{http_code}\n' \
  https://localhost/rest/user/login | sort | uniq -c

(printf 'GET / HTTP/1.1\r\nHost: localhost\r\nX-Slow: '; sleep 12) \
  | timeout 15 openssl s_client -quiet -connect localhost:443

echo | openssl s_client -connect localhost:443 -tls1_3 -brief \
  | grep -E 'Protocol version|Ciphersuite|Peer Temp Key'

curl -sk -o /dev/null -w 'no-waf: HTTP %{http_code}\n' \
  "https://localhost/rest/products/search?q='%20OR%201=1--"

curl -sk -o /dev/null -w 'with-waf: HTTP %{http_code}\n' \
  "https://localhost:8443/rest/products/search?q='%20OR%201=1--"

docker compose -f docker-compose.yml -f waf/docker-compose.override.yml \
  exec -T waf cat /var/log/modsec/audit.log

echo | openssl s_client -connect localhost:443 -tls1_2
git diff --check
docker compose -f docker-compose.yml -f waf/docker-compose.override.yml down

Observed output:

nginx: configuration file /etc/nginx/nginx.conf test is successful

HTTP/1.1 308 Permanent Redirect
Location: https://localhost/

Protocol version: TLSv1.3
Ciphersuite: TLS_AES_256_GCM_SHA384
Peer Temp Key: X25519, 253 bits

strict-transport-security: max-age=63072000; includeSubDomains; preload
x-frame-options: DENY
x-content-type-options: nosniff
referrer-policy: strict-origin-when-cross-origin
permissions-policy: camera=(), geolocation=(), microphone=()
content-security-policy-report-only: default-src 'self'; ...

      6 401
     54 429

Connection closed after 12 seconds (client_header_timeout = 10s).

no-waf: HTTP 500
with-waf: HTTP 403

[id "942100"]
[msg "SQL Injection Attack Detected via libinjection"]
[ver "OWASP_CRS/4.25.1"]
[msg "Inbound Anomaly Score Exceeded (Total Score: 5)"]

TLS 1.2 correctly rejected

Artifacts & Screenshots

Artifacts

  • submissions/lab11.md
  • labs/lab11/reverse-proxy/nginx.conf
  • labs/lab11/waf/docker-compose.override.yml
  • labs/lab11/results/

Screenshots

Checklist

  • Title is clear (feat(labN): <topic> style)

  • No secrets/large temp files committed

  • Submission file at submissions/labN.md exists

  • Task 1 — TLS 1.3 + 6 security headers (with proof)

  • Task 2 — Rate limit + timeouts + cipher hardening + cert-rotation runbook

  • Bonus — Coraza/ModSec WAF + OWASP CRS catching a payload Nginx-alone passes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant