Skip to content

Certificate Management

Griffen Fargo edited this page Jun 18, 2026 · 1 revision

Certificate Management

Manage Tailscale HTTPS certificates on remote hosts. Handles renewal, permission setup for Caddy, and service reload.

Since: v0.24.0

Overview

If you use Tailscale for internal networking and Caddy as a reverse proxy, strut automates the cert renewal lifecycle:

strut harbor cert:renew       # Renew cert + set permissions + reload Caddy
strut harbor cert:status      # Check certificate expiry

The host alias (harbor) resolves via [hosts] in strut.conf (see Multi-Host Topology).

Commands

cert:renew

Renews the Tailscale HTTPS certificate on a host:

  1. Ensures the cert directory exists
  2. Runs tailscale cert to generate/renew the certificate
  3. Sets ownership (root:caddy) and permissions (key mode 640)
  4. Reloads Caddy
strut harbor cert:renew
strut harbor cert:renew --dry-run

cert:status

Shows certificate details including subject, issuer, and expiry date:

strut harbor cert:status

Warns if the certificate expires within 14 days. Errors if already expired.

Configuration

Variable Default Description
CERT_DIR /etc/caddy/certs Remote directory for certificate files
CERT_OWNER root:caddy Ownership for cert and key files
CERT_KEY_MODE 640 File permissions for the private key
TAILSCALE_HOSTNAME Host alias Override the Tailscale MagicDNS hostname

Set these in strut.conf to override.

Certificate Paths

Certificates are stored at:

  • Cert: <CERT_DIR>/<hostname>.crt
  • Key: <CERT_DIR>/<hostname>.key

Where <hostname> is the Tailscale hostname (defaults to the host alias).

Prerequisites

On the remote host:

  • Tailscale installed and running with HTTPS enabled
  • openssl available (for cert:status)
  • Caddy running as a systemd service (for reload after renewal)

Automation

Combine with a cron job or scheduled task to auto-renew:

# In a CI pipeline or cron:
strut harbor cert:renew
strut compass cert:renew

Tailscale certs are valid for 90 days. Renewing early is safe (idempotent).

Clone this wiki locally