Add Let's Encrypt ACME client (#1216)

* add Let's Encrypt Client 'acme.sh'
This commit is contained in:
frennkie 2020-05-31 00:51:32 +02:00 committed by GitHub
parent 60ea450c6a
commit 9b0b7af6da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 280 additions and 19 deletions

61
FAQ.md
View File

@ -5,6 +5,7 @@
- Fix: DropBox StaticChannelBackup
- New: Balance of Satoshis [details](https://github.com/alexbosworth/balanceofsatoshis)
- New: Faraday [details](https://github.com/lightninglabs/faraday)
- New: Let's Encrypt client [details](FAQ.md#how-to-use-the-lets-encrypt-client)
## Whats new in Version 1.5 of RaspiBlitz?
@ -977,3 +978,63 @@ If you cannot login per SSH into your RaspiBlitz your SSH RaspiBlitz certs might
- then try again to SSH login
If you see a "REMOTE HOST IDENTIFICATION HAS CHANGED!" warning on login thats what we wanted - the SSH cert of your RaspiBlitz changed - thats good. We just need to remove the old one from our laptop first - on OSX you can use `rm ~/.ssh/known_hosts` (deletes all cached server certs) or remove the line with your RaspiBlitz IP manually from the `~/.ssh/known_hosts` file with a text editor.
## How to use the Let's Encrypt client
The [Let's Encrypt](https://letsencrypt.org/) client software [acme.sh](https://github.com/acmesh-official/acme.sh) is
included (since v1.6) and can be used to create TLS certificates that are signed by the Certificate Authority (*Root
CA*) **Let's Encrypt** and which are therefore trusted on all modern platforms.
In order to successfully get a signed certificate you need to **verify ownership** over a **DNS domain** or a **full
qualified domain name** (**FQDN**). Currently Let's Encrypt **doesn't** issue certificates for IP addresses. The two
most common standards for verification of control are `HTTP-01` and `DNS-01`.
The **acme.sh** client supports both modes and has a large number of DNS services (more than 50) it can interact with.
More details can be found on the [acme.sh wiki](https://github.com/acmesh-official/acme.sh/wiki).
### Let's Encrypt - HTTP-01
To use `HTTP-01` your RaspiBlitz needs to be accessible directly from the Internet on a **public IP address** on **port
80**. If you don't have a public IPv4/IPv6 IP on either `eth0` or `wlan0` then it might be possible to use **NAT port
forwarding** or an **autossh-tunnel** to fulfill this requirement.
If everything (this includes creating a `DNS A` or `DNS CNAME` record that points to a static or dynamic IP address) is
set up so that the Let's Encrypt servers can reach your RaspiBlitz on port 80 then the following command will perform
the initial creation of a signed certificate and will also store the configuration data needed to regularly refresh it.
Just run this once and then lean back and forget about it. :-D
```
~/.acme.sh/acme.sh --keylength ec-256 --issue -d hostname.example.com -w /var/www/letsencrypt/
```
### Let's Encrypt - DNS-01
The `DNS-01` standard **proves ownership** by creating `DNS TXT` records on the domain or subdomain you want to use.
This requires interaction with and access to a dns server but comes with the benefit that `wildcard certificates`
can be issued.
It is beyond the scope of this FAQ entry to explain all details of this - please refer to the official documentation.
Assuming you are using the [DuckDNS](https://www.duckdns.org/) dynamic DNS service then the following command will
get a certificate (including a wildcard subject alternative name (**SAN**) listing). It will also take care of continuous
renewals.
```
export DuckDNS_Token="abcdefgh-0123-56ij-78kl-abcd9012efgh"
~/.acme.sh/acme.sh --issue --keylength ec-256 --dns dns_duckdns -d hostname.duckdns.org -d *.hostname.duckdns.org
```
As mentioned more that 50 other services (including self-hosted options like e.g. `nsupdate` or `PowerDNS`) are supported.
### Let's Encrypt - eMail Address
The installation process of the `acme.sh` client includes a prompt for an eMail address. The data entered there is
stored in the `accounts.conf` file as `ACCOUNT_EMAIL`. This address is used by Let's Encrypt to notify you about
the expiry of certificates (which is not really needed as renewals are automated) and also about changes to their
**Terms of Service**. For more details please check their [privacy policy](https://letsencrypt.org/privacy/).
It is currently considered completely fine to leave this field empty and not provide an eMail address.
### Let's Encrypt - Installation details
The `acme.sh` script is installed in `/home/admin/.acme.sh/` - the configuration and the certificates are stored on the
external hard disk in `/mnt/hdd/app-data/letsencrypt`.

View File

@ -25,6 +25,7 @@ if [ ${#joinmarket} -eq 0 ]; then joinmarket="off"; fi
if [ ${#LNBits} -eq 0 ]; then LNBits="off"; fi
if [ ${#faraday} -eq 0 ]; then faraday="off"; fi
if [ ${#bos} -eq 0 ]; then bos="off"; fi
if [ ${#letsencrypt} -eq 0 ]; then letsencrypt="off"; fi
echo "map dropboxbackup to on/off"
DropboxBackup="off";
@ -37,20 +38,20 @@ if [ "${chain}" = "test" ]; then chainValue="on"; fi
echo "map domain to on/off"
domainValue="off"
dynDomainMenu='DynamicDNS'
if [ ${#dynDomain} -gt 0 ]; then
if [ ${#dynDomain} -gt 0 ]; then
domainValue="on"
dynDomainMenu="${dynDomain}"
fi
echo "map lcdrotate to on/off"
lcdrotateMenu='off'
if [ ${lcdrotate} -gt 0 ]; then
if [ ${lcdrotate} -gt 0 ]; then
lcdrotateMenu='on'
fi
echo "map touchscreen to on/off"
touchscreenMenu='off'
if [ ${touchscreen} -gt 0 ]; then
if [ ${touchscreen} -gt 0 ]; then
touchscreenMenu='on'
fi
@ -82,6 +83,7 @@ l 'Lightning Loop' ${loop} \
4 'Run behind TOR' ${runBehindTor} \
5 'RTL Webinterface' ${rtlWebinterface} \
b 'BTC-RPC-Explorer' ${BTCRPCexplorer} \
c 'Let`s Encrypt Client' ${letsencrypt} \
s 'Cryptoadvance Specter' ${specter} \
6 'LND Auto-Unlock' ${autoUnlock} \
9 'Touchscreen' ${touchscreenMenu} \
@ -105,6 +107,7 @@ l 'Lightning Loop' ${loop} \
4 'Run behind TOR' ${runBehindTor} \
5 'RTL Webinterface' ${rtlWebinterface} \
b 'BTC-RPC-Explorer' ${BTCRPCexplorer} \
c 'Let`s Encrypt Client' ${letsencrypt} \
s 'Cryptoadvance Specter' ${specter} \
6 'LND Auto-Unlock' ${autoUnlock} \
7 'BTC UPnP (AutoNAT)' ${networkUPnP} \
@ -173,13 +176,13 @@ if [ "${chain}" != "${choice}" ]; then
echo "Creating a new LND Wallet for ${network}/${choice}net"
echo "****************************************************************************"
echo "A) For 'Wallet Password' use your PASSWORD C --> !! minimum 8 characters !!"
echo "B) Answere 'n' because you dont have a 'cipher seed mnemonic' (24 words) yet"
echo "B) Answer 'n' because you don't have a 'cipher seed mnemonic' (24 words) yet"
echo "C) For 'passphrase' to encrypt your 'cipher seed' use PASSWORD D (optional)"
echo "****************************************************************************"
sudo -u bitcoin /usr/local/bin/lncli --chain=${network} --network=${chain}net create 2>error.out
error=`sudo cat error.out`
if [ ${#error} -eq 0 ]; then
sleep 2
sleep 2
# WIN
tryAgain=0
echo "!!! Make sure to write down the 24 words (cipher seed mnemonic) !!!"
@ -217,10 +220,10 @@ if [ "${chain}" != "${choice}" ]; then
sudo mkdir /home/admin/.lnd/data/chain/${network}/${choice}net
sudo cp /home/bitcoin/.lnd/data/chain/${network}/${choice}net/admin.macaroon /home/admin/.lnd/data/chain/${network}/${choice}net
sudo chown -R admin:admin /home/admin/.lnd/
needsReboot=1
fi
else
else
echo "Testnet Setting unchanged."
fi
@ -232,7 +235,7 @@ if [ "${autoPilot}" != "${choice}" ]; then
anychange=1
sudo /home/admin/config.scripts/lnd.autopilot.sh ${choice}
needsReboot=1
else
else
echo "Autopilot Setting unchanged."
fi
@ -256,7 +259,7 @@ if [ "${loop}" != "${choice}" ]; then
dialog --title 'FAIL' --msgbox "${l1}\n${l2}\n${l3}" 7 65
fi
fi
else
else
echo "Loop Setting unchanged."
fi
@ -331,7 +334,7 @@ Please keep in mind that thru your LND node id & your previous IP history with y
" 16 76
# make sure AutoNAT & UPnP is off
/home/admin/config.scripts/lnd.autonat.sh off
/home/admin/config.scripts/lnd.autonat.sh off
/home/admin/config.scripts/network.upnp.sh off
fi
@ -340,7 +343,7 @@ Please keep in mind that thru your LND node id & your previous IP history with y
sudo /home/admin/config.scripts/internet.tor.sh ${choice}
needsReboot=1
else
else
echo "TOR Setting unchanged."
fi
@ -397,6 +400,36 @@ else
echo "BTC-RPC-Explorer Setting unchanged."
fi
# Let's Encrypt process choice
choice="off"; check=$(echo "${CHOICES}" | grep -c "c")
if [ ${check} -eq 1 ]; then choice="on"; fi
if [ "${letsencrypt}" != "${choice}" ]; then
echo "Let's Encrypt Client Setting changed .."
anychange=1
/home/admin/config.scripts/bonus.letsencrypt.sh ${choice}
errorOnInstall=$?
if [ "${choice}" = "on" ]; then
if [ ${errorOnInstall} -eq 0 ]; then
msg="Successfully installed."
else
msg="Failed to install!"
fi
else
if [ ${errorOnInstall} -eq 0 ]; then
msg="Successfully removed."
else
msg="Failed to remove!"
fi
fi
dialog --backtitle "Additional Services" \
--title "Let's Encrypt Client" \
--infobox "\n${msg}" 5 40 ; sleep 3
else
echo "Let's Encrypt Client Setting unchanged."
fi
# cryptoadvance Specter process choice
choice="off"; check=$(echo "${CHOICES}" | grep -c "s")
if [ ${check} -eq 1 ]; then choice="on"; fi
@ -433,7 +466,7 @@ if [ "${autoUnlock}" != "${choice}" ]; then
l1="AUTO-UNLOCK IS NOW OFF"
if [ "${choice}" = "on" ]; then
l1="AUTO-UNLOCK IS NOW ACTIVE"
fi
fi
l2="-------------------------"
l3="mobile/external wallets may need reconnect"
l4="possible change in macaroon / TLS cert"
@ -513,7 +546,7 @@ When finished use the new 'ELECTRS' entry in Main Menu for more info.\n
extraparameter="deleteindex"
fi
/home/admin/config.scripts/bonus.electrs.sh off ${extraparameter}
fi
fi
else
echo "ElectRS Setting unchanged."
@ -566,7 +599,7 @@ if [ "${lndmanage}" != "${choice}" ]; then
if [ "${lndmanage}" = "on" ]; then
sudo -u admin /home/admin/config.scripts/bonus.lndmanage.sh menu
fi
else
else
echo "lndmanage setting unchanged."
fi
@ -581,7 +614,7 @@ if [ "${faraday}" != "${choice}" ]; then
if [ "${faraday}" = "on" ]; then
sudo -u admin /home/admin/config.scripts/bonus.faraday.sh menu
fi
else
else
echo "faraday setting unchanged."
fi
@ -597,7 +630,7 @@ if [ "${bos}" != "${choice}" ]; then
if [ "${bos}" = "on" ]; then
sudo -u admin /home/admin/config.scripts/bonus.faraday.sh menu
fi
else
else
echo "Balance of Satoshis setting unchanged."
fi
@ -612,7 +645,7 @@ if [ "${LNBits}" != "${choice}" ]; then
sudo systemctl start lnbits
sudo -u admin /home/admin/config.scripts/bonus.lnbits.sh menu
fi
else
else
echo "LNbits setting unchanged."
fi
@ -628,7 +661,7 @@ if [ "${DropboxBackup}" != "${choice}" ]; then
source /mnt/hdd/raspiblitz.conf
sudo /home/admin/config.scripts/dropbox.upload.sh upload ${dropboxBackupTarget} /home/admin/.lnd/data/chain/${network}/${chain}net/channel.backup
fi
else
else
echo "Dropbox backup setting unchanged."
fi
@ -641,7 +674,7 @@ if [ "${keysend}" != "${choice}" ]; then
needsReboot=1
sudo -u admin /home/admin/config.scripts/lnd.keysend.sh ${choice}
dialog --msgbox "Accept Keysend is now ${choice} after Reboot." 5 46
else
else
echo "keysend setting unchanged."
fi

View File

@ -0,0 +1,167 @@
#!/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]"
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
###################
# 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
It will be used to e.g. notify you about certificate expiries 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 "/mnt/hdd/app-data/letsencrypt" ]; then
sudo mkdir -p "/mnt/hdd/app-data/letsencrypt"
fi
sudo chown admin:admin "/mnt/hdd/app-data/letsencrypt"
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}"
}
###################
# running as admin
###################
adminUserId=$(id -u admin)
if [ "${EUID}" != "${adminUserId}" ]; then
echo "error='please run as admin user'"
exit 1
fi
# add default value to RaspiBlitz config if needed
if ! grep -Eq "^letsencrypt" /mnt/hdd/raspiblitz.conf; then
echo "letsencrypt=off" >> /mnt/hdd/raspiblitz.conf
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
sudo sed -i "s/^letsencrypt=.*/letsencrypt=on/g" /mnt/hdd/raspiblitz.conf
address=$(menu_enter_email)
echo ""
acme_install "${address}"
echo ""
else
echo "*** Let's Encrypt Client 'acme.sh' appears to be installed already ***"
fi
###################
# 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
sudo sed -i "s/^letsencrypt=.*/letsencrypt=off/g" /mnt/hdd/raspiblitz.conf
"${ACME_INSTALL_HOME}/acme.sh" --uninstall \
--home "${ACME_INSTALL_HOME}" \
--config-home "${ACME_CONFIG_HOME}" \
--cert-home "${ACME_CERT_HOME}"
else
echo "*** Let's Encrypt Client 'acme.sh' not installed ***"
fi
else
echo "# FAIL: parameter not known - run with -h for help"
exit 1
fi