Local Root CA and auto-renewed HTTPS certificates for private networks and services
with automatic deployment to Pi-hole, Technitium, and Tailscale
local-https creates a local Root CA and issues a server certificate for your machine, so you can access web UIs over HTTPS without browser warnings (after trusting the Root CA on your devices).
It can automatically deploy certificates and reload supported services:
- β Pi-hole (FTL webserver or Lighttpd)
- β
Technitium DNS (uses a password-protected
.pfx) - β Tailscale (adds your Tailscale DNS name to the certificate SANs)
It is officially supported on Debian-based distributions (Debian, Ubuntu, Raspberry Pi OS, Armbian). Other Linux distributions may work but are not officially supported.
curl -fsSL https://raw.githubusercontent.com/luizbizzio/local-https/main/install.sh | sudo bashThe installer downloads and verifies the latest local-https, then installs it to /usr/local/sbin/local-https.
On a new installation, or if the initial setup was never completed, it asks whether you want to start the setup. If local-https is already configured, running the same command only updates the program and keeps your existing certificates and configuration.
- π Creates (or reuses) a local Root CA (
rootCA.crt) - πͺͺ Issues a server certificate (default: 40 days) with SANs for:
- hostname
- relevant LAN IPs (filtered)
- a configurable domain name (default
pi.hole) - Tailscale DNS name when available
- π¦ Generates:
server.pem(cert + key, for services like Pi-hole)server.pfx(password-protected, for services like Technitium)
- π Can enable automatic renewal via systemd timer (or cron fallback)
- β¬οΈ Can check GitHub for a newer version and update itself with
--update - π§ On renewal, it only βdeploys/restartsβ if a new cert was actually created (unless forced)
| Command | What it does |
|---|---|
local-https --version / --v / -V |
Prints the installed local-https version |
sudo local-https --update |
Checks GitHub for a newer version and asks before updating |
sudo local-https --update --yes |
Updates without asking for confirmation |
sudo local-https --install |
Full setup (Root CA, server cert, PEM/PFX, permissions, auto-renew, optional Pi-hole deploy, Technitium TLS if detected) |
sudo local-https --renew |
Renew if needed (near expiry window). If nothing to do, exits fast |
sudo local-https --renew --force-renew |
Forces a new server certificate + rebuilds PFX + restarts detected services |
sudo local-https --status |
Shows the installed version, current status, and last run info |
sudo local-https --check |
Exit code indicates if renewal is needed |
sudo local-https --configure |
Re-run deploy steps for Pi-hole / Technitium without reinstalling everything |
sudo local-https --print-ca |
Prints rootCA.crt (useful to copy to devices) |
sudo local-https --print-pfx-pass |
Prints the PFX password (stored in a root-only file) |
sudo local-https --rotate-pfx-pass |
Rotates PFX password, rebuilds PFX, updates Technitium TLS settings |
sudo local-https --uninstall [--yes] [--purge-certs] |
Removes installed files and optionally deletes generated certs |
Once installed, you can check for a newer version without using the full curl command again:
sudo local-https --updateIf a newer version is available, local-https shows the current and latest versions and asks before installing it. The update only replaces the program itself; your existing Root CA, certificates, state, and service configuration are kept.
For non-interactive updates:
sudo local-https --update --yesUse --configure when you want to re-detect and reapply supported service integrations without reinstalling local-https.
sudo local-https --configureThis re-checks Pi-hole and Technitium, reapplies certificate permissions and TLS deployment, and keeps your existing Root CA and installation.
This is useful after installing or changing Pi-hole or Technitium, or when you want to run the integration setup again.
The certificate includes a friendly domain name (default pi.hole). If your network uses a different local domain, you can configure it. The chosen domain is added to the certificate SANs and is remembered across renewals (stored in the state file).
The domain is resolved with the following precedence (highest first):
- CLI flag β
--domain(works with--install,--configure, and--renew):sudo local-https --install --domain home.lan sudo local-https --configure --domain dns.home sudo local-https --renew --force-renew --domain home.lan
- Environment variable β
LOCAL_HTTPS_DOMAIN:sudo LOCAL_HTTPS_DOMAIN=home.lan local-https --install
- Persisted state β whatever was chosen on the previous run (so renewals stay consistent).
- Pi-hole auto-detection β on a fresh install, if Pi-hole is detected the script reads its configured
webserver.domain(viapihole-FTL --config, falling back to/etc/pihole/pihole.toml) and uses that as the default. - Default β
pi.hole.
During an interactive --install/--configure you are also prompted, pre-filled with the resolved value (press Enter to keep it).
To change the domain on an existing install, run sudo local-https --configure --domain <name> (or sudo local-https --renew --force-renew --domain <name>). The Root CA stays the same, so there is nothing new to trust on your devices.
- π The server certificate is issued for 40 days.
- β³
--renewonly renews when the cert is close to expiry (default window: 7 days). - π§© If you enable systemd timer, it runs daily (with randomized delay).
Check the timer:
systemctl list-timers | grep local-https
systemctl status local-https-renew.timer --no-pagerSee logs:
journalctl -u local-https-renew.service -n 100 --no-pagerForce-run via systemd (without editing unit files):
sudo systemd-run --unit=local-https-renew-force --service-type=oneshot /usr/local/sbin/local-https --renew --force-renew- Detects Pi-hole automatically.
- Supports:
- FTL webserver TLS (Pi-hole 6+)
- Lighttpd TLS (older setups)
- On renew (when a new cert is created), it restarts the correct service so the new cert is used.
- If Technitium is detected, the script can configure Technitium Web UI TLS to use:
server.pfx+ the stored password
- Supports both legacy Technitium Linux installations running as root and newer non-root installations.
- If the Technitium
dns-serveraccount exists, it is automatically granted access to thecertsgroup. Custom non-root Technitium service users are supported as well. - If the Technitium systemd service restricts filesystem access,
local-httpsautomatically creates a systemd drop-in granting read-only access toserver.pfx. - On renew (when a new cert is created), it restarts the Technitium service so the new cert is loaded.
- If
tailscaleandjqare available, the script adds your Tailscale DNS name (likehost.ts.net) to the certificate SANs.
Any service that needs to read the certificate files can be granted access by adding its user to the certs group:
sudo usermod -aG certs grafana
sudo usermod -aG certs nginxGroup membership is preserved across renewals, once added, the service will continue to have access after every certificate rotation without any manual intervention.
Some hardened systemd services may also restrict filesystem access and require an explicit ReadOnlyPaths= rule for certificate files.
Default folder:
/etc/ssl/servercerts
Main files:
rootCA.crtandrootCA.key(local Root CA)server.crt,server.key,server.pemserver.pfxand.pfx-pass(password file)
State:
/var/lib/local-https/state.env
Technitium systemd integration (non-root installations only):
/etc/systemd/system/<technitium-service>.d/local-https.conf
You must trust rootCA.crt on your device to avoid HTTPS warnings.
Get the certificate from the server:
- Print in terminal:
sudo local-https --print-ca - Or copy the file:
/etc/ssl/servercerts/rootCA.crt
- Copy
rootCA.crtto your PC. - Double-click it β Install Certificate
- Choose Local Machine
- Put it in Trusted Root Certification Authorities
- Reopen the browser.
- Open Keychain Access
- Drag
rootCA.crtinto System keychain - Open the cert β set Trust to Always Trust
- AirDrop/email the
rootCA.crtto the device, open it - Settings β General β VPN & Device Management β install profile
- Settings β General β About β Certificate Trust Settings β enable full trust
- Copy
rootCA.crtto the phone - Settings β Security β Encryption & credentials β Install a certificate β CA certificate
- Note: some apps ignore user-installed CAs.
sudo cp rootCA.crt /usr/local/share/ca-certificates/local-https-rootCA.crt
sudo update-ca-certificatesPublic TLS Certificate Authorities and browser policies now favor shorter lifetimes (around 40β45 days) for security reasons. Our default 40-day validity matches this industry trend and avoids issues with browser trust and automated renewals. See SSL.comβs discussion on ~47-day certificates: https://www.ssl.com/article/preparing-for-47-day-ssl-tls-certificates/
- π·οΈ When reporting an issue, include the output of
local-https --version. - π§± This is a local CA. It is for your own network and devices, not public HTTPS.
- π§ͺ If you are testing renew: use
sudo local-https --renew --force-renewand confirm the newnotAfterdate with OpenSSL. - π§ Pi-hole Lighttpd mode may install
lighttpd-mod-opensslviaapt-get. - π³ Not intended for container-based TLS termination or Docker ingress setups.
- π§· The PFX password is stored in a root-only file. Treat it as a secret.
- π The
certsgroup membership is preserved on every renew, any user or service manually added to the group (e.g.grafana,nginx) will automatically retain access after certificate rotation.
This repository is licensed under the Mozilla Public License Version 2.0