oCoreoCore Docs

SSL/TLS

Set up TLS certificates for oCore using Let's Encrypt, Caddy, or self-signed certificates.

TLS encryption is essential for protecting authentication tokens, API requests, and SSH credentials in transit. This guide covers several approaches to obtaining and managing certificates.

Let's Encrypt with Certbot

Certbot is the standard tool for obtaining free TLS certificates from Let's Encrypt. Use this approach with Nginx or standalone.

Install Certbot

# Ubuntu/Debian
sudo apt update
sudo apt install certbot python3-certbot-nginx

# Rocky Linux / RHEL
sudo dnf install certbot python3-certbot-nginx

Obtain a Certificate

With Nginx already configured and running:

sudo certbot --nginx -d ocore.example.com

Certbot automatically modifies your Nginx configuration to use the obtained certificate. For a standalone certificate (without modifying Nginx):

# Stop any service on port 80 first
sudo certbot certonly --standalone -d ocore.example.com

The certificate files are stored at:

FilePath
Full chain/etc/letsencrypt/live/ocore.example.com/fullchain.pem
Private key/etc/letsencrypt/live/ocore.example.com/privkey.pem

Automatic Renewal

Certbot installs a systemd timer or cron job for automatic renewal. Verify it is active:

# Check the renewal timer
sudo systemctl list-timers | grep certbot

# Test renewal without making changes
sudo certbot renew --dry-run

If the timer is not active, add a cron job:

# Edit crontab
sudo crontab -e

# Add renewal check twice daily
0 0,12 * * * certbot renew --quiet --deploy-hook "systemctl reload nginx"

The --deploy-hook reloads Nginx after a successful renewal so the new certificate is picked up without downtime.

Let's Encrypt with Caddy

If you use Caddy as your reverse proxy, TLS is fully automatic. Caddy obtains and renews certificates from Let's Encrypt or ZeroSSL without any configuration.

Simply specify your domain in the Caddyfile:

Caddyfile
ocore.example.com {
    reverse_proxy localhost:8080
}

Caddy will:

  1. Obtain a certificate on the first request to the domain
  2. Serve HTTPS by default (HTTP is automatically redirected)
  3. Renew the certificate before expiration
  4. Use OCSP stapling for improved performance

No cron jobs, no manual certificate management, no renewal hooks.

Certificate Storage

Caddy stores certificates at:

~/.local/share/caddy/certificates/

Or when running as a systemd service:

/var/lib/caddy/.local/share/caddy/certificates/

Self-Signed Certificates

For internal networks, development environments, or air-gapped deployments where Let's Encrypt is not available.

Generate a Self-Signed Certificate

# Create a directory for certificates
sudo mkdir -p /etc/ocore/tls

# Generate a private key and self-signed certificate (valid for 365 days)
sudo openssl req -x509 -nodes -days 365 \
  -newkey rsa:2048 \
  -keyout /etc/ocore/tls/ocore.key \
  -out /etc/ocore/tls/ocore.crt \
  -subj "/CN=ocore.example.com" \
  -addext "subjectAltName=DNS:ocore.example.com,IP:10.0.0.1"

Replace 10.0.0.1 with your server's internal IP if accessing by IP address.

Use with Nginx

server {
    listen 443 ssl http2;
    server_name ocore.example.com;

    ssl_certificate /etc/ocore/tls/ocore.crt;
    ssl_certificate_key /etc/ocore/tls/ocore.key;

    # ... proxy configuration
}

Trust the Certificate

Clients connecting to oCore will see a certificate warning unless they trust the self-signed certificate.

On the server (for API health checks):

sudo cp /etc/ocore/tls/ocore.crt /usr/local/share/ca-certificates/ocore.crt
sudo update-ca-certificates

On client machines, import the .crt file into the system or browser trust store.

TLS Best Practices

Protocol and Cipher Configuration

Restrict to TLS 1.2 and 1.3 with strong cipher suites:

Nginx TLS settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

HSTS

Enable HTTP Strict Transport Security to prevent protocol downgrade attacks:

add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;

Only enable includeSubDomains if all subdomains also serve HTTPS.

OCSP Stapling (Nginx)

ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 8.8.8.8 valid=300s;

Testing Your Configuration

Use SSL Labs to verify your TLS configuration after deployment:

# Quick local check with OpenSSL
openssl s_client -connect ocore.example.com:443 -tls1_3

An A+ rating on SSL Labs indicates a properly hardened configuration.

Was this page helpful?