Update documentation for wildcard SSL certificates

- Add wildcard certificate configuration to Traefik docs
- Document DuckDNS DNS challenge limitations
- Add SSL troubleshooting commands to quick reference
- Update getting-started with certificate verification steps
- Emphasize single wildcard cert vs individual certs best practice

Documentation now reflects production wildcard certificate setup.
This commit is contained in:
2026-01-12 23:24:38 -05:00
parent 90462cd179
commit 37a093189e
3 changed files with 97 additions and 15 deletions

View File

@@ -26,18 +26,27 @@ For most users, the automated setup script handles everything:
sudo ./scripts/setup-homelab.sh sudo ./scripts/setup-homelab.sh
``` ```
5. **Log out and back in** (or run `newgrp docker`) 5. **Log out and back in** (or run `newgrp docker`)
6. **Generate Authelia/Authentik Secrets 6. **Generate Authelia Secrets**:
```bash ```bash
# TODO: provide instructions for generating required secrets # Generate three required secrets for Authelia (128 characters each)
AUTHELIA_JWT_SECRET=your-jwt-secret-here-64-chars echo "AUTHELIA_JWT_SECRET=$(openssl rand -hex 64)"
AUTHELIA_SESSION_SECRET=your-session-secret-here-64-chars echo "AUTHELIA_SESSION_SECRET=$(openssl rand -hex 64)"
AUTHELIA_STORAGE_ENCRYPTION_KEY=your-encryption-key-here-64-chars echo "AUTHELIA_STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 64)"
AUTHENTIK_SECRET_KEY=your-authentik-secret-key-here-100-chars
# Copy these values and add them to your .env file
```
7. **Generate Authelia Admin Password Hash**:
```bash
# Replace 'yourpassword' with your desired admin password
docker run --rm authelia/authelia:4.37 authelia crypto hash generate argon2 --password 'yourpassword'
# Copy the output hash and update /opt/stacks/core/authelia/users_database.yml
# Replace the password field for the admin user
```
8. **Configure environment**: 8. **Configure environment**:
```bash ```bash
cp .env.example .env cp .env.example .env
nano .env # Edit with your settings nano .env # Edit with your settings and paste the Authelia secrets
``` ```
9. **Deploy core services**: 9. **Deploy core services**:
```bash ```bash
@@ -176,9 +185,12 @@ Use Dockge to deploy stacks like:
- **Network conflicts**: Check existing networks with `docker network ls` - **Network conflicts**: Check existing networks with `docker network ls`
### Service Issues ### Service Issues
- **Can't access services**: Check Traefik dashboard - **Can't access services**: Check Traefik dashboard at `https://traefik.yourdomain.duckdns.org`
- **SSL certificate errors**: Wait for Let's Encrypt - **SSL certificate errors**: Wait 2-5 minutes for wildcard certificate to be obtained from Let's Encrypt
- **Authelia login fails**: Check user database configuration - Check status: `python3 -c "import json; d=json.load(open('/opt/stacks/core/traefik/acme.json')); print(f'Certificates: {len(d[\"letsencrypt\"][\"Certificates\"])}')"`
- View logs: `docker exec traefik tail -50 /var/log/traefik/traefik.log | grep certificate`
- **Authelia login fails**: Check user database configuration at `/opt/stacks/core/authelia/users_database.yml`
- **"Not secure" warnings**: Clear browser cache or wait for DNS propagation (up to 5 minutes)
### Common Fixes ### Common Fixes
```bash ```bash

View File

@@ -323,6 +323,34 @@ https://prometheus.${DOMAIN} - Metrics collection
https://status.${DOMAIN} - Uptime monitoring https://status.${DOMAIN} - Uptime monitoring
``` ```
## Troubleshooting
### SSL Certificates
```bash
# Check wildcard certificate status
python3 -c "import json; d=json.load(open('/opt/stacks/core/traefik/acme.json')); print(f'Certificates: {len(d[\"letsencrypt\"][\"Certificates\"])}')"
# Verify certificate being served
echo | openssl s_client -connect auth.yourdomain.duckdns.org:443 -servername auth.yourdomain.duckdns.org 2>/dev/null | openssl x509 -noout -subject -issuer
# Check DNS TXT records (for DNS challenge)
dig +short TXT _acme-challenge.yourdomain.duckdns.org
# View Traefik certificate logs
docker exec traefik tail -50 /var/log/traefik/traefik.log | grep -E "acme|certificate"
# Reset certificates (if needed)
docker compose -f /opt/stacks/core/docker-compose.yml down
rm /opt/stacks/core/traefik/acme.json
touch /opt/stacks/core/traefik/acme.json
chmod 600 /opt/stacks/core/traefik/acme.json
sleep 60 # Wait for DNS to clear
docker compose -f /opt/stacks/core/docker-compose.yml up -d
```
**Important:** With DuckDNS, only Traefik should request certificates (wildcard cert covers all subdomains). Other services use `tls=true` without `certresolver`.
## Troubleshooting Quick Fixes ## Troubleshooting Quick Fixes
### Service won't start ### Service won't start

