commit ebe12d3db68578f1d69bdf6af3385dcd07799e1c Author: hellcat Date: Sat Oct 17 17:50:26 2026 +0800 Certbot security repair from source 6b0ac99d1984ff55f70aa6838b72290280af8bf1 diff --git a/dpl-certbot-apparmor-renew.conf b/dpl-certbot-apparmor-renew.conf new file mode 100644 index 0000000..23233b2 --- /dev/null +++ b/dpl-certbot-apparmor-renew.conf @@ -0,0 +1,7 @@ +[Unit] +Requires=dpl-certbot-apparmor.service +After=dpl-certbot-apparmor.service + +[Service] +# Recheck generated profiles after a snap refresh, before the existing renewal command. +ExecStartPre=/bin/bash /opt/dpl-certbot-security/provision/load-certbot-apparmor.sh --load diff --git a/dpl-certbot-apparmor.service b/dpl-certbot-apparmor.service new file mode 100644 index 0000000..c7b568a --- /dev/null +++ b/dpl-certbot-apparmor.service @@ -0,0 +1,14 @@ +[Unit] +Description=Load existing Certbot AppArmor profiles for DPL certificate operations +After=local-fs.target +RequiresMountsFor=/snap/core/current /snap/certbot/current /var/lib/snapd/apparmor/profiles +Before=snap.certbot.renew.service +ConditionPathExists=/var/lib/snapd/apparmor/profiles/snap.certbot.certbot + +[Service] +Type=oneshot +ExecStart=/bin/bash /opt/dpl-certbot-security/provision/load-certbot-apparmor.sh --load +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/load-certbot-apparmor.sh b/load-certbot-apparmor.sh new file mode 100644 index 0000000..f856c97 --- /dev/null +++ b/load-certbot-apparmor.sh @@ -0,0 +1,30 @@ +#!/bin/bash +set -euo pipefail +# Restore only profiles already generated by the installed Certbot/core snaps. +# This does not enable the global AppArmor service or change profile modes. +[[ $(id -u) == 0 ]] || exit 1 +mode=${1:---load} +[[ $# -le 1 && ( $mode == --load || $mode == --check ) ]] || exit 2 +[[ $(cat /sys/module/apparmor/parameters/enabled) == Y ]] || exit 3 +directory=/var/lib/snapd/apparmor/profiles +[[ -d $directory && ! -L $directory && $(stat -c %u "$directory") == 0 ]] || exit 4 +[[ -z $(find "$directory" -maxdepth 0 -perm /022 -print) ]] || exit 4 +[[ -f $directory/snap.certbot.certbot && -f $directory/snap.certbot.renew ]] || exit 5 +shopt -s nullglob +core=$(readlink -f /snap/core/current) +[[ $core =~ ^/(var/lib/snapd/)?snap/core/([0-9]+)$ ]] || exit 5 +revision=${BASH_REMATCH[2]} +profiles=("$directory"/snap.certbot.* "$directory"/snap-update-ns.certbot "$directory/snap-confine.core.$revision") +(( ${#profiles[@]} >= 4 )) || exit 5 +# Validate every input before loading any profile. Never use complain/disable flags. +for profile in "${profiles[@]}"; do + [[ -f $profile && ! -L $profile && $(stat -c %u "$profile") == 0 ]] || exit 6 + [[ -z $(find "$profile" -maxdepth 0 -perm /022 -print) ]] || exit 6 + /usr/sbin/apparmor_parser --skip-kernel-load --skip-cache "$profile" +done +if [[ $mode == --load ]]; then + for profile in "${profiles[@]}"; do + /usr/sbin/apparmor_parser --replace --skip-cache "$profile" + done +fi +printf 'Certbot/core profiles checked: %s; mode: %s\n' "${#profiles[@]}" "$mode"