veza/config/ssl/README.md
senke b657776892 fix(infra): HAProxy HTTPS and stats security
P1.1 - Enable HTTPS in HAProxy for production:
- HTTP to HTTPS redirect (301)
- HTTPS frontend on port 443 with veza.pem
- config/ssl/ structure with README and generate-ssl-cert.sh
- docker-compose.prod.yml volume for certs

P1.3 - Restrict HAProxy stats to internal network:
- ACL from_internal (127.0.0.1, 172.20.0.0/16)
- stats admin if from_internal

Also: remove errorfile directives (use HAProxy built-in defaults)
2026-02-15 15:58:51 +01:00

1.4 KiB

SSL Certificates for HAProxy

This directory holds SSL certificates for HTTPS in production. Never commit certificates or private keys (see .gitignore).

Required for Production HTTPS

HAProxy expects a single combined PEM file: veza.pem containing certificate + private key (concatenated). The config uses crt /etc/ssl/veza/veza.pem to avoid loading non-cert files (e.g. README.md).

Obtaining Certificates

Option 1: Let's Encrypt (Production)

# Standalone mode (stop HAProxy first)
certbot certonly --standalone -d yourdomain.com

# Copy to config
cat /etc/letsencrypt/live/yourdomain.com/fullchain.pem \
    /etc/letsencrypt/live/yourdomain.com/privkey.pem > config/ssl/veza.pem

Option 2: Self-Signed (Development/Staging)

openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout config/ssl/key.pem -out config/ssl/cert.pem \
  -subj "/CN=veza.local"

cat config/ssl/cert.pem config/ssl/key.pem > config/ssl/veza.pem

Docker Volume

docker-compose.prod.yml mounts this directory to /etc/ssl/veza in the HAProxy container. You must create veza.pem before starting production — the HAProxy healthcheck will fail otherwise.

Quick Start (First-Time Setup)

Run from repo root:

./scripts/generate-ssl-cert.sh

This creates a self-signed certificate for veza.local. For production, replace with Let's Encrypt or your CA.