mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-07 12:21:31 +00:00
feat(pre-2.1.0): demo data overhaul, examples, migration guides, install script
Pre-2.1.0 adoption polish delivering all four milestones: A) Demo Data Overhaul — seed_demo.sql rewritten with 35 certs across 5 issuers, 8 agents, 8 targets, 50+ jobs spanning 90 days, 55+ audit events, discovery scans, network scan targets, S/MIME cert. B) Examples Directory — 5 turnkey docker-compose configs: acme-nginx, acme-wildcard-dns01, private-ca-traefik, step-ca-haproxy, multi-issuer. C) Migration Guides — migrate-from-certbot.md, migrate-from-acmesh.md, certctl-for-cert-manager-users.md. D) Agent Install Script — install-agent.sh with cross-platform support (Linux systemd + macOS launchd), release.yml updated for 6-target cross-compilation. Triple-audited against codebase: 22 factual corrections applied across docs, examples, and config (env var names, CLI flags, ports, DNS hook interface, scheduler loop counts, license conversion date). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,355 @@
|
||||
# step-ca + HAProxy Example
|
||||
|
||||
This example demonstrates certctl managing certificates issued by **Smallstep step-ca** and deploying them to **HAProxy**.
|
||||
|
||||
## Scenario
|
||||
|
||||
You're a Smallstep user running step-ca as your internal PKI. You have HAProxy load balancers that need certificates. This setup:
|
||||
|
||||
1. **step-ca** issues certificates (via JWK provisioner, no challenge solving)
|
||||
2. **certctl** manages the certificate lifecycle (renewal policies, deployment, audit)
|
||||
3. **HAProxy** serves HTTPS with certificates managed by certctl
|
||||
|
||||
This is the natural choice if you're already invested in step-ca and want to consolidate certificate lifecycle management without learning Let's Encrypt, DNS-01 challenges, or external integrations.
|
||||
|
||||
## What's Included
|
||||
|
||||
| Service | Image | Purpose |
|
||||
|---------|-------|---------|
|
||||
| **step-ca** | `smallstep/step-ca:latest` | Private internal CA |
|
||||
| **certctl-server** | `ghcr.io/shankar0123/certctl-server:latest` | Certificate management control plane |
|
||||
| **certctl-agent** | `ghcr.io/shankar0123/certctl-agent:latest` | Agent running on HAProxy server |
|
||||
| **haproxy** | `haproxy:2.9-alpine` | Reverse proxy / load balancer |
|
||||
| **postgres** | `postgres:16-alpine` | certctl audit trail + config storage |
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Docker and Docker Compose
|
||||
- Curl (to interact with APIs)
|
||||
|
||||
### 1. Start Everything
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
This will:
|
||||
- Initialize step-ca with a self-signed root CA
|
||||
- Create a JWK provisioner named `certctl` (pre-configured credentials)
|
||||
- Start certctl-server (connected to step-ca)
|
||||
- Start the certctl-agent (ready to deploy certs to HAProxy)
|
||||
- Start HAProxy with a placeholder config
|
||||
|
||||
Monitor logs:
|
||||
|
||||
```bash
|
||||
docker compose logs -f certctl-server
|
||||
```
|
||||
|
||||
Wait for all services to reach healthy state:
|
||||
|
||||
```bash
|
||||
docker compose ps
|
||||
```
|
||||
|
||||
Expected output:
|
||||
```
|
||||
NAME STATUS
|
||||
certctl-postgres-... healthy
|
||||
certctl-server-... healthy
|
||||
step-ca-... healthy
|
||||
certctl-agent-... running
|
||||
certctl-haproxy-... healthy
|
||||
```
|
||||
|
||||
### 2. Access certctl Dashboard
|
||||
|
||||
Open your browser to:
|
||||
|
||||
```
|
||||
http://localhost:8443
|
||||
```
|
||||
|
||||
You should see an empty dashboard. This is expected — no certificates issued yet.
|
||||
|
||||
### 3. Create a Certificate Profile
|
||||
|
||||
This defines what certificates certctl can issue (key algorithm, max TTL, allowed names).
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8443/api/v1/profiles \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"name": "internal-web",
|
||||
"key_type": "rsa-2048",
|
||||
"max_ttl_days": 90,
|
||||
"description": "Internal web services"
|
||||
}'
|
||||
```
|
||||
|
||||
### 4. Create an HAProxy Deployment Target
|
||||
|
||||
This tells certctl where to deploy certificates on the HAProxy server.
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8443/api/v1/targets \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"name": "haproxy-01",
|
||||
"type": "haproxy",
|
||||
"enabled": true,
|
||||
"config": {
|
||||
"pem_path": "/etc/haproxy/ssl/cert.pem",
|
||||
"reload_command": "systemctl reload haproxy",
|
||||
"validate_command": "haproxy -c -f /etc/haproxy/haproxy.cfg"
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
Note: In the Docker Compose environment, reload command can be `kill -HUP $(pidof haproxy)` instead of `systemctl reload haproxy`.
|
||||
|
||||
### 5. Create a Renewal Policy
|
||||
|
||||
This ties a certificate profile to a deployment target and sets renewal thresholds.
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8443/api/v1/renewal-policies \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"name": "haproxy-internal-web",
|
||||
"profile_id": "<profile_id_from_step_3>",
|
||||
"issuer_id": "iss-stepca",
|
||||
"enabled": true,
|
||||
"renewal_days_before_expiry": 30,
|
||||
"alert_thresholds_days": [30, 14, 7, 0]
|
||||
}'
|
||||
```
|
||||
|
||||
Get the issuer ID:
|
||||
|
||||
```bash
|
||||
curl http://localhost:8443/api/v1/issuers | jq '.'
|
||||
```
|
||||
|
||||
You should see `iss-stepca` in the list.
|
||||
|
||||
### 6. Issue a Certificate
|
||||
|
||||
Request a certificate via the API. The server will sign it via step-ca.
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8443/api/v1/certificates \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"common_name": "api.internal.example.com",
|
||||
"sans": ["api.internal.example.com", "api.staging.example.com"],
|
||||
"issuer_id": "iss-stepca",
|
||||
"profile_id": "<profile_id_from_step_3>"
|
||||
}'
|
||||
```
|
||||
|
||||
### 7. Deploy to HAProxy
|
||||
|
||||
Get the certificate ID and trigger deployment:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8443/api/v1/certificates/<cert_id>/deploy \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"target_id": "<target_id_from_step_4>"
|
||||
}'
|
||||
```
|
||||
|
||||
The agent will:
|
||||
1. Fetch the deployment job
|
||||
2. Generate a combined PEM (cert + chain + key) locally
|
||||
3. Write it to `/etc/haproxy/ssl/cert.pem` on HAProxy
|
||||
4. Reload HAProxy
|
||||
5. Report status back to certctl
|
||||
|
||||
### 8. Verify in Dashboard
|
||||
|
||||
Refresh http://localhost:8443 and you should see:
|
||||
- 1 certificate (status: Active, expiry in 90 days)
|
||||
- 1 deployment job (status: Completed)
|
||||
- 1 agent (heartbeat: recent)
|
||||
|
||||
## Configuration Details
|
||||
|
||||
### step-ca Integration
|
||||
|
||||
step-ca is configured with:
|
||||
|
||||
- **Root CA Name**: `certctl-demo-ca`
|
||||
- **Provisioner**: `certctl` (JWK type)
|
||||
- **Default Password**: `certctl-provisioner-demo` (override with `STEP_CA_PROVISIONER_PASSWORD`)
|
||||
|
||||
To inspect step-ca:
|
||||
|
||||
```bash
|
||||
docker compose exec step-ca step ca provisioner list
|
||||
docker compose exec step-ca step ca health --insecure
|
||||
```
|
||||
|
||||
### HAProxy Combined PEM Format
|
||||
|
||||
HAProxy requires a single file with certificate, chain, and key concatenated:
|
||||
|
||||
```
|
||||
-----BEGIN CERTIFICATE-----
|
||||
[leaf certificate]
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
[intermediate CA]
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
[private key]
|
||||
-----END RSA PRIVATE KEY-----
|
||||
```
|
||||
|
||||
The agent automatically constructs this file from the issued certificate and step-ca-provided chain.
|
||||
|
||||
**Security**: The combined PEM is written with `0600` permissions (owner-readable only) because it contains the private key.
|
||||
|
||||
### Environment Variables
|
||||
|
||||
Customize behavior with:
|
||||
|
||||
| Variable | Default | Purpose |
|
||||
|----------|---------|---------|
|
||||
| `DB_PASSWORD` | `certctl-dev-password` | PostgreSQL password |
|
||||
| `STEP_CA_PASSWORD` | `stepca-demo-password` | step-ca root key password |
|
||||
| `STEP_CA_PROVISIONER_PASSWORD` | `certctl-provisioner-demo` | certctl JWK provisioner password |
|
||||
| `AGENT_API_KEY` | `agent-demo-key` | Agent authentication token |
|
||||
| `SERVER_PORT` | `8443` | certctl server external port |
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
STEP_CA_PASSWORD=myca-password AGENT_API_KEY=secret-key docker compose up -d
|
||||
```
|
||||
|
||||
## Integrating with an Existing step-ca Instance
|
||||
|
||||
If you already run step-ca elsewhere (not in this Compose file):
|
||||
|
||||
1. **Extract the root certificate** from your step-ca:
|
||||
|
||||
```bash
|
||||
step ca root /tmp/step-ca-root.crt --ca-url https://ca.internal:9000 --insecure
|
||||
```
|
||||
|
||||
2. **Create or retrieve the certctl JWK provisioner key**:
|
||||
|
||||
```bash
|
||||
step ca provisioner list --ca-url https://ca.internal:9000 --insecure
|
||||
step ca provisioner describe certctl --ca-url https://ca.internal:9000 --insecure
|
||||
```
|
||||
|
||||
3. **Update docker-compose.yml**:
|
||||
|
||||
```yaml
|
||||
certctl-server:
|
||||
environment:
|
||||
CERTCTL_STEPCA_URL: https://ca.internal:9000
|
||||
CERTCTL_STEPCA_ROOT_CERT_PATH: /etc/certctl/step-ca-root.crt
|
||||
CERTCTL_STEPCA_PROVISIONER_NAME: certctl
|
||||
CERTCTL_STEPCA_PROVISIONER_KEY_PATH: /etc/certctl/step-ca-provisioner.json
|
||||
CERTCTL_STEPCA_PROVISIONER_PASSWORD: <your-password>
|
||||
```
|
||||
|
||||
4. **Mount the cert and key**:
|
||||
|
||||
```yaml
|
||||
volumes:
|
||||
- /path/to/step-ca-root.crt:/etc/certctl/step-ca-root.crt:ro
|
||||
- /path/to/provisioner.json:/etc/certctl/step-ca-provisioner.json:ro
|
||||
```
|
||||
|
||||
## Cleanup
|
||||
|
||||
```bash
|
||||
docker compose down -v
|
||||
```
|
||||
|
||||
This removes all containers and volumes (step-ca config, certificates, database).
|
||||
|
||||
## Next Steps
|
||||
|
||||
### Production Deployment
|
||||
|
||||
- Replace image tags (`latest` → specific version)
|
||||
- Use real TLS certificates for step-ca (self-signed is fine internally, but use proper roots for verification)
|
||||
- Configure persistent storage for step-ca keys (HSM or encrypted filesystem)
|
||||
- Set `CERTCTL_AUTH_TYPE: api-key` and rotate API keys regularly
|
||||
- Enable audit trail export for compliance
|
||||
- Configure renewal alerts (Slack, email, PagerDuty)
|
||||
- Run agents on separate machines (not in Compose)
|
||||
|
||||
### Advanced Features
|
||||
|
||||
- **Multiple HAProxy instances**: Create additional targets and agents
|
||||
- **Policy-based renewal**: Set different renewal windows per environment (staging vs. production)
|
||||
- **Approval workflows**: Require manual approval before deploying to production
|
||||
- **Discovery**: Scan existing HAProxy certs and bring them under management
|
||||
- **Network scanning**: Discover TLS endpoints in your network and inventory them
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### step-ca fails to initialize
|
||||
|
||||
Check logs:
|
||||
|
||||
```bash
|
||||
docker compose logs step-ca
|
||||
```
|
||||
|
||||
Common issues:
|
||||
- Permissions on `/home/step/step-ca` volume
|
||||
- Port 9000 already in use
|
||||
|
||||
### Agent can't reach server
|
||||
|
||||
Verify network:
|
||||
|
||||
```bash
|
||||
docker compose exec certctl-agent curl http://certctl-server:8443/api/v1/health
|
||||
```
|
||||
|
||||
### HAProxy config validation fails
|
||||
|
||||
Check HAProxy config syntax:
|
||||
|
||||
```bash
|
||||
docker compose exec haproxy haproxy -c -f /etc/haproxy/haproxy.cfg
|
||||
```
|
||||
|
||||
### Deployment job stays in "Running" state
|
||||
|
||||
Check agent logs:
|
||||
|
||||
```bash
|
||||
docker compose logs certctl-agent
|
||||
```
|
||||
|
||||
Likely causes:
|
||||
- Agent can't write to `/etc/haproxy/ssl/cert.pem` (permissions)
|
||||
- Reload command is misconfigured
|
||||
- HAProxy container is not accessible
|
||||
|
||||
## Documentation
|
||||
|
||||
- [certctl Architecture](../../docs/architecture.md)
|
||||
- [step-ca Connector Docs](../../docs/connectors.md#step-ca)
|
||||
- [HAProxy Target Docs](../../docs/connectors.md#haproxy)
|
||||
- [API Reference](../../api/openapi.yaml)
|
||||
|
||||
## Support
|
||||
|
||||
For issues or questions:
|
||||
|
||||
1. Check the [troubleshooting guide](../../docs/troubleshooting.md)
|
||||
2. Review service logs: `docker compose logs <service>`
|
||||
3. Open an issue on GitHub
|
||||
@@ -0,0 +1,204 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# PostgreSQL database for certctl
|
||||
postgres:
|
||||
image: postgres:16-alpine
|
||||
container_name: certctl-postgres-stepca-haproxy
|
||||
environment:
|
||||
POSTGRES_DB: certctl
|
||||
POSTGRES_USER: certctl
|
||||
POSTGRES_PASSWORD: ${DB_PASSWORD:-certctl-dev-password}
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ['CMD-SHELL', 'pg_isready -U certctl -d certctl']
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
networks:
|
||||
- certctl-network
|
||||
restart: unless-stopped
|
||||
|
||||
# Smallstep step-ca (internal private CA)
|
||||
# Initialized with default admin token and provisioner configuration
|
||||
step-ca:
|
||||
image: smallstep/step-ca:latest
|
||||
container_name: step-ca-stepca-haproxy
|
||||
environment:
|
||||
# step-ca root password (for key encryption)
|
||||
STEPPATH: /home/step/step-ca
|
||||
# Provisioner password will be set up below
|
||||
volumes:
|
||||
# Persist step-ca configuration and keys
|
||||
- step_ca_data:/home/step/step-ca
|
||||
- ./step-ca-init.sh:/opt/step-ca-init.sh:ro
|
||||
entrypoint: /bin/sh
|
||||
command:
|
||||
- -c
|
||||
- |
|
||||
# Initialize step-ca if not already done
|
||||
if [ ! -f /home/step/step-ca/config/ca.json ]; then
|
||||
echo "Initializing step-ca..."
|
||||
step ca init \
|
||||
--name="certctl-demo-ca" \
|
||||
--dns=step-ca \
|
||||
--address=0.0.0.0:9000 \
|
||||
--provisioner=admin \
|
||||
--provisioner-password-file=<(echo "${STEP_CA_PASSWORD:-stepca-demo-password}") \
|
||||
--password-file=<(echo "${STEP_CA_PASSWORD:-stepca-demo-password}") \
|
||||
--deployment-type=standalone \
|
||||
--acme 2>&1 || true
|
||||
fi
|
||||
|
||||
# Add a JWK provisioner for certctl if not present
|
||||
if ! step ca provisioner list 2>/dev/null | grep -q "certctl"; then
|
||||
echo "Adding certctl JWK provisioner..."
|
||||
step ca provisioner add certctl \
|
||||
--type=JWK \
|
||||
--password-file=<(echo "${STEP_CA_PROVISIONER_PASSWORD:-certctl-provisioner-demo}") \
|
||||
2>&1 || true
|
||||
fi
|
||||
|
||||
# Start step-ca
|
||||
echo "Starting step-ca..."
|
||||
step-ca /home/step/step-ca/config/ca.json \
|
||||
--password-file=<(echo "${STEP_CA_PASSWORD:-stepca-demo-password}")
|
||||
ports:
|
||||
- '9000:9000'
|
||||
healthcheck:
|
||||
test: ['CMD-SHELL', 'step ca health --insecure || exit 1']
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
networks:
|
||||
- certctl-network
|
||||
restart: unless-stopped
|
||||
|
||||
# certctl server (control plane)
|
||||
certctl-server:
|
||||
image: ghcr.io/shankar0123/certctl-server:latest
|
||||
container_name: certctl-server-stepca-haproxy
|
||||
environment:
|
||||
# Database
|
||||
DATABASE_URL: postgres://certctl:${DB_PASSWORD:-certctl-dev-password}@postgres:5432/certctl?sslmode=disable
|
||||
|
||||
# Server settings
|
||||
CERTCTL_SERVER_PORT: 8443
|
||||
CERTCTL_SERVER_HOST: 0.0.0.0
|
||||
|
||||
# Auth (disabled for demo; production should use API keys)
|
||||
CERTCTL_AUTH_TYPE: none
|
||||
|
||||
# CORS (allow agent communication)
|
||||
CERTCTL_CORS_ORIGINS: '*'
|
||||
|
||||
# Key generation mode (agent-side in production, server-side for demo)
|
||||
CERTCTL_KEYGEN_MODE: agent
|
||||
|
||||
# step-ca issuer configuration
|
||||
# step-ca runs on step-ca:9000 in this compose network
|
||||
CERTCTL_STEPCA_URL: https://step-ca:9000
|
||||
CERTCTL_STEPCA_ROOT_CERT_PATH: /etc/certctl/step-ca-root.crt
|
||||
CERTCTL_STEPCA_PROVISIONER: certctl
|
||||
CERTCTL_STEPCA_KEY_PATH: /etc/certctl/step-ca-provisioner.json
|
||||
CERTCTL_STEPCA_PASSWORD: ${STEP_CA_PROVISIONER_PASSWORD:-certctl-provisioner-demo}
|
||||
|
||||
# Logging
|
||||
CERTCTL_LOG_LEVEL: info
|
||||
volumes:
|
||||
# Mount step-ca certs for TLS verification (auto-generated by step-ca init)
|
||||
- step_ca_data:/home/step/step-ca/config:ro
|
||||
ports:
|
||||
- '${SERVER_PORT:-8443}:8443'
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
step-ca:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- certctl-network
|
||||
healthcheck:
|
||||
test: ['CMD-SHELL', 'curl -sf http://localhost:8443/api/v1/health || exit 1']
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
restart: unless-stopped
|
||||
|
||||
# certctl agent (runs on the target machine with HAProxy)
|
||||
certctl-agent:
|
||||
image: ghcr.io/shankar0123/certctl-agent:latest
|
||||
container_name: certctl-agent-stepca-haproxy
|
||||
environment:
|
||||
# Control plane connection
|
||||
CERTCTL_SERVER_URL: http://certctl-server:8443
|
||||
CERTCTL_API_KEY: ${AGENT_API_KEY:-agent-demo-key}
|
||||
|
||||
# Key generation (agent-side keys, never sent to server)
|
||||
CERTCTL_KEYGEN_MODE: agent
|
||||
CERTCTL_KEY_DIR: /var/lib/certctl/keys
|
||||
|
||||
# Discovery (scan existing certs so operator knows what's already deployed)
|
||||
CERTCTL_DISCOVERY_DIRS: /etc/haproxy/ssl
|
||||
|
||||
# Heartbeat interval
|
||||
CERTCTL_HEARTBEAT_INTERVAL: 30s
|
||||
|
||||
# Agent metadata (self-reported)
|
||||
CERTCTL_AGENT_NAME: haproxy-agent-01
|
||||
|
||||
# Logging
|
||||
CERTCTL_LOG_LEVEL: info
|
||||
volumes:
|
||||
# Mount HAProxy config and cert directories
|
||||
# In production, these would be the actual HAProxy paths
|
||||
- haproxy_certs:/etc/haproxy/ssl
|
||||
- haproxy_conf:/etc/haproxy
|
||||
# Agent key storage (persisted across restarts)
|
||||
- agent_keys:/var/lib/certctl/keys
|
||||
depends_on:
|
||||
certctl-server:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- certctl-network
|
||||
restart: unless-stopped
|
||||
|
||||
# HAProxy reverse proxy / load balancer
|
||||
# This is where certificates will be deployed
|
||||
haproxy:
|
||||
image: haproxy:2.9-alpine
|
||||
container_name: certctl-haproxy-stepca-haproxy
|
||||
ports:
|
||||
- '80:80'
|
||||
- '443:443'
|
||||
volumes:
|
||||
- haproxy_conf:/etc/haproxy
|
||||
- haproxy_certs:/etc/haproxy/ssl
|
||||
# Default HAProxy config
|
||||
- ./haproxy.cfg:/etc/haproxy/haproxy.cfg:ro
|
||||
depends_on:
|
||||
- certctl-agent
|
||||
networks:
|
||||
- certctl-network
|
||||
healthcheck:
|
||||
test: ['CMD-SHELL', 'wget --quiet --tries=1 --spider http://localhost:8080/stats || exit 1']
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
restart: unless-stopped
|
||||
|
||||
networks:
|
||||
certctl-network:
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
driver: local
|
||||
step_ca_data:
|
||||
driver: local
|
||||
haproxy_certs:
|
||||
driver: local
|
||||
haproxy_conf:
|
||||
driver: local
|
||||
agent_keys:
|
||||
driver: local
|
||||
@@ -0,0 +1,69 @@
|
||||
global
|
||||
log stdout local0
|
||||
log stdout local1 notice
|
||||
chroot /var/lib/haproxy
|
||||
stats socket /run/haproxy/admin.sock mode 660 level admin
|
||||
stats timeout 30s
|
||||
user haproxy
|
||||
group haproxy
|
||||
daemon
|
||||
|
||||
# Default SSL options for modern TLS
|
||||
tune.ssl.default-dh-param 2048
|
||||
ssl-default-bind-ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384
|
||||
ssl-default-bind-options ssl-min-ver TLSv1.2
|
||||
|
||||
defaults
|
||||
mode http
|
||||
log global
|
||||
option httplog
|
||||
option dontlognull
|
||||
timeout connect 5000
|
||||
timeout client 50000
|
||||
timeout server 50000
|
||||
errorfile 400 /etc/haproxy/errors/400.http
|
||||
errorfile 403 /etc/haproxy/errors/403.http
|
||||
errorfile 408 /etc/haproxy/errors/408.http
|
||||
errorfile 500 /etc/haproxy/errors/500.http
|
||||
errorfile 502 /etc/haproxy/errors/502.http
|
||||
errorfile 503 /etc/haproxy/errors/503.http
|
||||
errorfile 504 /etc/haproxy/errors/504.http
|
||||
|
||||
# Statistics endpoint (accessible on port 8080)
|
||||
listen stats
|
||||
bind *:8080
|
||||
stats enable
|
||||
stats uri /stats
|
||||
stats refresh 30s
|
||||
stats admin if TRUE
|
||||
|
||||
# Example HTTPS frontend with certificate from certctl
|
||||
# This frontend will serve HTTPS on port 443 using a combined PEM file
|
||||
# deployed by certctl to /etc/haproxy/ssl/cert.pem
|
||||
frontend https_in
|
||||
# HTTP redirect to HTTPS
|
||||
bind *:80
|
||||
mode http
|
||||
acl is_http hdr(X-Forwarded-Proto) http
|
||||
redirect scheme https code 301 if !is_https
|
||||
|
||||
# HTTPS with certificate
|
||||
# In production, certctl will manage cert.pem and reload HAProxy after deployment
|
||||
bind *:443 ssl crt /etc/haproxy/ssl/cert.pem strict-sni
|
||||
mode http
|
||||
option httplog
|
||||
|
||||
# Default backend
|
||||
default_backend http_backend
|
||||
|
||||
# Example backend (simple web service placeholder)
|
||||
backend http_backend
|
||||
mode http
|
||||
option httpchk GET /
|
||||
server local_app 127.0.0.1:8000 check disabled
|
||||
|
||||
# Health endpoint (useful for certctl agent deployment verification)
|
||||
frontend health
|
||||
bind *:9999
|
||||
mode http
|
||||
monitor-uri /health
|
||||
Reference in New Issue
Block a user