Clients

Trantor's client side is split into three implementations that share the same protocol logic: a system daemon (terminus), a desktop GUI (terminus-gui), and per-platform mobile apps. They all do the same job — resolve encrypted DNS records, forge the matching TLS certificate, and inject it into the OS trust store — but they integrate with each operating system through a different mechanism.

Daemon — terminus #

The daemon is a Go binary that runs as a system service. It intercepts DNS queries for the configured domains, performs the Trantor resolution flow in the background, and keeps the OS trust store synchronized as the master passphrase rotates. Each operating system requires a different glue layer — but the protocol logic is shared.

OS DNS interception Trust store
Linux Hooks into systemd-resolved via D-Bus when present, otherwise rewrites /etc/resolv.conf directly. Drops the forged certificate into /usr/local/share/ca-certificates/ and runs update-ca-certificates.
Windows Uses the Name Resolution Policy Table (NRPT) to capture per-domain DNS at the OS level. Imports the certificate into the user's "Trusted Root Certification Authorities" store via the CertAddCertificateContextToStore API.
macOS Adds a per-domain entry under /etc/resolver/ that points the resolver at the local daemon. Adds the certificate to the user's Keychain with a "Always Trust" policy scoped to the relevant hostname.

CLI commands

sudo terminus start          # start the daemon
sudo terminus stop           # stop the daemon
sudo terminus reload         # re-read config and refresh records
sudo terminus status         # show active domains and last refresh
sudo terminus cache clear    # wipe local caches and force a fresh resolution
sudo terminus domain add    --name foo.bar.com --passphrase ...
sudo terminus domain remove --name foo.bar.com

Refresh cycle

Each managed domain is refreshed when its DNS TTL expires (the recommended TTL for Trantor records is 300 seconds, so the cadence is ~5 minutes — but the actual interval follows whatever TTL the server has published). The refresh is a compare-and-update rather than an unconditional re-write:

  1. Re-resolve the two phases of DNS records and decrypt them in memory.
  2. Rebuild the TLS certificate in memory using the private key just decrypted, the deterministic NotBefore / Serial, and ECDSA signing under RFC 6979.
  3. Compare the freshly built certificate, byte-for-byte, with the certificate currently stored in the OS trust store for that hostname (matched by Subject CN and the Trantor Subject-Organization marker).
  4. If they are identical → nothing to do; the trust store is left untouched (no syscalls, no log entries, no surprise prompts on platforms that ask for confirmation on cert changes).
  5. If they differ → the server has rotated (or the master passphrase has just been revoked); the trust store entry is replaced atomically with the new certificate. In-flight HTTPS connections keep running on the previous certificate until they close on their own.

This compare-and-update strategy is what keeps a fleet of Terminus daemons quiet: most TTL expirations end with no change at all, and the trust store is only touched on real rotations.

Discovery mode

An optional, off-by-default mode lets Terminus probe arbitrary hostnames for an empty-passphrase Trantor record before falling back to standard DNS. When enabled, every lookup for an unconfigured hostname triggers a Trantor query under Argon2id("", hostname, 16 MB) first; if no record is found, the daemon caches that negative result for one hour and lets the standard resolver answer.

Enable it via the daemon config:

{
  "discovery_mode": true
}

Trade-offs to weigh before turning it on:

  • Latency — every cache miss costs an extra Argon2id derivation plus a DNS round trip (~150–300 ms on a typical machine).
  • Observability — every hostname you visit produces a probe in your DNS provider's logs. The probe itself is indistinguishable from any other TXT lookup, but the access pattern (one TXT lookup per browsed hostname) is visible.
  • Coverage — only servers that opted into empty-passphrase mode (and published their record under Argon2id("", hostname)) are reachable this way. Standard-mode servers stay invisible without the user passphrase.

Use terminus cache clear to flush the negative cache when you suspect a server has just enabled empty-passphrase publishing.

Desktop GUI — terminus-gui #

For users who prefer not to edit configuration files, terminus-gui ships with the desktop installers as a Fyne-based tray application. It talks to the daemon over a local UNIX/named-pipe socket and exposes the same operations through point-and-click panels.

Linux / Windows / macOS

[Screenshot — desktop tray panel]

Tray icon shows connection state. Right-click to open the management panel: list of domains, add/remove, paste passphrase, view diagnostics.

Terminus iOS

[Screenshot — Terminus iOS]

Uses Apple's Network Extension framework to inject DNS interception and a per-domain certificate via a .mobileconfig profile. Distribution through the App Store once the app passes review.

Terminus Android

[Screenshot — Terminus Android]

Uses Android's VpnService API to capture DNS, and installs a user-added CA certificate scoped to the Trantor domains. Distribution through Google Play.

Source code #