From 4de59b58b34fe6338a584cfa3fc32b5d6c6f7203 Mon Sep 17 00:00:00 2001 From: openoms <43343391+openoms@users.noreply.github.com> Date: Thu, 14 Dec 2023 18:40:05 +0100 Subject: [PATCH] verify bitcoin core install and update with all signing keys (#4306) * verify bitcoin core update with all signing keys * remove the fallbackSigner * verify bitcoin core install with all signing keys --- home.admin/config.scripts/bitcoin.install.sh | 208 +++++++++--------- home.admin/config.scripts/bitcoin.update.sh | 121 +++++----- home.admin/config.scripts/bonus.joinmarket.sh | 11 + 3 files changed, 166 insertions(+), 174 deletions(-) diff --git a/home.admin/config.scripts/bitcoin.install.sh b/home.admin/config.scripts/bitcoin.install.sh index 5f4671d19..cfad2ef07 100644 --- a/home.admin/config.scripts/bitcoin.install.sh +++ b/home.admin/config.scripts/bitcoin.install.sh @@ -1,58 +1,101 @@ #!/bin/bash +# set version (change if update is available) +# https://bitcoincore.org/en/download/ +bitcoinVersion="26.0" + + # command info -if [ $# -eq 0 ] || [ "$1" = "-h" ] || [ "$1" = "-help" ];then +if [ $# -eq 0 ] || [ "$1" = "-h" ] || [ "$1" = "-help" ]; then echo echo "bitcoin.install.sh install - called by build.sdcard.sh" echo "Install or remove parallel chains for Bitcoin Core:" - echo "bitcoin.install.sh [install|on|off] [signet|testnet|mainnet]" + echo "bitcoin.install.sh install" + echo "bitcoin.install.sh [on|off] [signet|testnet|mainnet]" + echo "Installs Bitcoin Core $bitcoinVersion by default" echo exit 1 fi +echo "# Running: bitcoin.install.sh $*" + +# mainnet | testnet | signet +CHAIN=${2:-mainnet} +if [ "${CHAIN}" != signet ] && [ "${CHAIN}" != testnet ] && [ "${CHAIN}" != mainnet ]; then + echo "# ${CHAIN} is not supported" + exit 1 +fi +# prefixes for parallel services +if [ "${CHAIN}" = testnet ]; then + prefix="t" + bitcoinprefix="test" + zmqprefix=21 # zmqpubrawblock=21332 zmqpubrawtx=21333 zmqpubhashblock=21334 + rpcprefix=1 # rpcport=18332 +elif [ ${CHAIN} = signet ]; then + prefix="s" + bitcoinprefix="signet" + zmqprefix=23 + rpcprefix=3 +elif [ ${CHAIN} = mainnet ]; then + prefix="" + bitcoinprefix="main" + zmqprefix=28 + rpcprefix="" +fi +# bitcoinlogpath +if [ ${CHAIN} = signet ]; then + bitcoinlogpath="/mnt/hdd/bitcoin/signet/debug.log" +elif [ ${CHAIN} = testnet ]; then + bitcoinlogpath="/mnt/hdd/bitcoin/testnet3/debug.log" +elif [ ${CHAIN} = mainnet ]; then + bitcoinlogpath="/mnt/hdd/bitcoin/debug.log" +fi + +function addBitcoinAliases { + echo "# Add aliases ${prefix}bitcoin-cli, ${prefix}bitcoinlog" + sudo -u admin touch /home/admin/_aliases + if ! grep "alias ${prefix}bitcoin-cli" /home/admin/_aliases; then + echo "alias ${prefix}bitcoin-cli=\"sudo -u bitcoin /usr/local/bin/bitcoin-cli -rpcport=${rpcprefix}8332\"" | + sudo tee -a /home/admin/_aliases + fi + if ! grep "alias ${prefix}bitcoinlog" /home/admin/_aliases; then + echo "alias ${prefix}bitcoinlog=\"sudo -u bitcoin tail -n 30 -f ${bitcoinlogpath}\"" | + sudo tee -a /home/admin/_aliases + fi + if ! grep "alias bitcoinconf" /home/admin/_aliases; then + echo "alias bitcoinconf=\"sudo nano /mnt/hdd/bitcoin/bitcoin.conf\"" | + sudo tee -a /home/admin/_aliases + fi + sudo chown admin:admin /home/admin/_aliases +} + if [ "$1" = "install" ]; then echo "*** PREPARING BITCOIN ***" - # set version (change if update is available) - # https://bitcoincore.org/en/download/ - bitcoinVersion="26.0" - - # needed to check code signing - # https://github.com/laanwj - laanwjPGP="71A3 B167 3540 5025 D447 E8F2 7481 0B01 2346 C9A6" - # prepare directories sudo rm -rf /home/admin/download sudo -u admin mkdir /home/admin/download cd /home/admin/download || exit 1 - # receive signer key - if ! gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-key "71A3 B167 3540 5025 D447 E8F2 7481 0B01 2346 C9A6" - then - echo "# FAIL # Couldn't download Wladimir J. van der Laan's PGP pubkey" - exit 1 - fi + echo "# Receive signer keys" + curl -s "https://api.github.com/repos/bitcoin-core/guix.sigs/contents/builder-keys" | + jq -r '.[].download_url' | while read url; do curl -s "$url" | gpg --import; done # download signed binary sha256 hash sum file - sudo -u admin wget https://bitcoincore.org/bin/bitcoin-core-${bitcoinVersion}/SHA256SUMS + sudo -u admin wget --prefer-family=ipv4 --progress=bar:force -O SHA256SUMS https://bitcoincore.org/bin/bitcoin-core-${bitcoinVersion}/SHA256SUMS + # download the signed binary sha256 hash sum file and check + sudo -u admin wget --prefer-family=ipv4 --progress=bar:force -O SHA256SUMS.asc https://bitcoincore.org/bin/bitcoin-core-${bitcoinVersion}/SHA256SUMS.asc - # download signed binary sha256 hash sum file and check - sudo -u admin wget https://bitcoincore.org/bin/bitcoin-core-${bitcoinVersion}/SHA256SUMS.asc - verifyResult=$(LANG=en_US.utf8; gpg --verify SHA256SUMS.asc 2>&1) - goodSignature=$(echo ${verifyResult} | grep 'Good signature' -c) - echo "goodSignature(${goodSignature})" - correctKey=$(echo ${verifyResult} | grep "${laanwjPGP}" -c) - echo "correctKey(${correctKey})" - if [ ${correctKey} -lt 1 ] || [ ${goodSignature} -lt 1 ]; then - echo - echo "# BUILD FAILED --> PGP Verify not OK / signature(${goodSignature}) verify(${correctKey})" - exit 1 - else + if gpg --verify SHA256SUMS.asc; then echo echo "****************************************" echo "OK --> BITCOIN MANIFEST IS CORRECT" echo "****************************************" echo + else + echo + echo "# BUILD FAILED --> the PGP verification failed" + exit 1 fi # bitcoinOSversion @@ -74,8 +117,8 @@ if [ "$1" = "install" ]; then sudo -u admin wget --quiet https://bitcoincore.org/bin/bitcoin-core-${bitcoinVersion}/${binaryName} fi if [ ! -f "./${binaryName}" ]; then - echo "# FAIL # Could not download the BITCOIN BINARY" - exit 1 + echo "# FAIL # Could not download the BITCOIN BINARY" + exit 1 else # check binary checksum test @@ -104,58 +147,21 @@ if [ "$1" = "install" ]; then sudo -u admin tar -xvf ${binaryName} sudo install -m 0755 -o root -g root -t /usr/local/bin/ bitcoin-${bitcoinVersion}/bin/* sleep 3 - installed=$(sudo -u admin bitcoind --version | grep "${bitcoinVersion}" -c) - if [ ${installed} -lt 1 ]; then + if ! sudo /usr/local/bin/bitcoind --version | grep "${bitcoinVersion}"; then echo echo "# BUILD FAILED --> Was not able to install bitcoind version(${bitcoinVersion})" exit 1 fi - if [ "$(alias | grep -c "alias bitcoinlog")" -eq 0 ];then - echo "alias bitcoinlog=\"sudo tail -n 30 -f /mnt/hdd/bitcoin/debug.log\"" | sudo tee -a /home/admin/_aliases - fi - sudo chown admin:admin /home/admin/_aliases + + addBitcoinAliases echo "- Bitcoin install OK" exit 0 fi - -# CHAIN is mainnet | testnet | signet -CHAIN=$2 -if [ "${CHAIN}" != signet ]&&[ "${CHAIN}" != testnet ]&&[ "${CHAIN}" != mainnet ];then - echo "# ${CHAIN} is not supported" - exit 1 -fi -# prefixes for parallel services -if [ "${CHAIN}" = testnet ];then - prefix="t" - bitcoinprefix="test" - zmqprefix=21 # zmqpubrawblock=21332 zmqpubrawtx=21333 zmqpubhashblock=21334 - rpcprefix=1 # rpcport=18332 -elif [ ${CHAIN} = signet ];then - prefix="s" - bitcoinprefix="signet" - zmqprefix=23 - rpcprefix=3 -elif [ ${CHAIN} = mainnet ];then - prefix="" - bitcoinprefix="main" - zmqprefix=28 - rpcprefix="" -fi -# bitcoinlogpath -if [ ${CHAIN} = signet ]; then - bitcoinlogpath="/mnt/hdd/bitcoin/signet/debug.log" -elif [ ${CHAIN} = testnet ]; then - bitcoinlogpath="/mnt/hdd/bitcoin/testnet3/debug.log" -elif [ ${CHAIN} = mainnet ]; then - bitcoinlogpath="/mnt/hdd/bitcoin/debug.log" -fi - - function removeParallelService() { - if [ -f "/etc/systemd/system/${prefix}bitcoind.service" ];then - if [ ${CHAIN} != mainnet ];then + if [ -f "/etc/systemd/system/${prefix}bitcoind.service" ]; then + if [ ${CHAIN} != mainnet ]; then /usr/local/bin/bitcoin-cli -${CHAIN} stop else /usr/local/bin/bitcoin-cli stop @@ -163,9 +169,9 @@ function removeParallelService() { sudo systemctl stop ${prefix}bitcoind sudo systemctl disable ${prefix}bitcoind sudo rm /etc/systemd/system/${prefix}bitcoind.service 2>/dev/null - if [ ${bitcoinprefix} = signet ];then + if [ ${bitcoinprefix} = signet ]; then # check for signet service set up by joininbox - if [ -f "/etc/systemd/system/signetd.service" ];then + if [ -f "/etc/systemd/system/signetd.service" ]; then sudo systemctl stop signetd sudo systemctl disable signetd echo "# The signetd.service is stopped and disabled" @@ -178,9 +184,9 @@ function removeParallelService() { function installParallelService() { echo "# Installing Bitcoin Core instance on ${CHAIN}" # bitcoin.conf - if [ ! -f /home/bitcoin/.bitcoin/bitcoin.conf ];then + if [ ! -f /home/bitcoin/.bitcoin/bitcoin.conf ]; then # add minimal config - randomRPCpass=$(< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c8) + randomRPCpass=$(tr get actual state and possible actions" echo "tested -> only do a tested update by the RaspiBlitz team" echo "reckless -> the update was not tested by the RaspiBlitz team" - echo "custom -> update to a chosen version" - echo " the binary will be checked by signature and checksum in all cases" + echo "custom -> update to a chosen version" + echo " the binary checksum and signatures will be checked in all cases" + echo " except when 'skipverify' is used" echo exit 1 fi +echo "# Running: bitcoin.update.sh $*" + # 1. parameter [info|tested|reckless] mode="$1" # RECOMMENDED UPDATE BY RASPIBLITZ TEAM (just possible once per sd card update) -# comment will be shown as "BEWARE Info" when option is choosen (can be multiple lines) +# comment will be shown as "BEWARE Info" when option is chosen (can be multiple lines) bitcoinVersion="" # example: 22.0 .. keep empty if no newer version as sd card build is available -# needed to check code signing -# https://github.com/emzy.gpg -fallbackSigner=Emzy - # GATHER DATA # setting download directory to the current user downloadDir="/home/$(whoami)/download/bitcoin.update" -# detect CPU architecture & fitting download link -if [ $(uname -m | grep -c 'arm') -eq 1 ]; then +# bitcoinOSversion +if [ "$(uname -m | grep -c 'arm')" -gt 0 ]; then bitcoinOSversion="arm-linux-gnueabihf" -fi -if [ $(uname -m | grep -c 'aarch64') -eq 1 ]; then +elif [ "$(uname -m | grep -c 'aarch64')" -gt 0 ]; then bitcoinOSversion="aarch64-linux-gnu" -fi -if [ $(uname -m | grep -c 'x86_64') -eq 1 ]; then +elif [ "$(uname -m | grep -c 'x86_64')" -gt 0 ]; then bitcoinOSversion="x86_64-linux-gnu" fi @@ -98,16 +95,21 @@ elif [ "${mode}" = "reckless" ]; then pathVersion=${bitcoinVersion} elif [ "${mode}" = "custom" ]; then - clear - echo - echo "# Update Bitcoin Core to a chosen version." - echo - echo "# Input the version you would like to install and press ENTER." - echo "# Examples (versions below 22 are not supported):" - echo "22.0rc3" - echo "24.0.1" - echo - read bitcoinVersion + if [ $# -gt 1 ]; then + bitcoinVersion="$2" + else + clear + echo + echo "# Update Bitcoin Core to a chosen version." + echo + echo "# Input the version you would like to install and press ENTER." + echo "# Examples (versions below 22.1 are not supported):" + echo "24.0.1" + echo "26.0" + echo + read bitcoinVersion + fi + if [ $(echo ${bitcoinVersion} | grep -c "rc") -gt 0 ]; then cutVersion=$(echo ${bitcoinVersion} | awk -F"r" '{print $1}') rcVersion=$(echo ${bitcoinVersion} | awk -F"r" '{print $2}') @@ -120,6 +122,9 @@ elif [ "${mode}" = "custom" ]; then if curl --output /dev/null --silent --head --fail \ https://bitcoincore.org/bin/bitcoin-core-${pathVersion}/SHA256SUMS.asc; then echo "# OK version exists at https://bitcoincore.org/bin/bitcoin-core-${pathVersion}" + if [ "${mode}" = "custom" ] && [ "$3" = "skipverify" ]; then + echo "# skipping signature verification" + fi echo "# Press ENTER to proceed to install Bitcoin Core $bitcoinVersion or CTRL+C to abort." read key else @@ -148,48 +153,34 @@ if [ "${mode}" = "tested" ] || [ "${mode}" = "reckless" ] || [ "${mode}" = "cust mkdir -p "${downloadDir}" cd "${downloadDir}" || exit 1 - # NOTE: this script is run by provision and cannot have user input at this point or it will lock up the provision process - # echo "# Enter the github username of a signer. Find the list of signers at: " - # echo "https://github.com/bitcoin-core/guix.sigs/tree/main/${pathVersion}" - # echo "# Example for Peter Wuille (https://github.com/sipa):" - # echo "sipa" - # echo "# example for Emzy (https://github.com/Emzy):" - # echo "Emzy" - # read customSigner - # if [ ${#customSigner} -eq 0 ]; then - # customSigner=$fallbackSigner - # fi - customSigner=$fallbackSigner + echo "# Receive signer keys" + curl -s "https://api.github.com/repos/bitcoin-core/guix.sigs/contents/builder-keys" | + jq -r '.[].download_url' | while read url; do curl -s "$url" | gpg --import; done - echo "# Download the binary sha256 hash sum file" - wget -O all.SHA256SUMS https://raw.githubusercontent.com/bitcoin-core/guix.sigs/main/${pathVersion}/${customSigner}/all.SHA256SUMS - echo "# Download signature of the binary sha256 hash sum file" - wget -O all.SHA256SUMS.asc https://raw.githubusercontent.com/bitcoin-core/guix.sigs/main/${pathVersion}/${customSigner}/all.SHA256SUMS.asc + # download signed binary sha256 hash sum file + wget --prefer-family=ipv4 --progress=bar:force -O SHA256SUMS https://bitcoincore.org/bin/bitcoin-core-${bitcoinVersion}/SHA256SUMS + # download the signed binary sha256 hash sum file and check + wget --prefer-family=ipv4 --progress=bar:force -O SHA256SUMS.asc https://bitcoincore.org/bin/bitcoin-core-${bitcoinVersion}/SHA256SUMS.asc - echo "# Download PGP pubkey of ${customSigner}" - if ! wget -O pubkey.asc https://github.com/${customSigner}.gpg; then - echo "# FAIL # Could not down - load the PGP pubkey of ${customSigner}" - rm pubkey.asc - exit 1 - fi - echo "# Import PGP pubkey of ${customSigner}" - if ! gpg --import pubkey.asc; then - echo "# FAIL # Couldn't import the PGP pubkey of ${customSigner}" - rm pubkey.asc - exit 1 - fi - rm pubkey.asc - - echo "# Checking PGP signature of the binary sha256 hash sum file" - if ! gpg --verify all.SHA256SUMS.asc; then - echo - echo "# BUILD FAILED --> the signature does not match" - exit 1 + if [ "${mode}" = "custom" ] && [ "$3" = "skipverify" ]; then + echo "# skipping signature verification" + echo "# display the output of 'gpg --verify SHA256SUMS.asc'" + gpg --verify SHA256SUMS.asc else - echo - echo "# OK --> BITCOIN MANIFEST IS CORRECT" - echo + if gpg --verify SHA256SUMS.asc; then + echo + echo "****************************************" + echo "OK --> BITCOIN MANIFEST IS CORRECT" + echo "****************************************" + echo + else + echo + echo "# BUILD FAILED --> the PGP verification failed" + echo "# try again or with a different version" + echo "# if you want to skip verifying all signatures (and just show them) use the command:" + echo "# /home/admin/config.scripts/bonus.bitcoin.sh custom ${bitcoinVersion:-} skipverify" + exit 1 + fi fi echo "# Downloading Bitcoin Core v${bitcoinVersion} for ${bitcoinOSversion} ..." @@ -201,9 +192,9 @@ if [ "${mode}" = "tested" ] || [ "${mode}" = "reckless" ] || [ "${mode}" = "cust fi echo "# Checking the binary checksum ..." - if ! sha256sum -c --ignore-missing all.SHA256SUMS; then + if ! sha256sum -c --ignore-missing SHA256SUMS; then # get the sha256 value for the corresponding platform from signed hash sum file - bitcoinSHA256=$(grep -i "${binaryName}}" all.SHA256SUMS | cut -d " " -f1) + bitcoinSHA256=$(grep -i "${binaryName}}" SHA256SUMS | cut -d " " -f1) echo "# FAIL # Downloaded BITCOIN BINARY CHECKSUM:" echo "$(sha256sum ${binaryName})" echo "NOT matching SHA256 checksum:" @@ -235,7 +226,7 @@ if [ "${mode}" = "tested" ] || [ "${mode}" = "reckless" ] || [ "${mode}" = "cust tar -xvf ${binaryName} sudo install -m 0755 -o root -g root -t /usr/local/bin/ bitcoin-${bitcoinVersion}/bin/* sleep 3 - if ! bitcoind --version | grep "${bitcoinVersion}"; then + if ! sudo /usr/local/bin/bitcoind --version | grep "${bitcoinVersion}"; then echo echo "# BUILD FAILED --> Was not able to install bitcoind version(${bitcoinVersion})" exit 1 diff --git a/home.admin/config.scripts/bonus.joinmarket.sh b/home.admin/config.scripts/bonus.joinmarket.sh index 48eefdfb8..139ba690b 100755 --- a/home.admin/config.scripts/bonus.joinmarket.sh +++ b/home.admin/config.scripts/bonus.joinmarket.sh @@ -192,6 +192,17 @@ if [ -z \"\$TMUX\" ]; then fi " | sudo -u joinmarket tee -a /home/joinmarket/.bashrc + echo "# Check 'deprecatedrpc=create_bdb' in bitcoin.conf" + if ! sudo grep "deprecatedrpc=create_bdb" "/mnt/hdd/bitcoin/bitcoin.conf"; then + echo "# Place 'deprecatedrpc=create_bdb' in bitcoin.conf" + echo "deprecatedrpc=create_bdb" | sudo tee -a "/mnt/hdd/bitcoin/bitcoin.conf" + source <(/home/admin/_cache.sh get state) + if [ ${state} != "recovering" ]; then + echo "# Restarting bitcoind" + sudo systemctl restart bitcoind + fi + fi + # make sure the Bitcoin Core wallet is on /home/admin/config.scripts/network.wallet.sh on if [ $(/usr/local/bin/bitcoin-cli -conf=/mnt/hdd/bitcoin/bitcoin.conf listwallets | grep -c wallet.dat) -eq 0 ]; then