testsAndMisc/linux_configuration/scripts/sync-dot-cert.sh
Krzysztof kuhy Rudnicki 7b06fc3c4a
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (mypy, mypy) (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (pylint, pylint) (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (rest, ) (push) Waiting to run
Pre-commit checks / pre-commit (${{ matrix.group }}) (shellcheck, shellcheck) (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Shell tests / shell-tests (push) Waiting to run
Shell tests / lib-tests (push) Waiting to run
Shell tests / arch-tests (push) Waiting to run
refactor(dot-resolver): install the tracked sync-dot-cert.sh instead of generating it
Every script under /usr/local/bin must be a repo file. install_cert_sync
wrote /usr/local/bin/sync-dot-cert.sh from a heredoc with the domain,
Caddy container and cert dir baked in. The script now lives at
linux_configuration/scripts/sync-dot-cert.sh, takes those three as
arguments (defaults = the installer's constants), and is installed with
install -m 755. dot-cert-sync.service and the first sync pass the
arguments, so --domain reaches the timer too. Test asserts the installed
file is the tracked one byte for byte and runs the script itself against
a docker shim (reload only on change).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014yhTkYV6ZeuAbQYvykFGFc

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-11 19:32:54 +02:00

29 lines
1.2 KiB
Bash
Executable File

#!/bin/bash
# Copy the Caddy-managed certificate for the DoT hostname out to stunnel, and
# reload stunnel only when the content actually changed.
#
# Installed to /usr/local/bin/sync-dot-cert.sh by
# features/setup_dot_resolver.sh (install -m 755 of THIS file) and run daily by
# dot-cert-sync.timer. The installer passes all three arguments, so the
# defaults below only matter for a bare manual run; they match the installer's.
#
# Usage: sync-dot-cert.sh [<domain> [<caddy-container> [<cert-dir>]]]
set -euo pipefail
domain="${1:-dns.kuhy.duckdns.org}"
container="${2:-gitea-caddy}"
cert_dir="${3:-/etc/stunnel/dot}"
# Caddy stores certs per-domain under its data volume.
src="/data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/$domain"
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
docker cp "$container:$src/$domain.crt" "$tmp/cert.pem"
docker cp "$container:$src/$domain.key" "$tmp/key.pem"
cat "$tmp/cert.pem" "$tmp/key.pem" >"$tmp/combined.pem"
if ! cmp -s "$tmp/combined.pem" "$cert_dir/combined.pem"; then
install -m 600 "$tmp/combined.pem" "$cert_dir/combined.pem"
systemctl reload-or-restart stunnel-dot.service
echo "certificate updated for $domain"
fi