Headless Pis lose /root/.ssh/authorized_keys to imaging, first-boot tooling, or config management, which locks out the only SSH account that can fix it. - ensure-root-ssh-key: idempotent POSIX sh installer. Appends managed public keys from /usr/local/share/root-ssh-keys/authorized_keys, never removes or rewrites foreign keys, skips lines whose first field is not a known key algorithm, and enforces 0700 / 0600 root:root on the key dir and file. - ensure-root-ssh-key.service: oneshot, ordered Before=ssh.service so the key lands before the daemon starts; ConditionPathExists skips it when the managed keys file is absent. - ensure-root-ssh-key.path: PathChanged= + PathModified= on authorized_keys so deletes, renames, and in-place edits are healed at runtime, not just at boot. Writes only when a key is missing, so the unit settles after one no-op run. - authorized_keys.example: template with commented placeholder keys only; the real file stays on the host. - root-ssh-key.md: runbook with deploy, verification, revocation steps, and the gotcha that systemd has no PathMissing= key. LLM-Generated: true
17 lines
578 B
SYSTEMD
17 lines
578 B
SYSTEMD
[Unit]
|
|
Description=Watch /root/.ssh/authorized_keys and re-install the managed root SSH key
|
|
Documentation=man:sshd(8)
|
|
After=local-fs.target
|
|
|
|
[Path]
|
|
# PathChanged covers deletion / rename / creation of the file,
|
|
# PathModified covers in-place edits (key stripped or file truncated).
|
|
# ensure-root-ssh-key.service only writes when a managed key is missing, so
|
|
# its own writes settle after one extra no-op run instead of looping.
|
|
PathChanged=/root/.ssh/authorized_keys
|
|
PathModified=/root/.ssh/authorized_keys
|
|
Unit=ensure-root-ssh-key.service
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|