Skip to content

Instantly share code, notes, and snippets.

@kobuki
Last active December 3, 2025 00:24
Show Gist options
  • Select an option

  • Save kobuki/a8b29f3e989f1fa3fc36a9d96873e726 to your computer and use it in GitHub Desktop.

Select an option

Save kobuki/a8b29f3e989f1fa3fc36a9d96873e726 to your computer and use it in GitHub Desktop.
Migrate certbot configurations and certs to acme.sh
#/bin/bash
ACME_SH_ROOT=/etc/.acme.sh
WEBCONF_ROOT=/etc/apache2/sites-available.acmesh
WEBROOT=/var/www/html
RELOADCMD='systemctl reload apache2.service'
dom=()
altdoms=()
expiry=()
certpath=()
keypath=()
fixexpiry() {
local ts randoffset expshift
ts=$1
[[ -n $2 ]] && randoffset=$2 || offset=5
[[ -n $3 ]] && expshift=$3 || expshift=-30
echo $(( ts + RANDOM * randoffset * 86400 / 32767 + expshift * 86400))
}
certbot certificates > certs.txt
eval "$(cat certs.txt | awk '
/Domains:/ {print "\ndom+=(" $2 ")"; $1=$2=""; printf "altdoms+=(\""; for (i=3;i<=NF;i++) printf $i (i==NF ? "" : ","); print "\")"}
/Expiry Date:/ {print "expiry+=(\"" $3 " " $4 "\")"}
/Certificate Path:/ {print "certpath+=(" $3 ")"}
/Private Key Path:/ {print "keypath+=(" $4 ")"}
')"
i=0
for d in ${dom[@]}; do
echo "Converting: $d"
echo "Alternative names: ${altdoms[$i]}"
echo "Expiration: ${expiry[$i]}"
echo "Cert path: ${certpath[$i]}"
echo "Key path: ${keypath[$i]}"
siteroot=$ACME_SH_ROOT/$d
mkdir -p $siteroot
[[ -n ${altdoms[$i]} ]] && ad=$'\n'"Le_Alt='${altdoms[$i]}'" || ad=""
renewal=$(date -d "${expiry[$i]}" -u '+%s')
reloadcmd_b64=$(echo -n "$RELOADCMD" | base64)
renewal=$(fixexpiry $renewal 5 -30)
renewalstr=$(date -d @$renewal -u '+%FT%TZ')
creation=$(date +%s)
creation=$((creation - 86400 * 30))
creationstr=$(date -d @$creation -u '+%FT%TZ')
echo "New renewal date: $renewalstr"
cat >$siteroot/$d.conf <<EOF
Le_Domain='$d'$ad
Le_Webroot='$WEBROOT'
Le_PreHook=''
Le_PostHook=''
Le_RenewHook=''
Le_Keylength='2048'
Le_NextRenewTimeStr='$renewalstr'
Le_NextRenewTime='$renewal'
Le_CertCreateTimeStr='$creationstr'
Le_CertCreateTime='$creation'
Le_RealCertPath=''
Le_RealCACertPath=''
Le_RealKeyPath=''
Le_ReloadCmd='__ACME_BASE64__START_${reloadcmd_b64}__ACME_BASE64__END_'
Le_RealFullChainPath=''
Le_API='https://acme-v02.api.letsencrypt.org/directory'
EOF
cp -aH $(dirname ${certpath[$i]})/fullchain.pem $siteroot/fullchain.cer
cp -aH ${certpath[$i]} $siteroot/$d.cer
cp -aH ${keypath[$i]} $siteroot/$d.key
sed -i -e "s@$(dirname ${certpath[$i]})/fullchain.pem@$siteroot/fullchain.cer@" -e "s@${keypath[$i]}@$siteroot/$d.key@" $WEBCONF_ROOT/*
echo "====="
i=$((i + 1))
done
@kobuki
Copy link
Copy Markdown
Author

kobuki commented May 29, 2024

@bharatvaj
Copy link
Copy Markdown

This helped me in a migration. Thanks!

Some may get error when parsing the dates in alpine linux. Changing the code after line: 42 to the following fixes it,

      renewal=$(date -u -D '%Y-%m-%d %H:%M:%S+00:00' -d "${expiry[$i]}" '+%s')
      reloadcmd_b64=$(echo -n "$RELOADCMD" | base64)
      renewal=$(fixexpiry $renewal 5 -30)
      #renewalstr=$(date -u -D '%Y-%m-%d %H:%M:%S+00:00' -d $renewal +%FT%TZ) #-u '+%FT%TZ'
      renewalstr=$(date -u -d @$renewal +%FT%TZ) #-u '+%FT%TZ'
      creation=$(date +%s)
      creation=$((creation - 86400 * 30))
      creationstr=$(date -d @$creation -u '+%FT%TZ')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment