From 2f5b1fa3df0b49c5453aee19520e9a090794d044 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Fri, 10 Jul 2026 09:24:56 +0300 Subject: packages+frontends: dtail packaging follow-ups (vs0 review items) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - dtail-freebsd.json.tpl: move HostKeyFile from volatile /var/run/dserver/cache to persistent /var/db/dserver/ssh_host_key — FreeBSD's cleanvar purges /var/run at boot, so the host key was regenerated on every reboot (mirrors the NetBSD/OpenBSD templates) - dserver-freebsd.tpl rc.d: start_precmd now creates /var/db/dserver (0700, dserver-owned) and re-runs dserver-update-key-cache.sh on every start, so the volatile key cache repopulates right after a reboot or restart instead of waiting for the daily periodic job - packages/Makefile: .SHELLFLAGS gains -o pipefail — the "git archive | ssh ... tar" pipeline could mask a git archive failure as long as tar succeeded on the truncated stream (the only recipe-level pipeline; $(shell ...) calls are unaffected) - packages/Makefile: OS-suffixed /tmp staging names for the OpenBSD and NetBSD dtail tgz (dtail-openbsd-*/dtail-netbsd-*) — a dash-less version would have made both targets stage to the same /tmp/dtail-.tgz locally and on f0; the final repo copy keeps the canonical dtail-.tgz name - dserver-update-key-cache.sh.tpl (OpenBSD): port the NetBSD hardening — quote all variable expansions, derive the user via basename suffix stripping instead of cut -d. -f1 (dotted usernames broke), fix the obsolete-cachefile echo that used single quotes and never interpolated $cachefile, add a header comment documenting the rc_pre and /etc/daily.local call sites - dserver.tpl (OpenBSD rc.d): replace 'rc_cmd $1 &' with rc_bg=YES and a plain rc_cmd "$1" — the daemon needs backgrounding because it does not daemonize, but backgrounding the whole rc framework made rc_pre failures and the start result invisible to rcctl; rc_bg is rc.subr's supported way to background only the daemon - dserver-update-key-cache-freebsd.sh.tpl: header now documents the new rc.d start_precmd call site Deployed: FreeBSD pkg republished, f0/f1/f2 upgraded with host key migrated to /var/db/dserver first (sha256 verified identical); f3 unreachable, still on the old package. OpenBSD pkg republished, fishfinger reinstalled + restarted, host key unchanged, dcat verified. Co-Authored-By: Claude Fable 5 --- frontends/etc/dserver/dtail-freebsd.json.tpl | 2 +- frontends/etc/rc.d/dserver-freebsd.tpl | 9 +++++++ frontends/etc/rc.d/dserver.tpl | 6 ++++- .../dserver-update-key-cache-freebsd.sh.tpl | 4 ++- frontends/scripts/dserver-update-key-cache.sh.tpl | 31 +++++++++++----------- packages/Makefile | 29 +++++++++++++------- 6 files changed, 53 insertions(+), 28 deletions(-) diff --git a/frontends/etc/dserver/dtail-freebsd.json.tpl b/frontends/etc/dserver/dtail-freebsd.json.tpl index cd99560..634fcca 100644 --- a/frontends/etc/dserver/dtail-freebsd.json.tpl +++ b/frontends/etc/dserver/dtail-freebsd.json.tpl @@ -90,7 +90,7 @@ }, "Server": { "SSHBindAddress": "0.0.0.0", - "HostKeyFile": "/var/run/dserver/cache/ssh_host_key", + "HostKeyFile": "/var/db/dserver/ssh_host_key", "HostKeyBits": 2048, "MapreduceLogFormat": "default", "MaxConcurrentCats": 2, diff --git a/frontends/etc/rc.d/dserver-freebsd.tpl b/frontends/etc/rc.d/dserver-freebsd.tpl index 6110c0c..04380cb 100644 --- a/frontends/etc/rc.d/dserver-freebsd.tpl +++ b/frontends/etc/rc.d/dserver-freebsd.tpl @@ -21,9 +21,18 @@ start_precmd="dserver_precmd" dserver_precmd() { + # /var/run is volatile on FreeBSD (cleanvar purges it at boot) — recreate + # the runtime dirs and repopulate the SSH key cache on every service + # start (a daily periodic job keeps it fresh afterwards). The SSH host + # key lives in persistent /var/db/dserver so it survives reboots (a + # regenerated host key would break clients' known_hosts). install -d -o dserver -m 0755 /var/log/dserver install -d -o dserver -m 0755 /var/run/dserver install -d -o dserver -m 0755 /var/run/dserver/cache + install -d -o dserver -m 0700 /var/db/dserver + if [ -x /usr/local/bin/dserver-update-key-cache.sh ]; then + /usr/local/bin/dserver-update-key-cache.sh + fi } load_rc_config $name diff --git a/frontends/etc/rc.d/dserver.tpl b/frontends/etc/rc.d/dserver.tpl index 305b0ce..76e79a5 100755 --- a/frontends/etc/rc.d/dserver.tpl +++ b/frontends/etc/rc.d/dserver.tpl @@ -7,6 +7,10 @@ daemon_user="_dserver" . /etc/rc.d/rc.subr rc_reload=NO +# dserver does not daemonize itself — let rc.subr start it in the background +# (rc_bg) instead of backgrounding the whole rc_cmd invocation, which would +# hide rc_pre failures and the start result from rcctl. +rc_bg=YES rc_pre() { # /var/run is wiped by /etc/rc at boot — recreate the runtime dirs and @@ -26,4 +30,4 @@ rc_pre() { fi } -rc_cmd $1 & +rc_cmd "$1" diff --git a/frontends/scripts/dserver-update-key-cache-freebsd.sh.tpl b/frontends/scripts/dserver-update-key-cache-freebsd.sh.tpl index 22173d7..5b11acf 100644 --- a/frontends/scripts/dserver-update-key-cache-freebsd.sh.tpl +++ b/frontends/scripts/dserver-update-key-cache-freebsd.sh.tpl @@ -1,6 +1,8 @@ #!/bin/sh # Refresh the dserver SSH key cache from user authorized_keys files. -# Called by /usr/local/etc/periodic/daily/200.dserver-update-key-cache. +# FreeBSD variant: called from the dserver rc.d start_precmd (because +# /var/run is volatile across reboots — cleanvar purges it) and by +# /usr/local/etc/periodic/daily/200.dserver-update-key-cache. CACHEDIR=/var/run/dserver/cache DSERVER_USER=dserver diff --git a/frontends/scripts/dserver-update-key-cache.sh.tpl b/frontends/scripts/dserver-update-key-cache.sh.tpl index 86b5ecf..fc6bf9e 100644 --- a/frontends/scripts/dserver-update-key-cache.sh.tpl +++ b/frontends/scripts/dserver-update-key-cache.sh.tpl @@ -1,4 +1,8 @@ #!/bin/ksh +# Refresh the dserver SSH key cache from user authorized_keys files. +# OpenBSD variant: called from the dserver rc.d rc_pre (because /var/run is +# wiped by /etc/rc at boot) and from a daily /etc/daily.local entry added by +# the Rex 'dtail' task — see the pkgrepo skill's dtail-package.md. CACHEDIR=/var/run/dserver/cache DSERVER_USER=_dserver @@ -7,27 +11,24 @@ DSERVER_GROUP=_dserver echo 'Updating SSH key cache' ls /home/ | while read remoteuser; do - keysfile=/home/$remoteuser/.ssh/authorized_keys + keysfile="/home/$remoteuser/.ssh/authorized_keys" - if [ -f $keysfile ]; then - cachefile=$CACHEDIR/$remoteuser.authorized_keys + if [ -f "$keysfile" ]; then + cachefile="$CACHEDIR/$remoteuser.authorized_keys" echo "Caching $keysfile -> $cachefile" - cp $keysfile $cachefile - chown $DSERVER_USER:$DSERVER_GROUP $cachefile - chmod 600 $cachefile + cp "$keysfile" "$cachefile" + chown "$DSERVER_USER:$DSERVER_GROUP" "$cachefile" + chmod 600 "$cachefile" fi done -# Cleanup obsolete public SSH keys -find $CACHEDIR -name \*.authorized_keys -type f | -while read cachefile; do - remoteuser=$(basename $cachefile | cut -d. -f1) - keysfile=/home/$remoteuser/.ssh/authorized_keys - - if [ ! -f $keysfile ]; then - echo 'Deleting obsolete cache file $cachefile' - rm $cachefile +# Remove stale cache entries for users whose authorized_keys no longer exist +find "$CACHEDIR" -name '*.authorized_keys' -type f | while read cachefile; do + remoteuser=$(basename "$cachefile" .authorized_keys) + if [ ! -f "/home/$remoteuser/.ssh/authorized_keys" ]; then + echo "Deleting obsolete cache file $cachefile" + rm "$cachefile" fi done diff --git a/packages/Makefile b/packages/Makefile index f81859e..1c9a01a 100644 --- a/packages/Makefile +++ b/packages/Makefile @@ -31,7 +31,10 @@ SHELL := /bin/bash # -e: with .ONESHELL a whole recipe runs as one shell script, so without -e a # failing intermediate line (remote pkg_create, scp, doas cp upload, ...) # would NOT stop the recipe and make would exit 0 — silently "succeeding". -.SHELLFLAGS := -ec +# -o pipefail: without it a pipeline only reports the last command's status, +# so e.g. a failing "git archive | ssh ... tar" would still exit 0 as long +# as tar succeeds on the (truncated) stream. +.SHELLFLAGS := -e -o pipefail -c .ONESHELL: # SSH targets for production hosts @@ -193,12 +196,15 @@ dtail-openbsd: /tmp/dtail-binaries/.built $(OPENBSD_SCP) $(SCRIPTS)/pkg-dtail-openbsd.sh $(OPENBSD_HOST):/tmp/pkg-dtail-openbsd.sh $(OPENBSD_SSH) $(OPENBSD_HOST) "/bin/sh /tmp/pkg-dtail-openbsd.sh '$(DTAIL_VERSION)'" @echo "Copying signed package to PV via f0..." - $(OPENBSD_SCP) $(OPENBSD_HOST):/tmp/dtail-pkg/out/dtail-$(DTAIL_VERSION).tgz /tmp/dtail-$(DTAIL_VERSION).tgz - $(FREEBSD_SCP) /tmp/dtail-$(DTAIL_VERSION).tgz $(FREEBSD_HOST):/tmp/dtail-$(DTAIL_VERSION).tgz - $(FREEBSD_SSH) $(FREEBSD_HOST) "doas cp /tmp/dtail-$(DTAIL_VERSION).tgz $(PV_BASE)/$(OPENBSD_REPO)/ && rm /tmp/dtail-$(DTAIL_VERSION).tgz" + @# OS-suffixed staging name: a dash-less version would make the OpenBSD + @# and NetBSD staging files collide in /tmp (locally and on f0). Only the + @# final repo copy uses the canonical dtail-.tgz name. + $(OPENBSD_SCP) $(OPENBSD_HOST):/tmp/dtail-pkg/out/dtail-$(DTAIL_VERSION).tgz /tmp/dtail-openbsd-$(DTAIL_VERSION).tgz + $(FREEBSD_SCP) /tmp/dtail-openbsd-$(DTAIL_VERSION).tgz $(FREEBSD_HOST):/tmp/dtail-openbsd-$(DTAIL_VERSION).tgz + $(FREEBSD_SSH) $(FREEBSD_HOST) "doas cp /tmp/dtail-openbsd-$(DTAIL_VERSION).tgz $(PV_BASE)/$(OPENBSD_REPO)/dtail-$(DTAIL_VERSION).tgz && rm /tmp/dtail-openbsd-$(DTAIL_VERSION).tgz" @# Clean up remote and local temp files $(OPENBSD_SSH) $(OPENBSD_HOST) "doas rm -rf /tmp/dtail-pkg /tmp/dtail-binaries /tmp/pkg-dtail-openbsd.sh" - rm -rf /tmp/dtail-binaries /tmp/dtail-$(DTAIL_VERSION).tgz + rm -rf /tmp/dtail-binaries /tmp/dtail-openbsd-$(DTAIL_VERSION).tgz @echo "OpenBSD package dtail-$(DTAIL_VERSION) uploaded to repo" # Cross-compile dtail for FreeBSD/amd64 (CGO_ENABLED=0, nozstd), package on f0, upload to PV. @@ -230,7 +236,7 @@ dtail-netbsd: @echo "Building DTail $(DTAIL_VERSION) for NetBSD/arm64..." @# Remove stale artifacts from previous runs so a failed build can never @# silently upload an old package. - rm -rf /tmp/dtail-netbsd-binaries /tmp/dtail-$(DTAIL_NETBSD_VERSION).tgz /tmp/dtail-netbsd-pkg_summary.gz + rm -rf /tmp/dtail-netbsd-binaries /tmp/dtail-netbsd-$(DTAIL_NETBSD_VERSION).tgz /tmp/dtail-netbsd-pkg_summary.gz mkdir -p /tmp/dtail-netbsd-binaries cd $(DTAIL_SRC) && for bin in $(DTAIL_BINARIES); do \ echo " Cross-compiling $$bin for NetBSD..."; \ @@ -246,14 +252,17 @@ dtail-netbsd: $(NETBSD_SCP) $(SCRIPTS)/pkg-dtail-netbsd.sh $(NETBSD_BUILD_HOST):/tmp/pkg-dtail-netbsd.sh $(NETBSD_SSH) $(NETBSD_BUILD_HOST) "/bin/sh /tmp/pkg-dtail-netbsd.sh '$(DTAIL_NETBSD_VERSION)'" @echo "Copying package to PV via f0..." - $(NETBSD_SCP) $(NETBSD_BUILD_HOST):/tmp/dtail-netbsd-pkg/out/dtail-$(DTAIL_NETBSD_VERSION).tgz /tmp/dtail-$(DTAIL_NETBSD_VERSION).tgz + @# OS-suffixed staging name: a dash-less version would make the OpenBSD + @# and NetBSD staging files collide in /tmp (locally and on f0). Only the + @# final repo copy uses the canonical dtail-.tgz name. + $(NETBSD_SCP) $(NETBSD_BUILD_HOST):/tmp/dtail-netbsd-pkg/out/dtail-$(DTAIL_NETBSD_VERSION).tgz /tmp/dtail-netbsd-$(DTAIL_NETBSD_VERSION).tgz $(NETBSD_SCP) $(NETBSD_BUILD_HOST):/tmp/dtail-netbsd-pkg/out/pkg_summary.gz /tmp/dtail-netbsd-pkg_summary.gz - $(FREEBSD_SCP) /tmp/dtail-$(DTAIL_NETBSD_VERSION).tgz $(FREEBSD_HOST):/tmp/dtail-$(DTAIL_NETBSD_VERSION).tgz + $(FREEBSD_SCP) /tmp/dtail-netbsd-$(DTAIL_NETBSD_VERSION).tgz $(FREEBSD_HOST):/tmp/dtail-netbsd-$(DTAIL_NETBSD_VERSION).tgz $(FREEBSD_SCP) /tmp/dtail-netbsd-pkg_summary.gz $(FREEBSD_HOST):/tmp/dtail-netbsd-pkg_summary.gz - $(FREEBSD_SSH) $(FREEBSD_HOST) "doas mkdir -p $(PV_BASE)/$(NETBSD_REPO) && doas cp /tmp/dtail-$(DTAIL_NETBSD_VERSION).tgz $(PV_BASE)/$(NETBSD_REPO)/ && doas cp /tmp/dtail-netbsd-pkg_summary.gz $(PV_BASE)/$(NETBSD_REPO)/pkg_summary.gz && rm /tmp/dtail-$(DTAIL_NETBSD_VERSION).tgz /tmp/dtail-netbsd-pkg_summary.gz" + $(FREEBSD_SSH) $(FREEBSD_HOST) "doas mkdir -p $(PV_BASE)/$(NETBSD_REPO) && doas cp /tmp/dtail-netbsd-$(DTAIL_NETBSD_VERSION).tgz $(PV_BASE)/$(NETBSD_REPO)/dtail-$(DTAIL_NETBSD_VERSION).tgz && doas cp /tmp/dtail-netbsd-pkg_summary.gz $(PV_BASE)/$(NETBSD_REPO)/pkg_summary.gz && rm /tmp/dtail-netbsd-$(DTAIL_NETBSD_VERSION).tgz /tmp/dtail-netbsd-pkg_summary.gz" @# Clean up remote and local temp files $(NETBSD_SSH) $(NETBSD_BUILD_HOST) "rm -rf /tmp/dtail-netbsd-pkg /tmp/dtail-netbsd-binaries /tmp/pkg-dtail-netbsd.sh" - rm -rf /tmp/dtail-netbsd-binaries /tmp/dtail-$(DTAIL_NETBSD_VERSION).tgz /tmp/dtail-netbsd-pkg_summary.gz + rm -rf /tmp/dtail-netbsd-binaries /tmp/dtail-netbsd-$(DTAIL_NETBSD_VERSION).tgz /tmp/dtail-netbsd-pkg_summary.gz @echo "NetBSD package dtail-$(DTAIL_NETBSD_VERSION) uploaded to repo" # Build RPMs for Rocky Linux 9 (x86_64 + aarch64), generate repodata, and upload to the PV. -- cgit v1.2.3