Skip to content

Conversation

@casmith
Copy link
Owner

@casmith casmith commented Jan 23, 2026

Summary

Adds security headers to all production and demo nginx reverse proxy configs to address OWASP ZAP findings.

Configs Updated

  • nginx/conf/beoftexas.com.conf (production)
  • nginx/nginx/beoftexas.com.conf (alternate production)
  • nginx/conf/wbaoftexas.com.conf (production)
  • nginx-demo/conf/demo.beoftexas.com.conf (demo)
  • nginx-demo/conf/demo.wbaoftexas.com.conf (demo)

Headers Added

Header Value
Strict-Transport-Security max-age=31536000; includeSubDomains
X-Frame-Options SAMEORIGIN
X-Content-Type-Options nosniff
X-XSS-Protection 1; mode=block
Permissions-Policy geolocation=(), microphone=(), camera=()
Cross-Origin-Resource-Policy same-origin
Cross-Origin-Opener-Policy same-origin
Content-Security-Policy default-src 'self'; script-src 'self' 'unsafe-inline' https://ajax.googleapis.com; ...

Also Added

  • Proxy headers (X-Real-IP, X-Forwarded-For, X-Forwarded-Proto) where missing

Test Plan

After deploying, verify headers:

curl -I https://beoftexas.com/ | grep -E "(X-Content-Type|Permissions-Policy|Cross-Origin|Content-Security)"

Related Issues

  • casmith/beoftexas#173 (X-Content-Type-Options)
  • casmith/beoftexas#171 (Permissions-Policy)
  • casmith/beoftexas#170 (Spectre/CORP)
  • casmith/beoftexas#164 (CSP)

🤖 Generated with Claude Code

casmith and others added 18 commits January 20, 2026 21:22
Set up a demo/staging environment for local VM deployment with:
- Cloudflare Tunnel for public internet access (no firewall needed)
- Let's Encrypt SSL via DNS-01 challenge (Cloudflare DNS API)
- Services: beoftexas, strapi, wbaoftexas

New infrastructure:
- cloudflared container for tunnel connectivity
- nginx-demo with certbot/dns-cloudflare for SSL certs
- Demo-specific playbooks for each service

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add API token and tunnel token
- Tunnel 'demo-beoftexas' created via API with ingress rules
- DNS CNAME records created for all demo domains

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add DATABASE_PASSWORD env var to strapi docker-compose
- Update strapi playbook to set password from secret file
- Update demo secrets with actual passwords

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add ajax.googleapis.com to script-src in both prod and demo
beoftexas nginx configs to allow loading jQuery from Google CDN.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- strapi/restore-db-demo.yaml - restore postgres from S3
- strapi/restore-app-demo.yaml - restore app directory from S3

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add S3 credential checks to deploy-demo.sh prerequisites
- Add Strapi database and app restore steps to deploy-demo.sh
- Add beoftexas database restore step to deploy-demo.sh
- Clear beoftexas public_files volume before deployment for clean assets
- Add teardown-demo.sh script to cleanly tear down demo environment

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Stop Strapi web service before dropping database
- Terminate existing database connections before drop
- Connect to postgres database (not strapi) when waiting for db ready
- Restart Strapi service after restore completes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
strapi_latest.sql.gz is corrupted (see issue #9). Using
strapi_20260109T231005.sql.gz until the backup job is fixed.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Migrations require existing tables, so they must run after the
database is restored from backup, not on an empty database.

- Remove migration step from beoftexas/playbook-demo.yaml
- Add migration step to deploy-demo.sh after restore

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The .env and secrets files are owned by root (from ansible become: true)
so docker compose commands need sudo to read them.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add owner/group: ubuntu to all file and copy tasks in demo playbooks
so that docker compose commands can read .env and secrets files
without needing sudo.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Increase certbot DNS propagation wait from 30s to 60s
- Add owner/group: ubuntu to nginx-demo and cloudflared playbooks

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Backup certbot conf to S3 during teardown
- Restore certificates from S3 on deploy if backup exists
- Survives VM destruction/recreation
- Avoids Let's Encrypt rate limits and speeds up deployment

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The certbot container has an entrypoint that runs 'certbot renew' in
a loop, ignoring any command passed. Use --entrypoint '' to clear it
so certonly actually runs.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds security headers to all production and demo nginx configs:
- beoftexas.com (prod + demo)
- wbaoftexas.com (prod + demo)

Headers added:
- Strict-Transport-Security (HSTS)
- X-Frame-Options
- X-Content-Type-Options
- X-XSS-Protection
- Permissions-Policy
- Cross-Origin-Resource-Policy
- Cross-Origin-Opener-Policy
- Content-Security-Policy

Also adds proxy headers for proper client IP forwarding.

Related: casmith/beoftexas#173, #171, #170, #164

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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