5.1 KiB
SSL Certificates with Let's Encrypt and DuckDNS
Your homelab uses Let's Encrypt to automatically provide free SSL certificates for all your services. This ensures secure HTTPS connections without manual certificate management.
How SSL Certificates Work in Your Homelab
The Certificate Flow
- Domain Registration: DuckDNS provides your dynamic domain (e.g.,
yourname.duckdns.org) - Certificate Request: Traefik requests a wildcard certificate (
*.yourname.duckdns.org) - Domain Validation: Let's Encrypt validates you own the domain via DNS challenge
- Certificate Issuance: Free SSL certificate is issued and stored
- Automatic Renewal: Certificates renew automatically before expiration
DuckDNS + Let's Encrypt Integration
DuckDNS handles dynamic DNS updates, while Let's Encrypt provides certificates:
- DuckDNS: Updates your public IP → domain mapping every 5 minutes
- Let's Encrypt: Issues trusted SSL certificates via ACME protocol
- DNS Challenge: Proves domain ownership by setting TXT records
Wildcard Certificates Explained
Your setup uses a wildcard certificate (*.yourdomain.duckdns.org) that covers:
dockge.yourdomain.duckdns.orgplex.yourdomain.duckdns.orgjellyfin.yourdomain.duckdns.org- Any other subdomain automatically
Why wildcard? One certificate covers all services - no need for individual certificates per service.
Certificate Storage & Management
- Location:
/opt/stacks/core/traefik/acme.json - Permissions: Must be
600(read/write for owner only) - Backup: Always backup this file - contains your certificates
- Renewal: Automatic, 30 days before expiration
Testing vs Production Certificates
Staging Server (For Testing)
# In traefik.yml, add this line for testing:
caServer: https://acme-staging-v02.api.letsencrypt.org/directory
Staging Benefits:
- Unlimited certificates (no rate limits)
- Fast issuance for testing
- Not trusted by browsers (shows "Not Secure")
When to use staging:
- Setting up new environments
- Testing configurations
- Learning/development
Production Server (For Live Use)
# Remove or comment out caServer line for production
# certificatesResolvers:
# letsencrypt:
# acme:
# # No caServer = production
Production Limits:
This is why you want to use staging certificates for testing purposes!!! Always use staging certificates if you are running the setup & deploy scripts repeatedly
- 50 certificates per domain per week
- 5 duplicate certificates per week
- Trusted by all browsers
Certificate Troubleshooting
Check Certificate Status
# Count certificates in storage
python3 -c "import json; d=json.load(open('/opt/stacks/core/traefik/acme.json')); print(f'Certificates: {len(d[\"letsencrypt\"][\"Certificates\"])}')}"
Common Issues & Solutions
"Certificate not trusted" or "Not Secure" warnings:
- Staging certificates: Expected - use production for live sites
- DNS propagation: Wait 5-10 minutes after setup
- Browser cache: Clear browser cache and try incognito mode
Certificate request fails:
- Check Traefik logs:
docker logs traefik | grep -i certificate - Verify DuckDNS token is correct in
.env - Ensure ports 80/443 are open and forwarded
- Wait 1+ hours between certificate requests
Rate limit exceeded:
- Switch to staging server for testing
- Wait 1 week for production limits to reset
- Check status at: https://letsencrypt.org/docs/rate-limits/
DNS Challenge Process
When requesting certificates, Traefik:
- Asks DuckDNS to set TXT record:
_acme-challenge.yourdomain.duckdns.org - Let's Encrypt checks the TXT record to verify ownership
- If valid, certificate is issued
- TXT record is cleaned up automatically
Note: DuckDNS allows only ONE TXT record at a time. Multiple Traefik instances will conflict.
Certificate Validation Commands
# Test certificate validity
echo | openssl s_client -connect yourdomain.duckdns.org:443 -servername dockge.yourdomain.duckdns.org 2>/dev/null | openssl x509 -noout -subject -issuer -dates
# Check if certificate covers wildcards
echo | openssl s_client -connect yourdomain.duckdns.org:443 -servername any-subdomain.yourdomain.duckdns.org 2>/dev/null | openssl x509 -noout -text | grep "Subject Alternative Name"
Best Practices
For Production
- Use production Let's Encrypt server
- Backup
acme.jsonregularly - Monitor certificate expiration (Traefik dashboard)
- Keep DuckDNS token secure
For Development/Testing
- Use staging server to avoid rate limits
- Test with different subdomains
- Reset environments safely (preserve
acme.jsonif possible)
Security Notes
- Certificates are stored encrypted in
acme.json - Private keys never leave your server
- HTTPS provides encryption in transit
- Consider additional security headers in Traefik
Certificate Lifecycle
- Validity: 90 days
- Renewal: Automatic, 30 days before expiration
- Storage: Persistent across container restarts
- Backup: Include in your homelab backup strategy