HTTPS and certificates
Gamepads, Keyboard Lock and the microphone need HTTPS. Quasar makes and keeps its own certificate on first boot, so you don’t need one.
The default: Quasar’s own certificate
Section titled “The default: Quasar’s own certificate”On an owned install, the certificate’s names come from two seed inputs, read at the first install:
QUASAR_PUBLIC_HOST: "192.0.2.50" QUASAR_TLS_HOSTS: "quasar.lan,quasar.vpn.example"List every address anyone types into a browser: LAN IP, hostname, VPN address.
Changing them later means re-issuing the certificate (below). On a legacy Compose
install, set QUASAR_TLS_HOSTS in deploy/.env.
Trusting it on your devices
Section titled “Trusting it on your devices”Install the certificate in each device’s trust store instead of accepting the browser warning every time. Download it (no login needed; it’s public):
curl -k https://<host-ip>:8443/v1/tls/certificate.pem -o quasar.pemAdd quasar.pem to your platform’s trust store (macOS: Keychain Access, Always
Trust; Windows: Trusted Root Certification Authorities; Linux: usually
/usr/local/share/ca-certificates then update-ca-certificates).
Check the fingerprint first
Section titled “Check the fingerprint first”On a network you don’t control, compare the fingerprint with what the browser shows before the first visit, when the first admin is claimed:
docker logs quasar-control-plane 2>&1 | grep fingerprint(Legacy Compose: docker compose -f deploy/docker-compose.yml logs quasar-control-plane.)
Adding a name later
Section titled “Adding a name later”Owned install: change the names with reconfigure, then re-issue the certificate:
docker exec -it quasar-recovery quasar-recovery reconfigure --yes \ QUASAR_TLS_HOSTS=quasar.lan,quasar.vpn.example,192.0.2.50docker exec quasar-control-plane rm -f /var/lib/quasar-control/tls/cert.pem /var/lib/quasar-control/tls/key.pemdocker restart quasar-control-planeThe new fingerprint means browsers warn again, and separately added GPU hosts must be added again from Admin ▸ Fleet ▸ Add host (a combined host’s own agent is fine). To avoid this, use a name the certificate already has, or a reverse proxy.
Legacy Compose:
-
Add the name to
QUASAR_TLS_HOSTSindeploy/.env. -
Delete the existing pair.
Terminal window docker compose -f deploy/docker-compose.yml exec quasar-control-plane \rm -f /var/lib/quasar-control/tls/cert.pem /var/lib/quasar-control/tls/key.pem -
Recreate the container.
Terminal window docker compose -f deploy/docker-compose.yml up -d --force-recreate quasar-control-plane
Every browser and trust store needs the new certificate.
Supplying your own certificate
Section titled “Supplying your own certificate”Owned install: not supported in this release. Put a reverse proxy with your certificate in front.
Legacy Compose: mount both PEM files and set both (one alone stops startup):
QUASAR_TLS_CERT=/etc/quasar/tls/cert.pemQUASAR_TLS_KEY=/etc/quasar/tls/key.pemThe certificate needs:
- Every browser-facing name as a subject alternative name (IPs as IP SANs).
- The full chain, leaf first.
- An unencrypted private key.
- Extended key usage including server authentication.
Behind a reverse proxy
Section titled “Behind a reverse proxy”The proxy’s certificate is the one browsers see. Check allowed origins under Admin ▸ Settings. See Behind a reverse proxy.
Turning TLS off
Section titled “Turning TLS off”Legacy Compose only: QUASAR_TLS=off in deploy/.env. You lose gamepads,
Escape capture and the microphone unless something in front provides HTTPS. An
owned install always serves HTTPS; a proxy forwards to its HTTP port.
With TLS off, first-run setup and sign-in work only through a proxy named in
QUASAR_TRUSTED_PROXIES that sends X-Forwarded-Proto: https. Without one,
nobody can sign in.
Off by default. QUASAR_HSTS_MAX_AGE (seconds) makes the HTTPS listener send
Strict-Transport-Security: max-age=<n>; the HTTP port never does, and no
subdomains are named. On an owned install, on the first machine:
docker exec -it quasar-recovery quasar-recovery reconfigure --yes QUASAR_HSTS_MAX_AGE=86400An empty value turns it off again (a browser that already saw it keeps it until the max-age runs out). It needs a release whose control-plane image is recipe revision 4 or later; on an older one the command stops and says so.
HSTS pins the whole host name, on every port. Once a browser trusts the
certificate and has seen the header, any other http:// service on that name
(a NAS page, this control plane’s own HTTP port) is forced to HTTPS until the
max-age ends. Start with a short value such as 86400. IP addresses are never
pinned, and a browser that does not trust the certificate ignores the header.
It worked when curl -skI https://<console>:8443/health shows the header and
the same request to the HTTP port does not.
Settings
Section titled “Settings”Owned install (seed inputs):
| Seed input | Default | Purpose |
|---|---|---|
QUASAR_PUBLIC_HOST |
unset | The name or address of the console. The certificate claims it. |
QUASAR_TLS_HOSTS |
unset | More names and IPs for the certificate, comma-separated. |
QUASAR_HSTS_MAX_AGE |
unset (off) | Seconds of HSTS on the HTTPS listener. See HSTS. |
QUASAR_TLS_PORT |
8443 |
Host port for HTTPS. Browser routes on the HTTP port redirect here. |
QUASAR_HTTP_PORT |
8080 |
Host port for HTTP. |
Legacy Compose (deploy/.env):
| Setting | Default | Purpose |
|---|---|---|
QUASAR_TLS |
auto |
auto makes and keeps a self-signed pair. off disables HTTPS. |
QUASAR_TLS_HOSTS |
unset | Names and IPs the generated certificate claims. |
QUASAR_TLS_CERT / QUASAR_TLS_KEY |
unset | Your own PEM files. Set both. |
QUASAR_TLS_ADDR |
:8443 |
The HTTPS listener. |
LISTEN_ADDR |
:8080 |
The HTTP listener. |
QUASAR_HTTP_REDIRECT |
auto |
Redirects browser routes from HTTP to HTTPS. |
QUASAR_TLS_REDIRECT_PORT |
the TLS port | The external port to redirect to, if different. |