From 94a9ed900fe075a0febba36e0e732eddadb1f46f Mon Sep 17 00:00:00 2001 From: "Dustin C. Hatch" Date: Sat, 8 Feb 2025 17:11:10 -0600 Subject: [PATCH] autoprovision: Trigger host online webhook To initiate the automatic host provisioning process, a new machine must trigger the _POST /host/online_ webhook. Included in the request are the hostname of the new machine and its SSH host public keys. Optionally, the request can also contain the name of a branch in the configuration policy repository. For virtual machines, this branch name can be specified by a QEMU `fw_cfg` option. The `fw_cfg` values in sysfs are only readable by root, so the service must run as root, but it does not need any additional privileges, so we can use systemd sandbox features to restrict it. This feature is enabled by default for virtual machines. I haven't quite figured out how to do the branch selection for physical machines yet, but I will enable it for them once I do. --- autoprovision.ks | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ fedora.ks | 2 ++ 2 files changed, 71 insertions(+) create mode 100644 autoprovision.ks diff --git a/autoprovision.ks b/autoprovision.ks new file mode 100644 index 0000000..9727a9b --- /dev/null +++ b/autoprovision.ks @@ -0,0 +1,69 @@ +%post +cat > /root/.ssh/authorized_keys < /usr/local/libexec/notify-online.sh <<'EOF' +#!/bin/sh + +set -- \ + -F "hostname=$(hostname -f)" \ + -F 'sshkeys=<-;type=text/plain' + +fw_cfg=/sys/firmware/qemu_fw_cfg/by_name/opt/dch/cfg-branch/raw +if [ -r "${fw_cfg}" ]; then + set -- "$@" -F branch="$(cat "${fw_cfg}")" +fi + +cat /etc/ssh/ssh_host_*_key.pub \ +| curl -fsS https://webhooks.pyrocufflink.blue/host/online "$@" +EOF +chmod +x /usr/local/libexec/notify-online.sh + +cat > /etc/systemd/system/notify-online.service <<'EOF' +[Unit] +Description=Notify infrastructure services that this host is online +ConditionFirstBoot=yes +After=sshd.service +After=network-online.target +Wants=network-online.target +After=systemd-user-sessions.service + +[Service] +Type=exec +ExecStart=/usr/local/libexec/notify-online.sh +# Must run as root in order to read QEMU fw_config, so enable maximum +# sandbox restrictions. +CapabilityBoundingSet= +DeviceAllow= +DevicePolicy=closed +LockPersonality=yes +MemoryDenyWriteExecute=yes +NoNewPrivileges=yes +PrivateDevices=yes +PrivateUsers=yes +PrivateTmp=yes +ProcSubset=pid +ProtectClock=yes +ProtectControlGroups=yes +ProtectHome=yes +ProtectHostname=yes +ProtectKernelLogs=yes +ProtectKernelModules=yes +ProtectKernelTunables=yes +ProtectProc=invisible +ProtectSystem=strict +RestrictAddressFamilies=AF_INET AF_INET6 +RestrictNamespaces=yes +RestrictRealtime=yes +RestrictSUIDSGID=yes +SystemCallArchitectures=native +SystemCallFilter=@system-service +SystemCallFilter=~@privileged @resources + +[Install] +WantedBy=multi-user.target +EOF + +systemctl enable --no-reload notify-online.service +%end diff --git a/fedora.ks b/fedora.ks index ea5a103..14ee449 100644 --- a/fedora.ks +++ b/fedora.ks @@ -13,3 +13,5 @@ reqpart %packages qemu-guest-agent %end + +%include https://git.pyrocufflink.net/infra/kickstart/raw/branch/master/autoprovision.ks