Skip to content

ts certificate ​

Show or change how a server's Gateway serves HTTPS: with a certificate you upload, with one Let's Encrypt issues, behind a proxy that terminates HTTPS, or not at all. When the certificate has expired and browsers refuse the site, run ts certificate on the server with --local.

Usage ​

text
ts certificate [print] <server>
ts certificate set <server> <file> [--passphrase-file=FILE]
ts certificate lets-encrypt <server> --hostname=NAME... --email=ADDRESS --accept-terms [--force]
ts certificate external-proxy <server>
ts certificate clear <server> [--force]

Description ​

HTTPS is set on the server that runs the Gateway, which is the Controller. Name it as ts servers lists it, in any case; any other server is refused. The same settings are on the server's Settings tab, under TLS, in Infrastructure → Servers.

print, the default, shows the mode in force. For an uploaded certificate it also shows the subject, issuer, hostnames, expiry and thumbprint, read from the certificate the Gateway serves; for Let's Encrypt, the hostnames and the contact email, with no expiry. The Gateway renews a Let's Encrypt certificate itself, and its log reports issuance and renewal: read it with ts logs <server> Gateway.

set, lets-encrypt and external-proxy each replace whatever mode was in force. Every change is recorded in the audit log with who made it.

Uploading a Certificate ​

set serves a PEM file or a PFX. A PEM file holds the server certificate first, then its intermediates, and its private key, which must not be encrypted. A PFX holds its own key; put its passphrase in a file and pass --passphrase-file, which ignores a trailing newline. The file is checked as the Administration site's upload checks it, and refused with the reason when it has no private key, the key does not belong to the first certificate, the PFX does not open with the passphrase, the certificate has expired, or the file is over 256 KB. The Gateway sends the intermediates in the handshake and serves the new certificate within a minute.

Let's Encrypt ​

lets-encrypt has the Gateway request one certificate covering every --hostname from Let's Encrypt, and renew it. It needs --email, the contact address the Gateway's Let's Encrypt account registers with, and --accept-terms, your acceptance of the Let's Encrypt subscriber agreement.

Each hostname must resolve publicly to this server. A name that does not look public is reported with the reason: a single-label name, a loopback name, a .local name, a reserved suffix such as .internal, .corp or .lan, or an IP address, for which Let's Encrypt does not issue. ts then asks whether to request the certificate anyway, and --force answers yes. The Gateway restarts shortly and requests the certificate, which can take a few minutes; its log reports issuance and renewal.

External Proxy ​

external-proxy has the Gateway serve HTTP to a proxy in front of it that terminates HTTPS, while Turbo publishes HTTPS addresses to clients. The proxy must send X-Forwarded-For, X-Forwarded-Proto and X-Forwarded-Host. The Gateway trusts these only from the server's own addresses, so for a proxy on another machine add its address or CIDR range to TURBOSERVER_TRUSTED_PROXIES in turbo.env and restart Turbo Server. The Gateway restarts shortly.

Turning HTTPS Off ​

clear turns HTTPS off: the Gateway restarts shortly and serves HTTP only, and Turbo publishes HTTP addresses. It asks first, and --force answers yes. A server with no mode in force is left as it is.

WARNING

Browsers that received HSTS from this server keep requiring HTTPS for up to 30 days after clear.

When Browsers Refuse the Site ​

Without --local, ts reaches the API through the Gateway, over the same HTTPS the browsers refuse, so it cannot connect either and exits -3. Run ts on the server with --local instead. It takes a token from the install's own service credential and calls the API over loopback, without the Gateway or its certificate, and needs root or an administrator on that machine. From there, set a new certificate, or clear HTTPS until you have one.

Options ​

FlagDescriptionDefault/ValuesNotes
--passphrase-fileA file holding the PFX's passphrase.FILEset only. A trailing newline is ignored.
--hostnameA hostname the Let's Encrypt certificate covers.NAMElets-encrypt only, and required there. Repeat it, or separate names with commas.
--emailThe contact email for the Gateway's Let's Encrypt account.ADDRESSlets-encrypt only, and required there.
--accept-termsAccept the Let's Encrypt subscriber agreement.lets-encrypt only, and required there.
--force, -fAnswer the question clear or lets-encrypt asks.Required for either question when there is no terminal. For lets-encrypt, requests a certificate for a hostname that does not look public.
--localTarget the install on this machine with a service token.Reaches the API without the Gateway, so it works when browsers refuse the site. Run it on the server as root or an administrator.

Examples ​

bash
# How does the Controller serve HTTPS, and when does an uploaded certificate expire?
ts certificate srv01

# The certificate has expired: replace it from the server itself
ts --local certificate set srv01 fullchain.pem

# Upload a PFX, with its passphrase kept in a file
ts certificate set srv01 turbo.pfx --passphrase-file=pfx-passphrase.txt

# Have Let's Encrypt issue and renew one certificate for two names
ts certificate lets-encrypt srv01 --hostname=turbo.example.com,apps.example.com \
  [email protected] --accept-terms

# Watch the Gateway request it
ts logs srv01 Gateway --tail 50

# A load balancer terminates HTTPS in front of the Gateway
ts certificate external-proxy srv01

# Serve HTTP only, from the server, without being asked
ts --local certificate clear srv01 --force
bash
# Once the certificate has expired, ts without --local cannot connect either,
# and exits -3. Run this on the server with --local instead.
ts certificate set srv01 fullchain.pem

Output ​

text
Server:     srv01
Mode:       Uploaded certificate
Subject:    CN=turbo.example.com
Issuer:     CN=Example Issuing CA, O=Example Corp, C=US
Hostnames:  turbo.example.com, apps.example.com
Expires:    2027-01-14 23:59 (85 days left)
Thumbprint: 3A7F0C92D4E1B85A6C0F2E9D17B4A3C58E6F1D20

The expiry is in this machine's time zone, with the days left, (less than a day left), or (expired). Let's Encrypt prints its hostnames and contact; an external proxy prints only its mode, External proxy, which holds the certificate; a server with no mode prints srv01 has no HTTPS certificate.

text
Server:     srv01
Mode:       Let's Encrypt, renewed by the Gateway
Hostnames:  turbo.example.com, apps.example.com
Contact:    [email protected]

set, lets-encrypt and external-proxy print the new state, then what happens next, such as Saved. The Gateway starts serving it within a minute. clear prints only what happens next.

Exit Codes ​

0 on success, including a clear with no mode to turn off. -1 when the command or the server refuses the change: a missing server or file argument, lets-encrypt without --hostname, --email or --accept-terms, a malformed hostname or email, a hostname that does not look public with no terminal to ask and no --force, a clear with no terminal and no --force, a question answered no, a server that does not run the Gateway, or a certificate file refused for any of the reasons above. -3 when the server cannot be reached, including over a certificate ts will not trust. -4 when no account is signed in. -5 when the account is not a Server Administrator, or --local cannot read the service credential. -6 when no server has that name, or the certificate or passphrase file does not exist.

  • ts server — The servers, and which of them is the Controller.
  • ts logs — The Gateway's log, which reports Let's Encrypt issuance and renewal.
  • ts status — Whether the server is answering, from here or with --local on the server.
  • ts audit — Who changed how the Gateway serves HTTPS, and when.