Compare commits

...

4 Commits

Author SHA1 Message Date
Dustin 91af50acc2 nut0: Add host Ignition config
*nut0.pyrocufflink.blue* is a Raspberry Pi 3 that will run `upsd` and
`upsmon` to monitor and control the UPS on the server rack.
2024-01-19 21:56:52 -06:00
Dustin 05d5312382 fix-hybrid-mbr: Fix Hybrid GPT/MBR on RPi3
When Fedora CoreOS first boots, Ignition modifies the partition table,
either to add partitions as requested in the config, or just to resize
the root filesystem.  In any case, this has the side effect of erasing
the hybrid MBR partition table.  If the hybrid MBR table is missing or
incorrect, Raspberry Pi 2 and 3 devices will not be able to boot.  We
must therefore rebuild the missing table on first boot after Ignition
has run.
2024-01-17 20:30:34 -06:00
Dustin 196ce46d54 cfg: Add apply-config-policy container unit
The *apply-config-policy* service does what it says on the tin.  It
fetches the *cfg.git* repository and applies the configuration policy
therein for the current host.  This is a privileged container with
practically allisolation disabled, to allow the configuration tools to
manage the system.
2024-01-17 20:30:34 -06:00
Dustin 647cdb8346 ssh-host-certs: Run sshca-cli from a container
Installing packages on the host system via `rpm-ostree` is _insanely_
slow, especially on Raspberry Pi devices.  The main reason I chose to go
that route for managing the SSH host certificates was to avoid having to
maintain the systemd units in multiple places.  I think the trade-off is
worth it, though; bringing up a new Raspberry Pi is significantly
faster, by 15+ minutes, if we do not have to wait for `rpm-ostree` at
all.
2024-01-17 20:30:34 -06:00
9 changed files with 165 additions and 13 deletions

View File

@ -0,0 +1,27 @@
# vim: set ft=systemd :
[Unit]
Description=Apply Configuration Policy
Wants=network-online.target
After=network-online.target
After=install-packages.service
After=ssh-host-certs.service
[Container]
Image=git.pyrocufflink.net/infra/cfg:latest
Pull=newer
Environment=RUST_LOG=debug
Volume=/:/host:rw
Volume=/run:/run:rw
Tmpfs=/root
ReadOnly=true
VolatileTmp=true
SecurityLabelDisable=true
PodmanArgs=--uts=host --cgroupns=host --ipc=host --pid=host --privileged
Network=host
LogDriver=passthrough
[Service]
Type=oneshot
[Install]
WantedBy=multi-user.target

14
cfg.yaml Normal file
View File

@ -0,0 +1,14 @@
variant: fcos
version: 1.4.0
storage:
files:
- path: /etc/containers/systemd/apply-config-policy.container
mode: 0644
contents:
local: apply-config-policy.container
systemd:
units:
- name: apply-config-policy.service
enabled: true

36
fix-hybrid-mbr.yaml Normal file
View File

@ -0,0 +1,36 @@
variant: fcos
version: 1.4.0
storage:
files:
- path: /etc/ignition/fix-hybrid-mbr.sh
mode: 0755
contents:
inline: |-
#!/bin/sh
set -ex
bootdev=$(awk '$5=="/boot"{print $10}' /proc/1/mountinfo)
sysdev=$(readlink -e /sys/class/block/${bootdev##*/})
sysdev_parent=${sysdev%/*}
disk=/dev/${sysdev_parent##*/}
sgdisk -h 2:EE "${disk}"
echo type=0c,bootable | sfdisk -Y mbr -N 1 "${disk}"
systemd:
units:
- name: fix-hybrid-mbr.service
contents: |-
[Unit]
Description=Fix Hybrid MBR for Raspberry Pi 2/3
ConditionFirstBoot=yes
[Service]
Type=oneshot
ExecStart=/etc/ignition/fix-hybrid-mbr.sh
[Install]
WantedBy=basic.target
enabled: true

17
nut0.yaml Normal file
View File

@ -0,0 +1,17 @@
variant: fcos
version: 1.4.0
ignition:
config:
merge:
- local: fix-hybrid-mbr.ign
- local: common.ign
- local: zram.ign
- local: cfg.ign
storage:
files:
- path: /etc/hostname
mode: 0644
contents:
inline: nut0.pyrocufflink.blue

View File

@ -0,0 +1,22 @@
[Unit]
Description=Request %I SSH Host Certificate
After=network-online.target
Wants=network-online.target
Before=ssh-host-certs.service
[Service]
Type=oneshot
[Container]
Image=git.pyrocufflink.net/containerimages/sshca-cli
Pull=newer
EnvironmentFile=/etc/sysconfig/ssh-host-cert-sign
Exec=host sign --output /etc/ssh/ssh_host_%I_key-cert.pub /etc/ssh/ssh_host_%I_key.pub
Volume=/etc/ssh:/etc/ssh:rw
Volume=/sys/firmware:/sys/firmware:ro
Volume=/sys/class/dmi/id:/sys/class/dmi/id:ro
Network=host
SecurityLabelDisable=yes
ContainerName=%p-%i
PodmanArgs=--uts=host
PodmanArgs=--security-opt=unmask=/sys/firmware

View File

@ -0,0 +1,7 @@
# vim: set ft=systemd :
[Unit]
Description=Request SSH Host Certificates
StopWhenUnneeded=yes
Wants=ssh-host-cert-sign@ed25519.service
Wants=ssh-host-cert-sign@rsa.service
Wants=ssh-host-cert-sign@ecdsa.service

View File

@ -0,0 +1,12 @@
# vim: set ft=systemd :
[Unit]
Description=Periodically renew SSH host certificates
[Timer]
Unit=%N.target
OnCalendar=Tue *-*-* 00:00:00
RandomizedDelaySec=48h
Persistent=yes
[Install]
WantedBy=timers.target

12
ssh-host-certs.service Normal file
View File

@ -0,0 +1,12 @@
# vim: set ft=systemd :
[Unit]
Description=Request SSH Host Certificates
ConditionFirstBoot=yes
Wants=ssh-host-certs-renew.target
[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl disable %n
[Install]
WantedBy=multi-user.target

View File

@ -1,18 +1,12 @@
variant: fcos
version: 1.4.0
ignition:
config:
merge:
- local: dch-repo.ign
storage:
files:
- path: /etc/ignition/packages.d/sshca
- path: /etc/containers/systemd/ssh-host-cert-sign@.container
mode: 0644
contents:
inline: |
sshca-cli-systemd
local: ssh-host-cert-sign@.container
- path: /etc/ssh/sshd_config.d/10-hostcertificate.conf
mode: 0644
@ -28,13 +22,24 @@ storage:
inline: |
SSHCA_SERVER=https://sshca.pyrocufflink.blue
links:
- path: /etc/systemd/system/after-install.target.wants/ssh-host-certs.target
target: /usr/lib/systemd/system/ssh-host-certs.target
- path: /etc/systemd/system/after-install.target.wants/ssh-host-certs-renew.timer
target: /usr/lib/systemd/system/ssh-host-certs-renew.timer
- path: /etc/systemd/system/ssh-host-certs-renew.timer
mode: 0644
contents:
local: ssh-host-certs-renew.timer
- path: /etc/systemd/system/ssh-host-certs-renew.target
mode: 0644
contents:
local: ssh-host-certs-renew.target
- path: /etc/systemd/system/ssh-host-certs.service
mode: 0644
contents:
local: ssh-host-certs.service
systemd:
units:
- name: ssh-host-certs.service
enabled: true
- name: ssh-host-certs-renew.timer
enabled: true