View File

@@ -119,8 +119,12 @@ certificatesResolvers:
acme: acme:
email: your-email@example.com email: your-email@example.com
storage: /acme.json storage: /acme.json
httpChallenge: dnsChallenge:
entryPoint: web provider: duckdns
disablePropagationCheck: true
resolvers:
- "1.1.1.1:53"
- "8.8.8.8:53"
providers: providers:
docker: docker:
@@ -148,7 +152,7 @@ services:
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.http.routers.myservice.rule=Host(`myservice.${DOMAIN}`)" - "traefik.http.routers.myservice.rule=Host(`myservice.${DOMAIN}`)"
- "traefik.http.routers.myservice.entrypoints=websecure" - "traefik.http.routers.myservice.entrypoints=websecure"
- "traefik.http.routers.myservice.tls.certresolver=letsencrypt" - "traefik.http.routers.myservice.tls=true" # Uses wildcard cert automatically
- "traefik.http.routers.myservice.middlewares=authelia@docker" - "traefik.http.routers.myservice.middlewares=authelia@docker"
- "traefik.http.services.myservice.loadbalancer.server.port=8080" - "traefik.http.services.myservice.loadbalancer.server.port=8080"
networks: networks:
@@ -218,6 +222,8 @@ traefik:
- "traefik.http.routers.traefik.rule=Host(`traefik.${DOMAIN}`)" - "traefik.http.routers.traefik.rule=Host(`traefik.${DOMAIN}`)"
- "traefik.http.routers.traefik.entrypoints=websecure" - "traefik.http.routers.traefik.entrypoints=websecure"
- "traefik.http.routers.traefik.tls.certresolver=letsencrypt" - "traefik.http.routers.traefik.tls.certresolver=letsencrypt"
- "traefik.http.routers.traefik.tls.domains[0].main=${DOMAIN}"
- "traefik.http.routers.traefik.tls.domains[0].sans=*.${DOMAIN}"
- "traefik.http.routers.traefik.middlewares=authelia@docker" - "traefik.http.routers.traefik.middlewares=authelia@docker"
- "traefik.http.routers.traefik.service=api@internal" - "traefik.http.routers.traefik.service=api@internal"
``` ```
@@ -344,6 +350,42 @@ docker inspect service-name | grep Networks
docker inspect service-name | grep traefik docker inspect service-name | grep traefik
``` ```
#### Wildcard Certificates with DuckDNS
**IMPORTANT:** When using DuckDNS for DNS challenge, only ONE service should request certificates:
```yaml
# ✅ CORRECT: Only Traefik requests wildcard certificate
traefik:
labels:
- "traefik.http.routers.traefik.tls.certresolver=letsencrypt"
- "traefik.http.routers.traefik.tls.domains[0].main=${DOMAIN}"
- "traefik.http.routers.traefik.tls.domains[0].sans=*.${DOMAIN}"
# ✅ CORRECT: Other services just enable TLS
other-service:
labels:
- "traefik.http.routers.service.tls=true" # Uses wildcard cert
# ❌ WRONG: Multiple services requesting individual certs
other-service:
labels:
- "traefik.http.routers.service.tls.certresolver=letsencrypt" # Causes conflicts!
```
**Why?** DuckDNS can only maintain ONE TXT record at `_acme-challenge.yourdomain.duckdns.org`. Multiple simultaneous certificate requests will fail with "Incorrect TXT record" errors.
**Solution:** Use a wildcard certificate (`*.yourdomain.duckdns.org`) that covers all subdomains.
**Verify Certificate:**
```bash
# Check wildcard certificate is obtained
python3 -c "import json; d=json.load(open('/opt/stacks/core/traefik/acme.json')); print(f'Certificates: {len(d[\"letsencrypt\"][\"Certificates\"])}')"
# Test certificate being served
echo | openssl s_client -connect yourdomain.duckdns.org:443 -servername yourdomain.duckdns.org 2>/dev/null | openssl x509 -noout -subject -issuer
```
#### SSL Certificate Issues #### SSL Certificate Issues
```bash ```bash
@@ -352,7 +394,7 @@ ls -la /opt/stacks/core/traefik/acme.json
# Should be: -rw------- (600) # Should be: -rw------- (600)
# Check certificate generation logs # Check certificate generation logs
docker logs traefik | grep acme docker exec traefik tail -50 /var/log/traefik/traefik.log | grep -E "acme|certificate"
# Verify ports 80/443 are accessible # Verify ports 80/443 are accessible
curl -I http://yourdomain.duckdns.org curl -I http://yourdomain.duckdns.org