// docs · advanced install · manually
Install manually
Download a release binary, verify it, and run the systemd install yourself — the steps the one-liner automates, one at a time.
Download a release binary & verify
Every release ships pre-built static binaries. Check them against the published sha256sums.txt before you install:
# amd64 — for arm64 use syscert-linux-arm64
curl -fsSL https://github.com/tfindley/syscert/releases/latest/download/syscert-linux-amd64 -o syscert
chmod +x syscert
# verify against the published checksums
curl -fsSL https://github.com/tfindley/syscert/releases/latest/download/sha256sums.txt -o sha256sums.txt
sha256sum --check --ignore-missing sha256sums.txt
./syscert --help
Want a specific version? Swap latest/download for download/<tag> (say download/v0.3.0). See all releases.
Prefer to build it yourself? See Compile from source.
Install as a systemd service
The installer lives outside the binary. The syscert binary never touches your system; the script does, and you can run it as many times as you like. Point it at the binary you downloaded or built:
# need the packaging files? clone the repo into a named dir (no Go required)
git clone https://github.com/tfindley/syscert.git syscert-src
# point the installer at your downloaded or built binary (idempotent; needs root)
sudo syscert-src/packaging/install.sh ./syscert
That single command does a lot. It creates the syscert system user and /var/lib/syscert (0700), and installs the binary to /usr/local/bin/syscert. It writes a starter /etc/syscert/syscert.toml (0640 root:syscert, kept out of world-readable reach since it carries the internal CA URL and ACME email), a 0640 /etc/syscert/secrets, and an /etc/default/syscert for operator settings — existing files are never overwritten. Then it installs the units, enables the timer, and relabels for SELinux where that’s active. The binary gets relabeled too: /usr/local/bin/syscert becomes bin_t so systemd can execute it on an enforcing host. If you place the binary by hand instead of using the installer, run sudo restorecon /usr/local/bin/syscert to set the right label.
/usr/local/binand your PATH. The systemd unit calls the absolute/usr/local/bin/syscert, so the service never leans onPATH. When you run it by hand, though,/usr/local/binsometimes goes missing from asudosecure_pathor a minimal/nologinenvironment. Ifsyscertisn’t found, call/usr/local/bin/syscertdirectly or add the directory to yourPATH.
No systemd on this host (an appliance or NAS)? Run it as a cron job instead.
The user, service, and timer
syscert runs as a dedicated, no-login system user, never root. It owns the canonical store and gets just one capability from the unit, CAP_CHOWN, so it can set ownership on the copies it distributes. Add CAP_NET_BIND_SERVICE only if you use http-01/tls-alpn-01 on :80/:443.
syscert.service is a hardened oneshot that runs bare syscert (issue/renew as needed, then distribute):
[Unit]
Description=SysCert — ensure system TLS certificate is issued, renewed, and distributed
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
User=syscert
Group=syscert
EnvironmentFile=-/etc/default/syscert # operator settings, e.g. SYSCERT_CONFIG; optional
EnvironmentFile=-/etc/syscert/secrets # DNS/CA creds (0640); optional
ExecStart=/usr/local/bin/syscert # bare syscert = issue/renew as needed, then distribute
# Hardening (abridged)
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/var/lib/syscert
PrivateTmp=true
MemoryDenyWriteExecute=true
# CAP_CHOWN lets distribution set target ownership.
# Add CAP_NET_BIND_SERVICE only if you serve http-01/tls-alpn-01 on :80/:443.
AmbientCapabilities=CAP_CHOWN
CapabilityBoundingSet=CAP_CHOWN
There’s no long-running daemon. The timer firing bare syscert is the service: shortly after boot, then daily with jitter, and it catches up a missed run. install.sh enables the timer but doesn’t start it, so the first run can’t fail against the unconfigured starter config.
[Timer]
OnBootSec=5min
OnCalendar=daily
RandomizedDelaySec=12h
Persistent=true
Once you’ve edited the config, start it:
sudo systemctl start syscert.timer, then check withsystemctl list-timers syscert.timer. An Ansible role for fleet installs is on the roadmap, and it runs these same steps.
Removing it later? See Uninstall.
Next: Configuration · Compile from source · As a cron job