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

4.0 KiB

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/:

# docker-compose.yml
nginx:
  volumes:
    - ./certs:/etc/nginx/certs:ro

Referenced in nginx.conf:

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:

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:

# 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:

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:

    # 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:

    {
      "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
  • Agent certificate renewal: plugins/endpoints/api/certificate_renewal.py
  • Client certificate authentication: shopdb/core/auth/client_cert.py
  • Nginx configuration: nginx.conf