Compare commits

..

2 Commits

Author SHA1 Message Date
Dustin 6817c62295 ci: Pin to dedicated nodes
dustin/sshca-cli/pipeline/head Something is wrong with the build of this commit Details
Now that there are several production workloads on the Raspberry Pi
cluster, we don't want intense jobs like this running on them.  To
ensure this job runs on a dedicated node, we need to use a label
expression that matches the appropriate nodes.
2025-09-13 07:17:03 -05:00
Dustin 9dc20b4fd4 systemd: Add unit to auto reload sshd after renew
dustin/sshca-cli/pipeline/head This commit looks good Details
`sshd` no longer appears to automatically pick up the new certificate
after it has been renewed by `ssh-host-cert-sign@.service`; we need to
explicitly reload it.  To handle this, I've added a systemd _path_ unit
that monitors the certificate files for changes and triggers a
corresponding _service_ unit that reloads the SSH daemon.
2025-09-12 07:16:02 -05:00
8 changed files with 200 additions and 0 deletions

65
ci/Jenkinsfile vendored
View File

@ -82,5 +82,70 @@ pipeline {
}
}
stage('Build Container') {
matrix {
axes {
axis {
name 'ARCH'
values 'amd64', 'arm64'
}
}
stages {
stage('Container') {
agent {
kubernetes {
yamlFile 'ci/podTemplate-container.yaml'
yamlMergeStrategy merge()
defaultContainer 'buildah'
nodeSelector "kubernetes.io/arch=${ARCH}"
}
}
stages {
stage('Build') {
steps {
sh '. ci/build-container.sh'
stash name: env.ARCH, includes: "*.oci.tar"
}
}
}
}
}
}
}
stage('Publish Container') {
agent {
kubernetes {
yamlFile 'ci/podTemplate-container.yaml'
yamlMergeStrategy merge()
defaultContainer 'buildah'
}
}
environment {
REGISTRY_AUTH_FILE = "${env.WORKSPACE_TMP}/auth.json"
}
steps {
unstash 'amd64'
unstash 'arm64'
withCredentials([usernamePassword(
credentialsId: 'jenkins-packages',
usernameVariable: 'BUILDAH_USERNAME',
passwordVariable: 'BUILDAH_PASSWORD',
)]) {
sh """
buildah login \
--username \${BUILDAH_USERNAME} \
--password \${BUILDAH_PASSWORD} \
git.pyrocufflink.net
"""
}
sh '. ci/publish-container.sh'
}
}
}
}

11
reload-ssh-cert.path Normal file
View File

@ -0,0 +1,11 @@
[Unit]
Description=Watch SSH Host certificates for renewal
After=sshd.service
[Path]
PathChanged=/etc/ssh/ssh_host_rsa_key-cert.pub
PathChanged=/etc/ssh/ssh_host_ecdsa_key-cert.pub
PathChanged=/etc/ssh/ssh_host_ed25519-cert.pub
[Install]
WantedBy=paths.target

24
reload-ssh-cert.service Normal file
View File

@ -0,0 +1,24 @@
[Unit]
Description=Reload SSH daemon when certificate is renewed
After=sshd.service
[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl reload sshd
CapabilityBoundingSet=
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateDevices=true
PrivateTmp=true
ProtectHostname=true
ProtectClock=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectKernelLogs=true
ProtectControlGroups=yes
RestrictAddressFamilies=AF_UNIX
LockPersonality=true
MemoryDenyWriteExecute=true
RestrictRealtime=true
RestrictSUIDSGID=true

View File

@ -0,0 +1,34 @@
[Unit]
Description=Request %I SSH Host Certificate
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
EnvironmentFile=-/etc/sysconfig/ssh-host-cert-sign
ExecStart=/usr/bin/sshca-cli host sign --output /etc/ssh/ssh_host_%I_key-cert.pub /etc/ssh/ssh_host_%I_key.pub
CapabilityBoundingSet=CAP_CHOWN
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
ReadWritePaths=/etc/ssh
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
RestrictNamespaces=yes
RestrictRealtime=yes
RestrictSUIDSGID=yes

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

10
ssh-host-certs.target Normal file
View File

@ -0,0 +1,10 @@
# vim: set ft=systemd :
[Unit]
Description=Request SSH Host Certificates
ConditionFirstBoot=yes
Wants=ssh-host-cert-sign@ed25519.service
Wants=ssh-host-cert-sign@rsa.service
Wants=ssh-host-cert-sign@ecdsa.service
[Install]
WantedBy=multi-user.target

View File

@ -18,17 +18,32 @@ License: MIT OR Apache-2.0
URL: https://git.pyrocufflink.net/dustin/sshca
Source: sshca-cli-%{version}.tar.xz
Source: sshca-cli-%{version}-vendor.tar.xz
Source: ssh-host-cert-sign@.service
Source: ssh-host-certs.target
Source: ssh-host-certs-renew.target
Source: ssh-host-certs-renew.timer
Source: reload-ssh-cert.path
Source: reload-ssh-cert.service
ExclusiveArch: %{rust_arches}
BuildRequires: cargo-rpm-macros >= 25
BuildRequires: openssl-devel
BuildRequires: systemd-rpm-macros
%global _description %{expand:
CLI client for SSHCA.}
%description %{_description}
%package systemd
Summary: systemd units for managing SSH host certificates with SSHCA
Requires: %{name} = %{version}
%description systemd
A collection of systemd service, timer, and target units that automatically
request and renew SSH host certificates from an SSHCA server.
%prep
%autosetup -n %{crate}-%{version} -p1 -a1
%cargo_prep -v vendor
@ -43,11 +58,30 @@ CLI client for SSHCA.}
%install
%cargo_install
mkdir -p $RPM_BUILD_ROOT%{_unitdir}
install -m u=rw,go=r \
%{SOURCE2} \
%{SOURCE3} \
%{SOURCE4} \
%{SOURCE5} \
%{SOURCE6} \
%{SOURCE7} \
$RPM_BUILD_ROOT%{_unitdir}
%if %{with check}
%check
%cargo_test
%endif
%post systemd
%systemd_post ssh-host-certs.target ssh-host-certs-renew.timer reload-ssh-cert.path
%preun systemd
%systemd_preun ssh-host-certs.target ssh-host-certs-renew.timer reload-ssh-cert.path
%postun systemd
%systemd_postun ssh-host-certs.target ssh-host-certs-renew.timer reload-ssh-cert.path
%files
%license LICENSE-Apache-2.0.txt
%license LICENSE-MIT.txt
@ -55,6 +89,9 @@ CLI client for SSHCA.}
%license cargo-vendor.txt
%{_bindir}/sshca-cli
%files systemd
%{_unitdir}/*
%changelog
* Sun Nov 05 2023 Dustin C. Hatch <dustin@hatch.name> - 0.1.0-1
- Initial package