Deployment & systemd
ngstoned is meant to run as a long-lived systemd service on the VPS, restarted automatically on crash and surviving reboots without re-issuing certificates.
The systemd unit#
[Unit]Description=ngstone edge serverAfter=network-online.targetWants=network-online.target [Service]Type=simpleExecStart=/usr/local/bin/ngstoned --domain ngstone.site --cert-email you@ngstone.siteDynamicUser=yesStateDirectory=ngstonedAmbientCapabilities=CAP_NET_BIND_SERVICENoNewPrivileges=yesEnvironmentFile=/etc/ngstoned/ngstoned.envRestart=alwaysRestartSec=2 [Install]WantedBy=multi-user.targetDynamicUser & StateDirectory#
DynamicUser=yes paired with StateDirectory=ngstoned is the mechanism systemd provides specifically to make dynamic, unprivileged users work with persistent state. systemd creates the directory under /var/lib/private/ and re-chowns it to the current transient UID on every service start, so the certificate cache survives restarts intact even though the UID changes each time.
Reference the certificate path via ${STATE_DIRECTORY}/certs (or the systemd-bind-mounted /var/lib/ngstoned/certs) rather than hardcoding /var/lib/private/... — the literal private path silently becomes a different, unmanaged directory if DynamicUser is ever removed from the unit.
Binding to port 443#
AmbientCapabilities=CAP_NET_BIND_SERVICE lets the process bind privileged ports without running as root. It composes cleanly with both DynamicUser=yes and NoNewPrivileges=yes — NoNewPrivileges only blocks privilege gain via setuid binaries or file capabilities; it does not strip an ambient capability the service manager itself granted.
Secrets#
Never pass secrets as ExecStart flags
/proc/<pid>/cmdline is world-readable on stock Linux, so a token hash or API token passed as a command-line flag is readable by any local user via ps auxww. Put NGSTONE_TOKEN_SHA256 and NGSTONE_CF_API_TOKEN in the unit's EnvironmentFile= instead — ngstoned reads both in preference to the equivalent -token-sha256/-cf-api-token flags for exactly this reason. (The plaintext token itself, NGSTONE_TOKEN, belongs on the agent side, not on the VPS.)Restart behavior#
Restart=always means a crash or OOM typically recovers in under two seconds. Because certificates are cached under StateDirectory, a restart makes zero ACME traffic — provided the unit is configured correctly. Get DynamicUser/StateDirectorywrong and every restart instead re-issues against Let's Encrypt's rate limits, which is the failure this unit is written specifically to avoid.