Files
shopdb-flask/certs/README.md
Proudlock fd6240772e Add server certificate management documentation and regeneration scripts
Documentation:
- certs/README.md: Complete guide for managing nginx TLS certificates
- Server cert generation (self-signed, CA-signed, Let's Encrypt)
- Certificate expiry monitoring and renewal procedures
- Agent certificate pinning configuration
- Air-gapped deployment notes

Tooling:
- certs/regenerate-server-cert.sh: Bash script for cert regeneration
- certs/regenerate-server-cert.ps1: PowerShell script for Windows
- Both scripts backup old certs and display new thumbprint

Config:
- Updated .gitignore to allow cert management files (docs/scripts/config)
- Private keys and actual certificates still excluded (security)

Context:
- User asked where to manage server-side certificate
- Current cert: self-signed, CN=localhost, valid 1 year
- Agents validate server cert via pinning or Windows trusted roots
- Critical for mTLS client cert authentication (ADR-006)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-09-14 14:47:37 -04:00

141 lines
4.0 KiB
Markdown

# ShopDB Server Certificate Management
This directory contains the TLS certificates for ShopDB's nginx server.
## Current Certificate
- **File**: `server.crt` (certificate) and `server.key` (private key)
- **Common Name**: localhost
- **Subject Alternative Names**: localhost, 192.168.100.1
- **Validity**: 1 year from generation date
- **Type**: Self-signed (for development and air-gapped sites)
## Certificate Location
The `certs/` directory is mounted into the nginx container at `/etc/nginx/certs/`:
```yaml
# docker-compose.yml
nginx:
volumes:
- ./certs:/etc/nginx/certs:ro
```
Referenced in `nginx.conf`:
```nginx
ssl_certificate /etc/nginx/certs/server.crt;
ssl_certificate_key /etc/nginx/certs/server.key;
```
## Generating a New Server Certificate
### Option 1: Self-Signed (Development/Air-Gapped)
Generate a new self-signed certificate valid for 1 year:
```bash
cd certs
# Generate new private key and certificate
openssl req -x509 -newkey rsa:2048 -nodes \
-keyout server.key \
-out server.crt \
-days 365 \
-config openssl.cnf
# Restart nginx to pick up new certificate
docker-compose restart nginx
```
### Option 2: Custom Certificate (Production)
If you have a certificate from a trusted CA or internal PKI:
1. Copy your certificate to `certs/server.crt`
2. Copy your private key to `certs/server.key`
3. Update `certs/openssl.cnf` with the correct CN and SANs
4. Restart nginx: `docker-compose restart nginx`
### Option 3: Let's Encrypt (Public-Facing Sites)
For internet-accessible ShopDB instances, use Let's Encrypt:
```bash
# Install certbot
apt-get install certbot python3-certbot-nginx
# Generate certificate (interactive)
certbot --nginx -d your-domain.com
# Copy certificates to certs directory
cp /etc/letsencrypt/live/your-domain.com/fullchain.pem certs/server.crt
cp /etc/letsencrypt/live/your-domain.com/privkey.pem certs/server.key
# Restart nginx
docker-compose restart nginx
```
## Certificate Expiry
Check current certificate expiry:
```bash
openssl x509 -in certs/server.crt -noout -dates
```
ShopDB agents validate the server certificate using:
- **Pinning** (if `ServerCertThumbprint` configured in agent appsettings.json)
- **Windows trusted roots** (if no pinning configured)
## Agent Certificate Pinning
To enable server certificate pinning on agents:
1. Get the server certificate thumbprint:
```powershell
# Windows
certutil -hashfile certs\server.crt SHA256
# Or from certificate details
openssl x509 -in certs/server.crt -fingerprint -sha256 -noout
```
2. Update agent `appsettings.json`:
```json
{
"ServerCertThumbprint": "AA:BB:CC:DD:EE:FF:..."
}
```
3. Restart the agent service
**NOTE**: When you renew the server certificate, you must update `ServerCertThumbprint` on all agents before the old certificate expires, or agents will reject the new certificate.
## Air-Gapped Site Deployment
For air-gapped sites:
1. Generate certificate on work PC (with correct hostname/IP)
2. Include `certs/` directory in bundle (already in git repo)
3. Deploy bundle to site
4. Certificate deploys automatically with `docker-compose up`
## Certificate Files
- `server.crt` - Server certificate (nginx HTTPS)
- `server.key` - Server private key
- `openssl.cnf` - OpenSSL configuration for certificate generation
- `test-client.crt`, `test-client.key`, `test-client.p12` - Test client certificates (for development only)
## Security Notes
- **Private Key Protection**: `server.key` should be readable only by nginx (done via Docker volume mount)
- **Self-Signed Trust**: Self-signed certificates are expected in air-gapped environments
- **Agent Pinning**: Use `ServerCertThumbprint` to prevent MITM attacks with self-signed certs
- **Expiry Monitoring**: Set calendar reminders to renew certificates before expiry
## Related Documentation
- Agent certificate renewal: `plugins/endpoints/api/certificate_renewal.py`
- Client certificate authentication: `shopdb/core/auth/client_cert.py`
- Nginx configuration: `nginx.conf`