This guide uses 192.168.1.50 as a working example. Its certificate covers:

192-168-1-50.lancert.dev *.192-168-1-50.lancert.dev

Replace the IP address, domain names, and file paths in the examples below with your own environment values.

⚠️

For local development & LAN testing only

lancert private keys are publicly accessible by design: anyone can download the certificate and key for any supported private IP. While valid certificates eliminate browser warnings, they do not prove device identity. Do not use these certificates in production or on untrusted networks.

01

Download Certificate & Key

Trigger certificate issuance for your LAN IP via HTTP API, then download the PEM files:

bash — trigger issuance
# Issuance via Let's Encrypt DNS-01 challenge takes ~5-10s $ curl --fail -X POST https://lancert.dev/certs/192.168.1.50

Once ready, save the fullchain certificate and private key to your local config folder:

bash — save certificate files
IP=192.168.1.50 CERT_DIR="$HOME/.config/lancert/$IP"
mkdir -p "$CERT_DIR" curl --fail -o "$CERT_DIR/fullchain.pem" "https://lancert.dev/certs/$IP/fullchain.pem" curl --fail -o "$CERT_DIR/privkey.pem" "https://lancert.dev/certs/$IP/privkey.pem" chmod 600 "$CERT_DIR/privkey.pem"
02

Configure Your Web Server

Select your reverse proxy or web server below to view the configuration snippet and reload command:

Point the tls directive in your Caddyfile at the downloaded certificate files:

Caddyfile
192-168-1-50.lancert.dev, *.192-168-1-50.lancert.dev { tls /home/alice/.config/lancert/192.168.1.50/fullchain.pem /home/alice/.config/lancert/192.168.1.50/privkey.pem reverse_proxy 127.0.0.1:3000 }

Reload Caddy to apply the new certificates:

bash — reload Caddy
$ caddy reload --force --config /path/to/Caddyfile

💡 --force tells Caddy to reload manually provided certificates even if the Caddyfile text hasn't changed.

03

Automated Renewal Script

lancert certificates renew automatically on our servers. To fetch updated certificates and reload your web server without unnecessary restarts, use this POSIX shell helper script:

Save script as ~/.local/bin/lancert-update:

lancert-update
#!/bin/sh set -eu
if [ "$#" -lt 3 ] || [ "$2" != "--" ]; then echo "usage: lancert-update IP -- RELOAD [ARG ...]" >&2 exit 2 fi
ip=$1 shift 2
dest="${XDG_CONFIG_HOME:-"$HOME/.config"}/lancert/$ip" url="https://lancert.dev/certs/$ip"
mkdir -p "$dest" tmp=$(mktemp -d "$dest/.update.XXXXXX") trap 'rm -rf "$tmp"' EXIT HUP INT TERM
curl --fail -o "$tmp/fullchain.pem" "$url/fullchain.pem" curl --fail -o "$tmp/privkey.pem" "$url/privkey.pem"
# Verify public/private key cryptographic match cert_key=$(openssl x509 -in "$tmp/fullchain.pem" -pubkey -noout | openssl pkey -pubin -outform DER 2>/dev/null | openssl dgst -sha256) private_key=$(openssl pkey -in "$tmp/privkey.pem" -pubout -outform DER 2>/dev/null | openssl dgst -sha256)
if [ "$cert_key" != "$private_key" ]; then echo "certificate and private key do not match" >&2 exit 1 fi
# Skip reload if certificate hasn't changed if [ -f "$dest/fullchain.pem" ] && cmp -s "$tmp/fullchain.pem" "$dest/fullchain.pem"; then exit 0 fi
chmod 644 "$tmp/fullchain.pem" chmod 600 "$tmp/privkey.pem" mv "$tmp/fullchain.pem" "$dest/fullchain.pem" mv "$tmp/privkey.pem" "$dest/privkey.pem"
"$@"

Make it executable:

bash — chmod
$ mkdir -p "$HOME/.local/bin" && chmod 755 "$HOME/.local/bin/lancert-update"

Run daily with cron or your preferred scheduler:

cron — Caddy renewal invocation
$ "$HOME/.local/bin/lancert-update" 192.168.1.50 -- \ caddy reload --force --config /path/to/Caddyfile
04

Verify the Served TLS Certificate

Check that your web server serves the certificate for your LAN hostname. You can open the hostname in a browser or test it with curl; use OpenSSL when you need to inspect certificate details or verify the SNI response:

bash — optional OpenSSL handshake check
echo | openssl s_client \ -connect 192.168.1.50:443 \ -servername 192-168-1-50.lancert.dev 2>/dev/null | \ openssl x509 -noout -subject -issuer -dates

💡 Any covered subdomain works as SNI servername (e.g. app.192-168-1-50.lancert.dev).

Troubleshooting & FAQ

The download returns HTTP 404

The certificate may not exist yet on the server. Send a POST https://lancert.dev/certs/{ip} request first, wait 5–10 seconds for Let's Encrypt issuance, and retry downloading.

The browser shows a certificate warning or mismatch

Ensure you are connecting using a *.lancert.dev hostname (e.g. https://192-168-1-50.lancert.dev) rather than accessing the raw IP address directly in the browser location bar.

The certificate was renewed on disk but the server still serves the old one

Your web server has not reloaded the new certificate files from disk. Execute a reload command (e.g. caddy reload --force or nginx -s reload) or ensure your Traefik file provider is set to watch: true.