Skip to content

Instantly share code, notes, and snippets.

@giulnz
Forked from vindard/cln-sqlite-backup.sh
Created May 10, 2019 12:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save giulnz/3943278ef34097e163e86cb8e6b6ab70 to your computer and use it in GitHub Desktop.
Save giulnz/3943278ef34097e163e86cb8e6b6ab70 to your computer and use it in GitHub Desktop.
A script built off of @alexbosworth's backup script that monitors lnd's `channel.backup` file for changes and uploads those changes to Dropbox when detected.

Lnd Automated Channel Backup Guide

This script was inspired by @alexbosworth's channel.backup backup script and my own .lnd folder backup script. It monitors lnd's channel.backup file for changes and uploads those changes to Dropbox when detected.

Setup Script

To get started, download the script:

$ cd && wget -qN https://gist.githubusercontent.com/vindard/e0cd3d41bb403a823f3b5002488e3f90/raw/4bcf3c0163f77443a6f7c00caae0750b1fa0d63d/lnd-channel-backup.sh
$ sudo chmod +x lnd-channel-backup.sh

Setup Dropbox API Key

In your web browser, do the following:

  1. Go to https://www.dropbox.com/developers/apps/create and sign in

  2. Choose Dropbox Api

    Dropbox API 1

  3. Choose App Folder

    Dropbox API 2

  4. Name your app and click Create App to proceed

    Dropbox API 3

  5. On the settings page for your new app, scroll down to OAuth 2 and click Generate

    Dropbox API 4

  6. You will now see a string of letters and numbers appear. This is your Api Token. Copy this token and keep it safe for the next steps. This api token will be referenced as <dropbox-api-token> in the next step.

  7. Return to your terminal and run the following to insert the api token into the backup script:

    $ TOKEN=<dropbox-api-token>
    $ cd && sed -i "s/DROPBOX_APITOKEN=\".*\"/DROPBOX_APITOKEN=\"$TOKEN\"/" lnd-channel-backup.sh
    $ unset TOKEN
    

Setup script as systemd service

Create file: sudo nano /etc/systemd/system/backup-channels.service

Note: be sure to change the <user-here> value to your own home folder's name

[Service]
ExecStart=/home/<user-here>/lnd-channel-backup.sh
Restart=always
RestartSec=1
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=backup-channels
User=root
Group=root

[Install]
WantedBy=multi-user.target

Start

sudo systemctl start backup-channels

Monitor

journalctl -fu backup-channels

Run at boot

sudo systemctl enable backup-channels

#!/bin/bash
# SET DROPBOX API KEY FOR UPLOADS
DROPBOX_APITOKEN=""
# OPTIONAL SET A DEVICE NAME TO BE USED FOR BACKUPS (DEFAULTS TO /etc/hostname)
DEVICE=""
# INOTIFY CHECK
# --------------
install_inotify () {
sudo apt update
sudo apt install -y inotify-tools
}
inotifycheck () {
dpkg -s "inotify-tools" &> /dev/null
if [ ! $? -eq 0 ]; then
install_inotify
fi
}
# SETUP
# --------------
setup_files_and_folders () {
# Fetches the user whose home folder the directories will be stored under
ADMINUSER=( $(ls /home | grep -v bitcoin) )
if [ -z "$DEVICE" ] ; then
DEVICE=$(echo $(cat /etc/hostname))
fi
DEVICE=$(echo $DEVICE | awk '{print tolower($0)}' | sed -e 's/ /-/g')
# Setup folders and filenames
DATADIR=/home/bitcoin/.lnd
WORKINGDIR=/home/$ADMINUSER/lnd-data-backups
BACKUPFOLDER=.lndbackup-$DEVICE
# channel.backup file details
CHANFILEDIR=data/chain/bitcoin/mainnet
BACKUPFILE=channel.backup
SOURCEFILE=$DATADIR/$CHANFILEDIR/$BACKUPFILE
# Make sure necessary folders exist
if [[ ! -e ${WORKINGDIR} ]]; then
mkdir -p ${WORKINGDIR}
fi
cd ${WORKINGDIR}
if [[ ! -e ${BACKUPFOLDER} ]]; then
mkdir -p ${BACKUPFOLDER}
fi
cd ${BACKUPFOLDER}
}
# CHECKS
# --------------
online_check () {
wget -q --tries=10 --timeout=20 --spider http://google.com
if [[ $? -eq 0 ]]; then
ONLINE=true
else
ONLINE=false
fi
#echo "Online: "$ONLINE
}
dropbox_api_check () {
VALID_DROPBOX_APITOKEN=false
curl -s -X POST https://api.dropboxapi.com/2/users/get_current_account \
--header "Authorization: Bearer "$DROPBOX_APITOKEN | grep rror
if [[ ! $? -eq 0 ]] ; then
VALID_DROPBOX_APITOKEN=true
else
echo "Invalid Dropbox API Token!"
fi
}
dropbox_upload_check () {
UPLOAD_TO_DROPBOX=false
if [ ! -z $DROPBOX_APITOKEN ] ; then
online_check
if [ $ONLINE = true ] ; then
dropbox_api_check
else
echo "Please check that the internet is connected and try again."
fi
if [ $VALID_DROPBOX_APITOKEN = true ] ; then
UPLOAD_TO_DROPBOX=true
fi
fi
}
# UPLOAD
# --------------
upload_to_dropbox () {
FINISH=$(curl -s -X POST https://content.dropboxapi.com/2/files/upload \
--header "Authorization: Bearer "${DROPBOX_APITOKEN}"" \
--header "Dropbox-API-Arg: {\"path\": \"/"$BACKUPFOLDER"/"$1"\",\"mode\": \"overwrite\",\"autorename\": true,\"mute\": false,\"strict_conflict\": false}" \
--header "Content-Type: application/octet-stream" \
--data-binary @$1)
#echo $FINISH | jq .
UPLOADTIME=$(echo $FINISH | jq -r .server_modified)
if [ ! -z $UPLOADTIME ] ; then
echo "Successfully uploaded!"
else
echo "Unknown error when uploading..."
fi
}
# RUN CHECKS AND IF PASS, EXECUTE BACKUP TO DROPBOX
run_dropbox_backup () {
dropbox_upload_check
if [ $UPLOAD_TO_DROPBOX = true ] ; then
upload_to_dropbox $1
fi
}
##############
# RUN SCRIPT
##############
run_backup_on_change () {
echo "Copying backup file..."
cp $SOURCEFILE $BACKUPFILE
md5sum $SOURCEFILE > $BACKUPFILE.md5
sed -i 's/\/.*\///g' $BACKUPFILE.md5
echo
echo "Uploading backup file: '"${BACKUPFILE}"'..."
run_dropbox_backup $BACKUPFILE
echo "---"
echo "Uploading signature: '"${BACKUPFILE}.md5"'..."
run_dropbox_backup $BACKUPFILE.md5
}
run () {
inotifycheck
setup_files_and_folders
while true; do
inotifywait $SOURCEFILE
run_backup_on_change
echo
done
}
run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment