Initial infrastructure documentation - comprehensive homelab reference
This commit is contained in:
460
infrastructure/LOCAL-CA-SETUP.md
Normal file
460
infrastructure/LOCAL-CA-SETUP.md
Normal file
@@ -0,0 +1,460 @@
|
||||
# Local Certificate Authority Setup
|
||||
|
||||
This document describes the setup of a local Certificate Authority (CA) for issuing HTTPS certificates to internal services.
|
||||
|
||||
## Overview
|
||||
|
||||
**Problem:** Internal services (Home Assistant, AD5M printer, Dockge, etc.) use HTTP, causing:
|
||||
- Browser security warnings
|
||||
- Some services refuse to work without HTTPS
|
||||
- Insecure credential transmission
|
||||
|
||||
**Solution:** Local CA using `step-ca` that issues trusted certificates for `.nianticbooks.home` domain.
|
||||
|
||||
## Architecture
|
||||
|
||||
### CA Server Location
|
||||
- **Host:** main-pve (10.0.10.3) - most reliable server
|
||||
- **Container:** LXC container for isolation
|
||||
- **IP:** 10.0.10.15 (reserved for ca-server)
|
||||
- **Domain:** ca.nianticbooks.home
|
||||
|
||||
### Services Requiring Certificates
|
||||
|
||||
| Service | Current IP | Domain | Port |
|
||||
|---------|-----------|---------|------|
|
||||
| Home Assistant | 10.0.10.24 | bob.nianticbooks.home | 8123 |
|
||||
| AD5M Printer | 10.0.10.30 | ad5m.nianticbooks.home | 80 |
|
||||
| Dockge | 10.0.10.27 | dockge.nianticbooks.home | 5001 |
|
||||
| Proxmox (main-pve) | 10.0.10.3 | freddesk.nianticbooks.home | 8006 |
|
||||
| Proxmox (pve-router) | 10.0.10.2 | pve-router.nianticbooks.home | 8006 |
|
||||
| OMV | 10.0.10.5 | omv.nianticbooks.home | 80 |
|
||||
|
||||
## Implementation Plan
|
||||
|
||||
### Phase 1: CA Server Setup
|
||||
|
||||
1. Create LXC container on main-pve
|
||||
2. Install step-ca
|
||||
3. Initialize CA with:
|
||||
- CA name: "Homelab Internal CA"
|
||||
- Domain: nianticbooks.home
|
||||
- Validity: 10 years (root), 1 year (leaf certificates)
|
||||
|
||||
### Phase 2: Certificate Generation
|
||||
|
||||
For each service, generate:
|
||||
- Server certificate
|
||||
- Private key
|
||||
- Auto-renewal script
|
||||
|
||||
### Phase 3: Service Configuration
|
||||
|
||||
Configure each service to:
|
||||
- Use generated certificate
|
||||
- Listen on HTTPS port
|
||||
- Optionally redirect HTTP → HTTPS
|
||||
|
||||
### Phase 4: Client Trust
|
||||
|
||||
Distribute root CA certificate to:
|
||||
- Linux clients (this computer, servers)
|
||||
- Windows clients
|
||||
- macOS clients
|
||||
- Mobile devices (iOS/Android)
|
||||
|
||||
## Step-by-Step Implementation
|
||||
|
||||
### 1. Create CA Server Container
|
||||
|
||||
```bash
|
||||
# On main-pve (10.0.10.3)
|
||||
pct create 115 local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst \
|
||||
--hostname ca-server \
|
||||
--cores 1 \
|
||||
--memory 512 \
|
||||
--swap 512 \
|
||||
--storage local-lvm \
|
||||
--rootfs 8 \
|
||||
--net0 name=eth0,bridge=vmbr0,ip=10.0.10.15/24,gw=10.0.10.1 \
|
||||
--unprivileged 1 \
|
||||
--features nesting=1 \
|
||||
--onboot 1
|
||||
|
||||
# Start container
|
||||
pct start 115
|
||||
|
||||
# Enter container
|
||||
pct enter 115
|
||||
```
|
||||
|
||||
### 2. Install step-ca
|
||||
|
||||
```bash
|
||||
# Inside container
|
||||
apt update && apt install -y wget
|
||||
|
||||
# Download step-ca
|
||||
wget https://dl.smallstep.com/gh-release/cli/gh-release-header/v0.25.0/step-cli_0.25.0_amd64.deb
|
||||
wget https://dl.smallstep.com/gh-release/certificates/gh-release-header/v0.25.0/step-ca_0.25.0_amd64.deb
|
||||
|
||||
# Install
|
||||
dpkg -i step-cli_0.25.0_amd64.deb step-ca_0.25.0_amd64.deb
|
||||
|
||||
# Verify
|
||||
step version
|
||||
step-ca version
|
||||
```
|
||||
|
||||
### 3. Initialize CA
|
||||
|
||||
```bash
|
||||
# Create CA user
|
||||
useradd -r -s /bin/bash -m -d /etc/step-ca step
|
||||
|
||||
# Initialize CA (as step user)
|
||||
su - step
|
||||
step ca init
|
||||
|
||||
# Configuration prompts:
|
||||
# Name: Homelab Internal CA
|
||||
# DNS: ca.nianticbooks.home
|
||||
# Address: :443
|
||||
# Provisioner: admin@nianticbooks.home
|
||||
# Password: [generate strong password, save to password manager]
|
||||
```
|
||||
|
||||
### 4. Configure CA Service
|
||||
|
||||
```bash
|
||||
# Create systemd service
|
||||
cat > /etc/systemd/system/step-ca.service <<'EOF'
|
||||
[Unit]
|
||||
Description=step-ca Certificate Authority
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=step
|
||||
Group=step
|
||||
WorkingDirectory=/etc/step-ca
|
||||
ExecStart=/usr/bin/step-ca /etc/step-ca/config/ca.json --password-file=/etc/step-ca/password.txt
|
||||
Restart=on-failure
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
# Store CA password securely
|
||||
echo "YOUR_CA_PASSWORD" > /etc/step-ca/password.txt
|
||||
chown step:step /etc/step-ca/password.txt
|
||||
chmod 600 /etc/step-ca/password.txt
|
||||
|
||||
# Enable and start
|
||||
systemctl daemon-reload
|
||||
systemctl enable step-ca
|
||||
systemctl start step-ca
|
||||
systemctl status step-ca
|
||||
```
|
||||
|
||||
### 5. Issue Certificates for Services
|
||||
|
||||
#### Home Assistant (bob.nianticbooks.home)
|
||||
|
||||
```bash
|
||||
# Generate certificate
|
||||
step certificate create bob.nianticbooks.home \
|
||||
bob.crt bob.key \
|
||||
--profile leaf \
|
||||
--not-after 8760h \
|
||||
--ca /etc/step-ca/certs/intermediate_ca.crt \
|
||||
--ca-key /etc/step-ca/secrets/intermediate_ca_key \
|
||||
--bundle
|
||||
|
||||
# Copy to Home Assistant
|
||||
scp bob.crt bob.key homeassistant.local:/ssl/
|
||||
```
|
||||
|
||||
Configure Home Assistant (`configuration.yaml`):
|
||||
```yaml
|
||||
http:
|
||||
ssl_certificate: /ssl/bob.crt
|
||||
ssl_key: /ssl/bob.key
|
||||
server_port: 8123
|
||||
```
|
||||
|
||||
#### AD5M Printer (Fluidd/Klipper)
|
||||
|
||||
```bash
|
||||
step certificate create ad5m.nianticbooks.home \
|
||||
ad5m.crt ad5m.key \
|
||||
--profile leaf \
|
||||
--not-after 8760h \
|
||||
--ca /etc/step-ca/certs/intermediate_ca.crt \
|
||||
--ca-key /etc/step-ca/secrets/intermediate_ca_key \
|
||||
--bundle
|
||||
|
||||
# Copy to printer
|
||||
scp ad5m.crt ad5m.key root@10.0.10.30:/etc/nginx/ssl/
|
||||
```
|
||||
|
||||
Configure nginx for Fluidd:
|
||||
```nginx
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name ad5m.nianticbooks.home;
|
||||
|
||||
ssl_certificate /etc/nginx/ssl/ad5m.crt;
|
||||
ssl_certificate_key /etc/nginx/ssl/ad5m.key;
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:80;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Dockge
|
||||
|
||||
```bash
|
||||
step certificate create dockge.nianticbooks.home \
|
||||
dockge.crt dockge.key \
|
||||
--profile leaf \
|
||||
--not-after 8760h \
|
||||
--ca /etc/step-ca/certs/intermediate_ca.crt \
|
||||
--ca-key /etc/step-ca/secrets/intermediate_ca_key \
|
||||
--bundle
|
||||
|
||||
# Copy to Dockge host
|
||||
```
|
||||
|
||||
#### Proxmox
|
||||
|
||||
```bash
|
||||
# Main PVE
|
||||
step certificate create freddesk.nianticbooks.home \
|
||||
freddesk.crt freddesk.key \
|
||||
--profile leaf \
|
||||
--not-after 8760h \
|
||||
--ca /etc/step-ca/certs/intermediate_ca.crt \
|
||||
--ca-key /etc/step-ca/secrets/intermediate_ca_key \
|
||||
--bundle
|
||||
|
||||
# Copy to Proxmox
|
||||
scp freddesk.crt freddesk.key root@10.0.10.3:/etc/pve/local/pveproxy-ssl.pem
|
||||
scp freddesk.key root@10.0.10.3:/etc/pve/local/pveproxy-ssl.key
|
||||
|
||||
# Restart Proxmox web service
|
||||
ssh root@10.0.10.3 "systemctl restart pveproxy"
|
||||
```
|
||||
|
||||
### 6. Certificate Auto-Renewal
|
||||
|
||||
Create renewal script on CA server:
|
||||
|
||||
```bash
|
||||
cat > /usr/local/bin/renew-certs.sh <<'EOF'
|
||||
#!/bin/bash
|
||||
# Auto-renew certificates for homelab services
|
||||
|
||||
SERVICES=(
|
||||
"bob.nianticbooks.home:10.0.10.24:/ssl/"
|
||||
"ad5m.nianticbooks.home:10.0.10.30:/etc/nginx/ssl/"
|
||||
"dockge.nianticbooks.home:10.0.10.27:/etc/ssl/"
|
||||
"freddesk.nianticbooks.home:10.0.10.3:/etc/pve/local/"
|
||||
)
|
||||
|
||||
for service in "${SERVICES[@]}"; do
|
||||
IFS=':' read -r domain ip path <<< "$service"
|
||||
|
||||
echo "Renewing certificate for $domain..."
|
||||
|
||||
# Check if certificate expires in < 30 days
|
||||
if step certificate needs-renewal "${domain}.crt"; then
|
||||
# Generate new certificate
|
||||
step certificate create "$domain" \
|
||||
"${domain}.crt" "${domain}.key" \
|
||||
--profile leaf \
|
||||
--not-after 8760h \
|
||||
--ca /etc/step-ca/certs/intermediate_ca.crt \
|
||||
--ca-key /etc/step-ca/secrets/intermediate_ca_key \
|
||||
--bundle --force
|
||||
|
||||
# Deploy to service
|
||||
scp "${domain}.crt" "${domain}.key" "root@${ip}:${path}"
|
||||
|
||||
# Restart service
|
||||
case "$domain" in
|
||||
bob.*)
|
||||
ssh root@${ip} "systemctl restart home-assistant@homeassistant"
|
||||
;;
|
||||
ad5m.*)
|
||||
ssh root@${ip} "systemctl restart nginx"
|
||||
;;
|
||||
freddesk.*)
|
||||
ssh root@${ip} "systemctl restart pveproxy"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "✓ Renewed $domain"
|
||||
fi
|
||||
done
|
||||
EOF
|
||||
|
||||
chmod +x /usr/local/bin/renew-certs.sh
|
||||
|
||||
# Add to crontab (weekly check)
|
||||
echo "0 2 * * 0 /usr/local/bin/renew-certs.sh" >> /etc/crontab
|
||||
```
|
||||
|
||||
### 7. Client Trust Configuration
|
||||
|
||||
#### Linux (Ubuntu/Debian)
|
||||
|
||||
```bash
|
||||
# Copy root CA certificate
|
||||
scp root@10.0.10.15:/etc/step-ca/certs/root_ca.crt /usr/local/share/ca-certificates/homelab-ca.crt
|
||||
|
||||
# Update trust store
|
||||
update-ca-certificates
|
||||
|
||||
# Verify
|
||||
curl https://bob.nianticbooks.home:8123
|
||||
```
|
||||
|
||||
#### Windows
|
||||
|
||||
1. Copy `root_ca.crt` to Windows machine
|
||||
2. Right-click → Install Certificate
|
||||
3. Store Location: Local Machine
|
||||
4. Certificate Store: Trusted Root Certification Authorities
|
||||
5. Click Next → Finish
|
||||
|
||||
#### macOS
|
||||
|
||||
```bash
|
||||
# Copy certificate
|
||||
scp root@10.0.10.15:/etc/step-ca/certs/root_ca.crt ~/Downloads/
|
||||
|
||||
# Import to keychain
|
||||
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ~/Downloads/root_ca.crt
|
||||
```
|
||||
|
||||
#### iOS/Android
|
||||
|
||||
1. Email `root_ca.crt` to device or host on web server
|
||||
2. Open certificate file on device
|
||||
3. Install profile
|
||||
4. iOS: Settings → General → About → Certificate Trust Settings → Enable
|
||||
5. Android: Settings → Security → Install from storage
|
||||
|
||||
## DNS Configuration
|
||||
|
||||
Ensure UCG Ultra has DNS entries for all services:
|
||||
|
||||
```
|
||||
bob.nianticbooks.home → 10.0.10.24
|
||||
ad5m.nianticbooks.home → 10.0.10.30
|
||||
dockge.nianticbooks.home → 10.0.10.27
|
||||
freddesk.nianticbooks.home → 10.0.10.3
|
||||
pve-router.nianticbooks.home → 10.0.10.2
|
||||
omv.nianticbooks.home → 10.0.10.5
|
||||
ca.nianticbooks.home → 10.0.10.15
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
Test each service:
|
||||
|
||||
```bash
|
||||
# Home Assistant
|
||||
curl -I https://bob.nianticbooks.home:8123
|
||||
|
||||
# AD5M
|
||||
curl -I https://ad5m.nianticbooks.home
|
||||
|
||||
# Dockge
|
||||
curl -I https://dockge.nianticbooks.home:5001
|
||||
|
||||
# Proxmox
|
||||
curl -I https://freddesk.nianticbooks.home:8006
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Certificate Not Trusted
|
||||
|
||||
```bash
|
||||
# Check if CA is in trust store
|
||||
ls /usr/local/share/ca-certificates/
|
||||
|
||||
# Verify certificate chain
|
||||
openssl s_client -connect bob.nianticbooks.home:8123 -showcerts
|
||||
|
||||
# Check certificate validity
|
||||
openssl x509 -in bob.crt -text -noout
|
||||
```
|
||||
|
||||
### Service Won't Start with HTTPS
|
||||
|
||||
```bash
|
||||
# Check certificate permissions
|
||||
ls -la /ssl/
|
||||
|
||||
# Check service logs
|
||||
journalctl -u home-assistant@homeassistant -f
|
||||
|
||||
# Verify certificate matches key
|
||||
openssl x509 -noout -modulus -in cert.crt | openssl md5
|
||||
openssl rsa -noout -modulus -in cert.key | openssl md5
|
||||
# Should match
|
||||
```
|
||||
|
||||
## Maintenance
|
||||
|
||||
### Certificate Expiry Monitoring
|
||||
|
||||
```bash
|
||||
# Check certificate expiration
|
||||
for cert in *.crt; do
|
||||
echo "$cert:"
|
||||
openssl x509 -in "$cert" -noout -dates
|
||||
done
|
||||
```
|
||||
|
||||
### Renewing Root CA
|
||||
|
||||
Root CA expires in 10 years. To renew:
|
||||
|
||||
1. Generate new root CA
|
||||
2. Issue new intermediate CA
|
||||
3. Re-issue all service certificates
|
||||
4. Update all client trust stores
|
||||
|
||||
## Security Considerations
|
||||
|
||||
- CA private key stored encrypted on CA server
|
||||
- CA server only accessible from local network
|
||||
- Certificate validity limited to 1 year
|
||||
- Auto-renewal prevents expiry
|
||||
- Root CA backed up to OMV storage
|
||||
|
||||
## Backup
|
||||
|
||||
```bash
|
||||
# Backup CA configuration
|
||||
rsync -av /etc/step-ca/ /mnt/omv-backup/ca-backup/$(date +%Y%m%d)/
|
||||
|
||||
# Store root CA password in password manager
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [ ] Create CA server LXC container
|
||||
- [ ] Install and configure step-ca
|
||||
- [ ] Generate certificates for all services
|
||||
- [ ] Configure services to use HTTPS
|
||||
- [ ] Distribute root CA to all devices
|
||||
- [ ] Set up auto-renewal
|
||||
- [ ] Test all services with HTTPS
|
||||
- [ ] Update Pangolin routes to use HTTPS backend
|
||||
Reference in New Issue
Block a user