raspiblitz/home.admin/config.scripts/bonus.letsencrypt.sh

413 lines
12 KiB
Bash
Raw Normal View History

#!/bin/bash
# command info
if [ $# -eq 0 ] || [ "$1" = "-h" ] || [ "$1" = "--help" ] || [ "$1" = "-help" ]; then
echo "config script to install or remove the Let's Encrypt Client (ACME.SH)"
echo "bonus.letsencrypt.sh [on|off]"
echo "bonus.letsencrypt.sh issue-cert DNSSERVICE FULLDOMAINNAME APITOKEN ip|tor|ip&tor"
2020-07-14 17:22:40 +02:00
echo "bonus.letsencrypt.sh remove-cert FULLDOMAINNAME ip|tor|ip&tor"
2020-11-23 18:37:58 +01:00
echo "bonus.letsencrypt.sh refresh-nginx-certs"
exit 1
fi
source /mnt/hdd/raspiblitz.conf
ACME_LOAD_BASE_URL="https://codeload.github.com/acmesh-official/acme.sh/tar.gz"
ACME_VERSION="2.8.6"
ACME_INSTALL_HOME="/home/admin/.acme.sh"
ACME_CONFIG_HOME="/mnt/hdd/app-data/letsencrypt"
ACME_CERT_HOME="${ACME_CONFIG_HOME}/certs"
ACME_IS_INSTALLED=0
# if Tor is on test that CURL is by default running over Tor
# TODO: issue https://github.com/rootzoll/raspiblitz/issues/1341
#if [ "${runBehindTor}" == "on" ]; then
# echo "# checking if Tor proxy for CURL is working ..."
# checkTor=$(curl -s https://check.torproject.org | grep -c "Congratulations")
# if [ ${checkTor} -eq 0 ]; then
# echo "err='curl tor proxy not working'"
# exit 1
# else
# echo "# OK Tor proxy for CURL"
# fi
#fi
###################
# FUNCTIONS
###################
function menu_enter_email() {
HEIGHT=18
WIDTH=56
BACKTITLE="Manage TLS certificates"
TITLE="Let's Encrypt - eMail"
INPUTBOX="\n
You can *optionally* enter an eMail address.\n
\n
The address will not be included in the generated certificates.\n
\n
2021-08-27 09:59:21 +02:00
It will be used to e.g. notify you about certificate expiration and changes
to the Terms of Service of Let's Encrypt.\n
\n
Feel free to leave empty."
ADDRESS=$(dialog --clear \
--backtitle "${BACKTITLE}" \
--title "${TITLE}" \
--inputbox "${INPUTBOX}" ${HEIGHT} ${WIDTH} 2>&1 >/dev/tty)
echo "${ADDRESS}"
}
function acme_status() {
# check if acme is installed (either directory or cronjob)
cron_count=$(crontab -l | grep "acme.sh" -c)
if [ -f "${ACME_INSTALL_HOME}/acme.sh" ] || [ "${cron_count}" = "1" ]; then
ACME_IS_INSTALLED=1
else
ACME_IS_INSTALLED=0
fi
}
function acme_install() {
email="${1}"
# ensure socat
if ! command -v socat >/dev/null; then
echo "# installing socat..."
sudo apt-get update >/dev/null 2>&1
sudo apt-get install -y socat >/dev/null 2>&1
fi
if ! [ -d $ACME_CONFIG_HOME ]; then
sudo mkdir -p $ACME_CONFIG_HOME
fi
sudo chown admin:admin $ACME_CONFIG_HOME
rm -f "/tmp/acme.sh_${ACME_VERSION}.tar.gz"
if ! curl --silent --fail -o "/tmp/acme.sh_${ACME_VERSION}.tar.gz" "${ACME_LOAD_BASE_URL}/${ACME_VERSION}" 2>&1; then
echo "Error ($?): Download failed from: ${ACME_LOAD_BASE_URL}/${ACME_VERSION}"
rm -f "/tmp/acme.sh_${ACME_VERSION}.tar.gz"
exit 1
fi
if tar xzf "/tmp/acme.sh_${ACME_VERSION}.tar.gz" -C /tmp/; then
cd "/tmp/acme.sh-${ACME_VERSION}" || exit
if [ -n "${email}" ]; then
./acme.sh --install \
--noprofile \
--home "${ACME_INSTALL_HOME}" \
--config-home "${ACME_CONFIG_HOME}" \
--cert-home "${ACME_CERT_HOME}" \
--accountemail "${email}"
else
./acme.sh --install \
--noprofile \
--home "${ACME_INSTALL_HOME}" \
--config-home "${ACME_CONFIG_HOME}" \
--cert-home "${ACME_CERT_HOME}"
fi
fi
rm -f "/tmp/acme.sh_${ACME_VERSION}.tar.gz"
rm -Rf "/tmp/acme.sh_${ACME_VERSION}"
}
function refresh_certs_with_nginx() {
# FIRST: SET ALL TO DEFAULT SELF SIGNED
echo "# default IP certs"
sudo rm /mnt/hdd/app-data/nginx/tls.cert
2020-11-23 18:37:58 +01:00
sudo rm /mnt/hdd/app-data/nginx/tls.key
sudo ln -sf /mnt/hdd/lnd/tls.cert /mnt/hdd/app-data/nginx/tls.cert
sudo ln -sf /mnt/hdd/lnd/tls.key /mnt/hdd/app-data/nginx/tls.key
echo "# default TOR certs"
sudo rm /mnt/hdd/app-data/nginx/tor_tls.cert
sudo rm /mnt/hdd/app-data/nginx/tor_tls.key
sudo ln -sf /mnt/hdd/lnd/tls.cert /mnt/hdd/app-data/nginx/tor_tls.cert
sudo ln -sf /mnt/hdd/lnd/tls.key /mnt/hdd/app-data/nginx/tor_tls.key
# SECOND: SET LETSENCRPYT CERTS FOR SUBSCRIPTIONS
if [ "${letsencrypt}" != "on" ]; then
echo "# lets encrypt is off - so no certs replacements"
return
fi
certsDirectories=$(sudo ls ${ACME_CERT_HOME})
echo "# certsDirectories(${certsDirectories})"
directoryArray=(`echo "${certsDirectories}" | tr ' ' ' '`)
for i in "${directoryArray[@]}"; do
FQDN=$(echo "${i}" | cut -d "_" -f1)
echo "# i(${i})"
echo "# FQDN(${FQDN})"
# check if there is a LetsEncrypt Subscription for this domain
details=$(/home/admin/config.scripts/blitz.subscriptions.letsencrypt.py subscription-detail $FQDN)
2021-09-22 22:21:57 +02:00
if [ $(echo "${details}" | grep -c "error=") -eq 0 ] && [ ${#details} -gt 10 ]; then
echo "# details(${details})"
# get target for that domain
options=$(echo "${details}" | jq -r ".target")
2020-11-23 18:37:58 +01:00
# replace certs for clearnet
if [ "${options}" == "ip" ] || [ "${options}" == "ip&tor" ]; then
echo "# replacing IP certs for ${FQDN}"
sudo rm /mnt/hdd/app-data/nginx/tls.cert
2020-11-23 18:37:58 +01:00
sudo rm /mnt/hdd/app-data/nginx/tls.key
sudo ln -s ${ACME_CERT_HOME}/${FQDN}_ecc/fullchain.cer /mnt/hdd/app-data/nginx/tls.cert
sudo ln -s ${ACME_CERT_HOME}/${FQDN}_ecc/${FQDN}.key /mnt/hdd/app-data/nginx/tls.key
fi
2021-08-27 09:59:21 +02:00
# replace certs for tor
if [ "${options}" == "tor" ] || [ "${options}" == "ip&tor" ]; then
echo "# replacing TOR certs for ${FQDN}"
sudo rm /mnt/hdd/app-data/nginx/tor_tls.cert
sudo rm /mnt/hdd/app-data/nginx/tor_tls.key
sudo ln -s ${ACME_CERT_HOME}/${FQDN}_ecc/fullchain.cer /mnt/hdd/app-data/nginx/tor_tls.cert
sudo ln -s ${ACME_CERT_HOME}/${FQDN}_ecc/${FQDN}.key /mnt/hdd/app-data/nginx/tor_tls.key
fi
# todo maybe allow certs for single services later (dont forget that these also need to be replaced in 'on' then)
if [ "${options}" != "tor" ] && [ "${options}" != "ip" ] && [ "${options}" != "ip&tor" ]; then
echo "# FAIL target '${options}' not supported yet'"
fi
fi
done
}
###################
# running as admin
###################
adminUserId=$(id -u admin)
if [ "${EUID}" != "${adminUserId}" ]; then
echo "error='please run as admin user'"
exit 1
fi
###################
# update status
###################
acme_status
###################
# ON
###################
if [ "$1" = "1" ] || [ "$1" = "on" ]; then
if [ ${ACME_IS_INSTALLED} -eq 0 ]; then
echo "*** INSTALLING Let's Encrypt Client 'acme.sh' ***"
# setting value in RaspiBlitz config
/home/admin/config.scripts/blitz.conf.sh set letsencrypt "on"
2020-07-14 00:31:52 +02:00
address="$2"
if [ "$2" == "enter-email" ]; then
address=$(menu_enter_email)
echo ""
fi
# make sure storage directory exist
sudo mkdir -p $ACME_CERT_HOME 2>/dev/null
sudo chown -R admin:admin $ACME_CONFIG_HOME
sudo chmod -R 733 $ACME_CONFIG_HOME
# install the acme script
acme_install "${address}"
echo ""
# make sure already existing certs get refreshed in to nginx
refresh_certs_with_nginx
echo "# restarting nginx"
sudo systemctl restart nginx 2>&1
2020-07-14 17:44:32 +02:00
exit 0
else
2020-07-14 17:44:32 +02:00
echo "# *** Let's Encrypt Client 'acme.sh' appears to be installed already ***"
exit 1
fi
###################
# ISSUE-CERT
###################
elif [ "$1" = "issue-cert" ]; then
2020-07-14 16:56:35 +02:00
# check if letsencrypt is on
if [ "${letsencrypt}" != "on" ]; then
2021-08-27 09:59:21 +02:00
echo "error='letsencrypt is not on'"
2020-07-14 16:56:35 +02:00
exit 1
fi
# make sure storage directory exist
sudo mkdir -p $ACME_CERT_HOME 2>/dev/null
sudo chown -R admin:admin $ACME_CONFIG_HOME
sudo chmod -R 733 $ACME_CONFIG_HOME
# get and check parameters
dnsservice=$2
FQDN=$3
apitoken=$4
2020-07-14 15:20:59 +02:00
options=$5
if [ ${#dnsservice} -eq 0 ] || [ ${#FQDN} -eq 0 ] || [ ${#apitoken} -eq 0 ]; then
echo "error='invalid parameters'"
exit 1
fi
if [ ${#options} -eq 0 ]; then
options="ip&tor"
fi
# prepare values and exports based on dnsservice
if [ "${dnsservice}" == "duckdns" ]; then
echo "# preparing DUCKDNS"
dnsservice="dns_duckdns"
2020-07-14 15:15:35 +02:00
export DuckDNS_Token=${apitoken}
elif [ "${dnsservice}" == "dynu" ]; then
echo "# preparing DYNYU"
dnsservice="dns_dynu"
clientid=$(echo "${apitoken}" | cut -d ':' -f 1)
secret=$(echo "${apitoken}" | cut -d ':' -f 2)
export Dynu_ClientId="${clientid}"
export Dynu_Secret="${secret}"
else
echo "error='not supported dnsservice'"
exit 1
fi
2021-08-27 09:59:21 +02:00
# create certificates
2020-07-14 16:44:28 +02:00
echo "# creating certs for ${FQDN}"
2020-07-14 17:05:57 +02:00
$ACME_INSTALL_HOME/acme.sh --home "${ACME_INSTALL_HOME}" --config-home "${ACME_CONFIG_HOME}" --cert-home "${ACME_CERT_HOME}" --issue --dns ${dnsservice} -d ${FQDN} --keylength ec-256 2>&1
2020-07-14 18:08:12 +02:00
success1=$($ACME_INSTALL_HOME/acme.sh --list --home "${ACME_INSTALL_HOME}" --config-home "${ACME_CONFIG_HOME}" --cert-home "${ACME_CERT_HOME}" | grep -c "${FQDN}")
2020-07-14 18:12:25 +02:00
success2=$(sudo ls ${ACME_CERT_HOME}/${FQDN}_ecc//fullchain.cer | grep -c "/fullchain.cer")
2020-07-14 18:08:12 +02:00
if [ ${success1} -eq 0 ] || [ ${success2} -eq 0 ]; then
2020-07-14 15:26:29 +02:00
sleep 6
echo "error='acme failed'"
exit 1
fi
# test nginx config
refresh_certs_with_nginx
syntaxOK=$(sudo nginx -t 2>&1 | grep -c "syntax is ok")
testOK=$(sudo nginx -t 2>&1 | grep -c "test is successful")
if [ ${syntaxOK} -eq 0 ] || [ ${testOK} -eq 0 ]; then
echo "# to check details on nginx config use: sudo nginx -t"
echo "error='nginx config failed'"
exit 1
fi
# restart nginx
echo "# restarting nginx"
sudo systemctl restart nginx 2>&1
2020-07-14 17:44:32 +02:00
exit 0
2020-07-14 17:22:40 +02:00
###################
# REMOVE-CERT
###################
elif [ "$1" = "remove-cert" ]; then
# make sure storage directory exist
sudo mkdir -p $ACME_CERT_HOME 2>/dev/null
sudo chown -R admin:admin $ACME_CONFIG_HOME
sudo chmod -R 733 $ACME_CONFIG_HOME
2020-07-14 17:22:40 +02:00
# get and check parameters
FQDN=$2
options=$3
if [ ${#FQDN} -eq 0 ]; then
echo "error='invalid parameters'"
exit 1
fi
if [ ${#options} -eq 0 ]; then
options="ip&tor"
fi
2021-09-22 22:21:57 +02:00
echo "# bonus.letsencrypt.sh remove-cert ${FQDN} ${options}"
2020-07-14 17:22:40 +02:00
# remove cert from renewal
$ACME_INSTALL_HOME/acme.sh --remove -d "${FQDN}" --ecc --home "${ACME_INSTALL_HOME}" --config-home "${ACME_CONFIG_HOME}" --cert-home "${ACME_CERT_HOME}" 2>&1
2020-07-14 17:27:48 +02:00
# delete cert files
sudo rm -r ${ACME_CERT_HOME}/${FQDN}_ecc
2020-07-14 17:22:40 +02:00
# test nginx config
refresh_certs_with_nginx
2020-07-14 17:22:40 +02:00
syntaxOK=$(sudo nginx -t 2>&1 | grep -c "syntax is ok")
testOK=$(sudo nginx -t 2>&1 | grep -c "test is successful")
if [ ${syntaxOK} -eq 0 ] || [ ${testOK} -eq 0 ]; then
echo "# to check details on nginx config use: sudo nginx -t"
echo "error='nginx config failed'"
exit 1
fi
# restart nginx
echo "# restarting nginx"
sudo systemctl restart nginx 2>&1
2020-07-14 17:44:32 +02:00
exit 0
###################
# REFRESH NGINX CERTS
###################
2020-11-23 18:37:58 +01:00
elif [ "$1" = "refresh-nginx-certs" ]; then
# refresh nginx
refresh_certs_with_nginx
syntaxOK=$(sudo nginx -t 2>&1 | grep -c "syntax is ok")
testOK=$(sudo nginx -t 2>&1 | grep -c "test is successful")
if [ ${syntaxOK} -eq 0 ] || [ ${testOK} -eq 0 ]; then
echo "# to check details on nginx config use: sudo nginx -t"
echo "error='nginx config failed'"
exit 1
fi
echo "# restarting nginx"
sudo systemctl restart nginx 2>&1
2020-11-23 18:37:58 +01:00
###################
# OFF
###################
elif [ "$1" = "0" ] || [ "$1" = "off" ]; then
if [ ${ACME_IS_INSTALLED} -eq 1 ]; then
echo "*** UNINSTALLING Let's Encrypt Client 'acme.sh' ***"
# setting value in RaspiBlitz config
/home/admin/config.scripts/blitz.conf.sh set letsencrypt "off"
"${ACME_INSTALL_HOME}/acme.sh" --uninstall \
--home "${ACME_INSTALL_HOME}" \
--config-home "${ACME_CONFIG_HOME}" \
--cert-home "${ACME_CERT_HOME}"
# refresh nginx
refresh_certs_with_nginx
echo "# restarting nginx"
sudo systemctl restart nginx 2>&1
2020-07-14 17:01:04 +02:00
# remove old script install
sudo rm -r ${ACME_INSTALL_HOME}
sudo rm -r ${ACME_CONFIG_HOME}
2020-07-14 17:44:32 +02:00
exit 0
else
2020-07-14 17:44:32 +02:00
echo "# *** Let's Encrypt Client 'acme.sh' not installed ***"
exit 1
fi
else
echo "# FAIL: parameter not known - run with -h for help"
exit 1
fi