52 lines
2.0 KiB
Desktop File
52 lines
2.0 KiB
Desktop File
[Unit]
|
|
Description=Fleet SSH host-certificate acquisition (TPM-authenticated, fleet SSH CA)
|
|
Documentation=https://git.bitasylum.org/audiobuzz/diskless-workstation/docs/ssh-host-certificate-design.md
|
|
# Needs the network up (dials step-ca) and sshd's per-boot host key to exist.
|
|
# sshd-keygen generates the host key before sshd starts, so ordering After sshd
|
|
# guarantees the key is present; sshd itself serves the bare key until we install
|
|
# the cert and reload it. All soft ordering (After, not Requires) — this unit is
|
|
# FAIL-OPEN: if the CA is unreachable or the host isn't enrolled yet, it exits
|
|
# non-zero WITHOUT touching sshd, and the timer retries.
|
|
After=network-online.target sshd.service
|
|
Wants=network-online.target
|
|
# Don't run in the throwaway build VM (no TPM, no enrolment, no network CA).
|
|
ConditionPathExists=/dev/tpmrm0
|
|
|
|
[Service]
|
|
Type=oneshot
|
|
EnvironmentFile=/etc/ssh-hostcert/ssh-hostcert.env
|
|
ExecStart=/usr/local/bin/fleet-ssh-hostcert
|
|
|
|
# Runs as root — unlike the DynamicUser agent — because it writes root-owned
|
|
# files under /etc/ssh and reloads sshd. Kept tightly sandboxed otherwise. The
|
|
# TPM private key never leaves the chip; root only drives signing through it.
|
|
User=root
|
|
# STIG-friendly sandbox. /etc/ssh must be writable (the cert + drop-in); the rest
|
|
# of the filesystem is read-only.
|
|
ProtectSystem=strict
|
|
ReadWritePaths=/etc/ssh
|
|
ProtectHome=yes
|
|
PrivateTmp=yes
|
|
DeviceAllow=/dev/tpmrm0 rw
|
|
NoNewPrivileges=yes
|
|
ProtectKernelTunables=yes
|
|
ProtectKernelModules=yes
|
|
ProtectKernelLogs=yes
|
|
ProtectControlGroups=yes
|
|
ProtectClock=yes
|
|
ProtectHostname=yes
|
|
RestrictNamespaces=yes
|
|
RestrictRealtime=yes
|
|
RestrictSUIDSGID=yes
|
|
LockPersonality=yes
|
|
MemoryDenyWriteExecute=yes
|
|
SystemCallArchitectures=native
|
|
SystemCallFilter=@system-service
|
|
SystemCallFilter=~@privileged @resources
|
|
# INET egress to step-ca; AF_UNIX for the journal + talking to systemd (reload
|
|
# sshd); AF_NETLINK for Go's interface/source-address selection.
|
|
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX AF_NETLINK
|
|
UMask=0022
|
|
|
|
# Triggered by ssh-hostcert.timer (boot + periodic renewal), not enabled directly.
|