Lawliet LAWLIET
Book a demo

TLS and certificates

Agents verify the server's certificate on every call, as they should. That makes the certificate, and the names and addresses it covers, the most common reason an agent install fails. This page covers what the installer makes, switching encryption on and off, repairing a certificate that misses an address, and giving enrolled agents a new certificate.

HTTPS and lab mode

HTTPS is the default: nginx serves the console, the API and the agents on port 443. Lab mode serves plain HTTP on ports 3000 and 8000, so passwords and tokens cross the network in clear text; it is for an isolated lab only. Agents refuse a plain-HTTP server unless their installer is given --insecure (-Insecure on Windows), which exists for lab use.

Switch encryption on and off

sudo ./lawliet tls status
sudo ./lawliet tls off      # asks first; --yes skips the question
sudo ./lawliet tls on

An agent cannot be told a new server address, so the server keeps both doors open and no agent is reinstalled in either direction:

Encryption on (default)Encryption off
Console and APIhttps://<address>http://<address> on port 80
Port 80Sends browsers to HTTPS. Still answers the agent API, only for agents that enrolled over plain HTTP.The whole console and API
Port 443The console and APIStill up with the same certificate, so agents enrolled over HTTPS keep working
New install commands and deploymentshttps://, with the certificate arguments if it is self-signedhttp://

Each switch saves .env, the deployment settings and the certificate first, restarts only nginx and the backend, checks the result, and puts the saved configuration back if the check fails. ./lawliet update keeps the state. A plain-HTTP installation (ports 3000 and 8000) is moved behind nginx by tls on, keeping its data, secrets and agents.

Self-signed or your own certificate

./lawliet install asks for the address users and agents will reach, then for a certificate:

Servers reached by IP address

When an agent connects by IP address, it checks that the certificate carries that address as an IP entry (an IP subjectAltName). A certificate issued only for a host name fails that check, and the install stops with curl error 60, "no alternative certificate subject name matches target ipv4 address". So a certificate for a server reached by IP must list every address agents use, each as an IP: entry, and any host name as a DNS: entry.

./lawliet status, ./lawliet doctor and ./lawliet start list each address the certificate does not cover: certificate does not cover <ip>; run: sudo ./lawliet tls repair. The console's certificate card shows the same.

Repair a certificate with ./lawliet tls repair

sudo ./lawliet tls repair          # asks first when agents are enrolled
sudo ./lawliet tls repair --yes    # no question, for scripts

It re-issues a self-signed certificate for every address this server is reached by: the deployment address, the server's own IPv4 addresses (container bridges and loopback left out) and localhost, keeping every name the old certificate had. The new certificate is installed the way ./lawliet tls installs one: nginx tests it and reloads, and a pair nginx refuses is replaced by the previous one. The previous pair is kept as a backup readable by its owner only, and the addresses are added to TRUSTED_HOSTS. When nothing is missing it says certificate already covers ... and changes nothing. A self-signed certificate that has expired, or expires within 30 days, is re-issued the same way.

Trusted host names and addresses

The server answers only requests addressed to a name or address listed in TRUSTED_HOSTS in .env; any other request gets 403 "Invalid host header". The installer sets it to the address you gave and this server's own IPv4 addresses. ./lawliet tls and ./lawliet tls repair add the names and addresses the certificate covers.

If users or agents reach the server by another name, add it to TRUSTED_HOSTS (and to CORS_ORIGINS for the console) and run ./lawliet start.

Install your own certificate with ./lawliet tls

./lawliet tls shows the current certificate and replaces it with the certificate and key you give it, in PEM. A running nginx tests the new pair (nginx -t) and reloads without dropping connections, and the certificate's names and addresses are added to TRUSTED_HOSTS. If nginx refuses the new pair, the previous certificate and key are put back, nginx goes on serving them, and the command stops with nginx's reason.

For a self-signed certificate, use sudo ./lawliet tls repair instead of making one by hand.

Give agents the certificate

./lawliet tls --export writes lawliet-server.pem. Copy it to each host and pass it to the installer with --ca-cert <path> (-CaCert <path> on Windows). The commands that ./lawliet token and the console's Install agent print already carry the flag when the server uses a self-signed certificate, and an offline package carries the certificate itself. The agent then trusts exactly that certificate, and verification stays on.

Hosts enrolled before a certificate change

Hosts already enrolled show as offline once the server presents a new certificate. Give each the new one without reinstalling: export it with sudo ./lawliet tls --export, copy lawliet-server.pem to the host and run the installer the server serves with the refresh option.

HostCommand (as root or Administrator)
Linuxsudo bash install.sh --refresh-ca --ca-cert /path/to/lawliet-server.pem
Windowspowershell -ExecutionPolicy Bypass -File install.ps1 -RefreshCa -CaCert C:\path\to\lawliet-server.pem
macOSCopy the file over /etc/lawliet/server-ca.pem, then sudo launchctl kickstart -k system/com.lawliet.agent

The refresh checks the agent's server with the new certificate first and changes nothing if that fails, then replaces the agent's trust file (keeping the old one as server-ca.pem.previous) and restarts the agent. The agent keeps its identity; nothing is re-enrolled.