From e3d6422dc551fae6a502a10a554296765e2c59f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= Date: Wed, 14 Dec 2022 15:11:58 +0100 Subject: [PATCH 1/3] acme-common: Export canonical paths for storing certificates and challenges MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The contract between the acme-common framework and consumers and hook scripts is that certificates can be consumed from /etc/ssl/acme and that web challenges are stored in /var/run/acme/challenge. Make this explicit by exporting $CERT_DIR and $CHALLENGE_DIR as environment variables as well, instead of having knowledge of those paths depend on out-of-band information. We already exported $challenge_dir, but let's change it to upper-case to make it clear that it's not a user configuration variable. Signed-off-by: Toke Høiland-Jørgensen --- net/acme-common/files/acme.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/net/acme-common/files/acme.sh b/net/acme-common/files/acme.sh index 5a2f7d739..defd66005 100644 --- a/net/acme-common/files/acme.sh +++ b/net/acme-common/files/acme.sh @@ -9,7 +9,8 @@ # Authors: Toke Høiland-Jørgensen run_dir=/var/run/acme -export challenge_dir=$run_dir/challenge +export CHALLENGE_DIR=$run_dir/challenge +export CERT_DIR=/etc/ssl/acme NFT_HANDLE= HOOK=/usr/lib/acme/hook LOG_TAG=acme @@ -63,7 +64,7 @@ load_options() { config_get webroot "$section" webroot export webroot if [ "$webroot" ]; then - log warn "Option \"webroot\" is deprecated, please remove it and change your web server's config so it serves ACME challenge requests from $challenge_dir." + log warn "Option \"webroot\" is deprecated, please remove it and change your web server's config so it serves ACME challenge requests from $CHALLENGE_DIR." fi } @@ -79,7 +80,7 @@ get_cert() { load_options "$section" if [ -z "$dns" ] && [ "$standalone" = 0 ]; then - mkdir -p "$challenge_dir" + mkdir -p "$CHALLENGE_DIR" fi if [ "$standalone" = 1 ] && [ -z "$NFT_HANDLE" ]; then @@ -109,7 +110,7 @@ load_globals() { config_get state_dir "$section" state_dir if [ "$state_dir" ]; then - log warn "Option \"state_dir\" is deprecated, please remove it. Certificates now exist in /etc/ssl/acme." + log warn "Option \"state_dir\" is deprecated, please remove it. Certificates now exist in $CERT_DIR." mkdir -p "$state_dir" else state_dir=/etc/acme From 152a26da57ba18166cda5349d4597e909cb93f5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= Date: Wed, 14 Dec 2022 15:14:59 +0100 Subject: [PATCH 2/3] acme-acmesh: Don't hard-code certificate directory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The acme-acmesh package hardcoded the certificate path in its hook script. Now that we export it as a variable we can avoid hard-coding and use the variable version instead. Also factor out the linking of certificates into a function so it's not repeated. Signed-off-by: Toke Høiland-Jørgensen --- net/acme-acmesh/files/hook.sh | 46 ++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/net/acme-acmesh/files/hook.sh b/net/acme-acmesh/files/hook.sh index 149a3e751..4eb3f04fa 100644 --- a/net/acme-acmesh/files/hook.sh +++ b/net/acme-acmesh/files/hook.sh @@ -2,8 +2,8 @@ set -u ACME=/usr/lib/acme/client/acme.sh LOG_TAG=acme-acmesh -# webroot option deprecated, use the hardcoded value directly in the next major version -WEBROOT=${webroot:-$challenge_dir} +# webroot option deprecated, use the exported value directly in the next major version +WEBROOT=${webroot:-$CHALLENGE_DIR} NOTIFY=/usr/lib/acme/notify # shellcheck source=net/acme/files/functions.sh @@ -13,6 +13,28 @@ NOTIFY=/usr/lib/acme/notify export CURL_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt export NO_TIMESTAMP=1 +link_certs() +{ + local main_domain + local domain_dir + domain_dir="$1" + main_domain="$2" + + + if [ ! -e "$CERT_DIR/$main_domain.crt" ]; then + ln -s "$domain_dir/$main_domain.cer" "$CERT_DIR/$main_domain.crt" + fi + if [ ! -e "$CERT_DIR/$main_domain.key" ]; then + ln -s "$domain_dir/$main_domain.key" "$CERT_DIR/$main_domain.key" + fi + if [ ! -e "$CERT_DIR/$main_domain.fullchain.crt" ]; then + ln -s "$domain_dir/fullchain.cer" "$CERT_DIR/$main_domain.fullchain.crt" + fi + if [ ! -e "$CERT_DIR/$main_domain.chain.crt" ]; then + ln -s "$domain_dir/ca.cer" "$CERT_DIR/$main_domain.chain.crt" + fi +} + case $1 in get) set -- @@ -45,20 +67,7 @@ get) case $status in 0) - mkdir -p /etc/ssl/acme - if [ ! -e "/etc/ssl/acme/$main_domain.crt" ]; then - ln -s "$domain_dir/$main_domain.cer" "/etc/ssl/acme/$main_domain.crt" - fi - if [ ! -e "/etc/ssl/acme/$main_domain.key" ]; then - ln -s "$domain_dir/$main_domain.key" "/etc/ssl/acme/$main_domain.key" - fi - if [ ! -e "/etc/ssl/acme/$main_domain.fullchain.crt" ]; then - ln -s "$domain_dir/fullchain.cer" "/etc/ssl/acme/$main_domain.fullchain.crt" - fi - if [ ! -e "/etc/ssl/acme/$main_domain.chain.crt" ]; then - ln -s "$domain_dir/ca.cer" "/etc/ssl/acme/$main_domain.chain.crt" - fi - + link_certs "$domain_dir" "$main_domain" $NOTIFY renewed exit ;; @@ -124,10 +133,7 @@ get) case $status in 0) - ln -s "$domain_dir/$main_domain.cer" "/etc/ssl/acme/$main_domain.crt" - ln -s "$domain_dir/$main_domain.key" "/etc/ssl/acme/$main_domain.key" - ln -s "$domain_dir/fullchain.cer" "/etc/ssl/acme/$main_domain.fullchain.crt" - ln -s "$domain_dir/ca.cer" "/etc/ssl/acme/$main_domain.chain.crt" + link_certs "$domain_dir" "$main_domain" $NOTIFY issued ;; *) From 17691a5a52833511ef3fcd31ae835c3c4a230542 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= Date: Wed, 14 Dec 2022 15:21:59 +0100 Subject: [PATCH 3/3] acme-acmesh: Provide a 'combined' certificate bundle as well MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The haproxy hotplug script creates a 'combined' certificate bundle that contains both the certificate chain and the private key. However, having a daemon hotplug script write into CERT_DIR is not great; so let's provide the bundle as part of the main acme framework, keeping it in $domain_dir and just linking it into CERT_DIR. That way we can keep CERT_DIR as just a collection of links for everything, that no consumers should need to write into. Also make sure to set the umask correctly so the combined file is not world-readable (since it contains the private key). Signed-off-by: Toke Høiland-Jørgensen --- net/acme-acmesh/Makefile | 2 +- net/acme-acmesh/files/hook.sh | 4 ++++ net/haproxy/Makefile | 4 +--- net/haproxy/files/acme.hotplug | 8 -------- 4 files changed, 6 insertions(+), 12 deletions(-) delete mode 100644 net/haproxy/files/acme.hotplug diff --git a/net/acme-acmesh/Makefile b/net/acme-acmesh/Makefile index 0a198cc52..a5ffe76a5 100644 --- a/net/acme-acmesh/Makefile +++ b/net/acme-acmesh/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=acme-acmesh PKG_VERSION:=3.0.1 -PKG_RELEASE:=9 +PKG_RELEASE:=10 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/acmesh-official/acme.sh/tar.gz/$(PKG_VERSION)? diff --git a/net/acme-acmesh/files/hook.sh b/net/acme-acmesh/files/hook.sh index 4eb3f04fa..03343dacb 100644 --- a/net/acme-acmesh/files/hook.sh +++ b/net/acme-acmesh/files/hook.sh @@ -20,6 +20,7 @@ link_certs() domain_dir="$1" main_domain="$2" + (umask 077; cat "$domain_dir/fullchain.cer" "$domain_dir/$main_domain.key" > "$domain_dir/combined.cer") if [ ! -e "$CERT_DIR/$main_domain.crt" ]; then ln -s "$domain_dir/$main_domain.cer" "$CERT_DIR/$main_domain.crt" @@ -30,6 +31,9 @@ link_certs() if [ ! -e "$CERT_DIR/$main_domain.fullchain.crt" ]; then ln -s "$domain_dir/fullchain.cer" "$CERT_DIR/$main_domain.fullchain.crt" fi + if [ ! -e "$CERT_DIR/$main_domain.combined.crt" ]; then + ln -s "$domain_dir/combined.cer" "$CERT_DIR/$main_domain.combined.crt" + fi if [ ! -e "$CERT_DIR/$main_domain.chain.crt" ]; then ln -s "$domain_dir/ca.cer" "$CERT_DIR/$main_domain.chain.crt" fi diff --git a/net/haproxy/Makefile b/net/haproxy/Makefile index 179658361..1c0d8fde1 100644 --- a/net/haproxy/Makefile +++ b/net/haproxy/Makefile @@ -11,7 +11,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=haproxy PKG_VERSION:=2.6.6 -PKG_RELEASE:=103 +PKG_RELEASE:=104 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://www.haproxy.org/download/2.6/src @@ -122,8 +122,6 @@ define Package/haproxy/install $(INSTALL_CONF) ./files/haproxy.cfg $(1)/etc/ $(INSTALL_DIR) $(1)/etc/init.d $(INSTALL_BIN) ./files/haproxy.init $(1)/etc/init.d/haproxy - $(INSTALL_DIR) $(1)/etc/hotplug.d/acme - $(INSTALL_DATA) ./files/acme.hotplug $(1)/etc/hotplug.d/acme/00-haproxy endef Package/haproxy-nossl/install = $(Package/haproxy/install) diff --git a/net/haproxy/files/acme.hotplug b/net/haproxy/files/acme.hotplug deleted file mode 100644 index 9896bbdee..000000000 --- a/net/haproxy/files/acme.hotplug +++ /dev/null @@ -1,8 +0,0 @@ -case $ACTION in -issued|renewed) - cat \ - "/etc/ssl/acme/$main_domain.fullchain.crt" \ - "/etc/ssl/acme/$main_domain.key" \ - >"/etc/ssl/acme/$main_domain.combined.crt" - ;; -esac