Tutorial: Set up a Bitcoin Lightning Node on a Raspberry Pi!

This guide was written by Edwin Kiaraho, a Community Member at BitHub Africa. Reach Edwin at ekairu(at)alumni.cmu.edu.

Prerequisites

This guide was pieced together from several other online guides including:

 

Port Forwarding

Unless your Raspberry Pi is hosted on the network DMZ with a public IP address, you will need to forward incoming Bitcoin and Lightning connections. Instructions on how to enable port forwarding depend on your router make and model. At a minimum, the following ports need to be forwarded to your Raspberry Pi: tcp/8333, tcp/9735, tcp/18333. You may also need to assign your Raspberry Pi a static IP address if port forwarding is not based on hostname or MAC address.

 

Raspberry Pi Configuration

Run the following command to change the password for the default user, configure network settings, localization options, etc.

 

$ sudo raspi-config

 

Software Updates

 

Run the following commands to install the latest software and security updates. Updates should be installed at least once a month. If the Bitcoin or LND services are running, stop them before installing updates.

 

$ sudo apt-get update

$ sudo apt-get upgrade

 

Disable Swap File

 

By default, the Raspberry Pi uses a portion of the SD card’s available space for virtual memory. This will degrade the SD card very quickly when running Bitcoin and LND software.

 

$ sudo swapoff –all

$ sudo apt-get remove dphys-swapfile

 

Bitcoin Service Account

Running Bitcoin or LND as the default user is not recommend given ‘pi’ can execute commands as ‘root’ via the sudo command. This can lead to privilege escalation attacks if remote execution bugs are discovered in the Bitcoin or LND software.

 

$ sudo adduser bitcoin

 

Enable Firewall

Run the following command to install and enable the Uncomplicated Firewall to limit access to the Raspberry Pi. Note that <IP_ADDR> refers to a specific host (IP address) or network (IP address + CIDR).

 

# Install firewall

$ sudo apt-get install ufw

 

# Create firewall rules

$ sudo ufw default deny incoming

$ sudo ufw default allow outgoing

$ sudo ufw allow from <IP_ADDR> to any port 22 comment ‘allow SSH from specific host or network’

$ sudo ufw allow 8333 comment ‘allow Bitcoin’

$ sudo ufw allow 9735 comment ‘allow Lightning’

$ sudo ufw allow 18333 comment ‘allow Bitcoin Testnet’

 

# Enable firewall and check status

$ sudo ufw enable

$ sudo ufw status

 

# Enable firewall on boot

$ sudo systemctl enable ufw

 

Mount External Storage

Unless you have an SD card with a capacity of more than 256GB, you will need an external USB drive to store a fully indexed copy of the Bitcoin blockchain. Use of an external USB drive is also recommended to reduce SD card degradation, caused by the high number of Bitcoin database read and write operations.

 

# Identify the partition, file system type and UUID

$ sudo lsblk -o UUID,NAME,FSTYPE,SIZE,LABEL,MODEL

 

# Install ExFAT or NTFS drivers depending on the identified file system type

$ sudo apt-get install exfat-fuse

$ sudo apt-get install ntfs-3g

 

# Create an fstab entry to mount the USB drive on boot

$ sudo nano /etc/fstab

 

# Add the following line for an ExFAT file system

UUID=<UUID_VALUE>     /mnt/hdd exfat defaults,nofail,auto,umask=000,users,rw 0 0

 

# Create the mount point then mount the USB drive

$ sudo mkdir /mnt/hdd

$ sudo mount -a

 

—–

 

Bitcoin Core

External Sync

Due to the CPU and memory limitations of the Raspberry Pi, we recommend syncing a fully indexed copy of the Bitcoin blockchain using a desktop or laptop computer. You can check the status of the sync by comparing the value of the ‘blocks’ field from the bitcoin-cli getblockchaininfo command, to the output of the wget -q -O- https://blockchain.info/q/getblockcount command.

 

Once fully synced, copy the following directories to the external USB drive used by the Raspberry Pi.

 

bitcoin/blocks

bitcoin/chainstate

bitcoin/database

 

Install Bitcoin

Run the following commands to install the latest Bitcoin Core software (currently v0.16).

 

# Download the Bitcoin Core 0.16 software

$ wget https://bitcoin.org/bin/bitcoin-core-0.16.0/bitcoin-0.16.0-arm-linux-gnueabihf.tar.gz

 

# Extract, install and verify the Bitcoin software

$ tar -xzf bitcoin-0.16.0-arm-linux-gnueabihf.tar.gz

$ sudo install -m 0755 -o root -g root -t /usr/local/bin bitcoin-0.16.0/bin/*

$ bitcoind –version

 

Configure Bitcoin

Run the following commands to configure the Bitcoin client. Note that <USER_VALUE> and <PASS_VALUE> refer to RPC credentials specific to your Bitcoin node. Do not reuse the credentials for the ‘pi’, ‘root’ or ‘bitcoin’ accounts.

 

# Switch to user ‘bitcoin’ context

$ sudo su bitcoin

$ cd ~

 

# Create the ‘bitcoin’ directory on the external USB drive if it does not exist

$ mkdir /mnt/hdd/bitcoin

 

# Add a symbolic link that points to the ‘bitcoin’ directory on the external USB drive

$ ln -s /mnt/hdd/bitcoin /home/bitcoin/.bitcoin

 

# Create the Bitcoin configuration file

$ nano /home/bitcoin/.bitcoin/bitcoin.conf

 

# Add the following lines to the Bitcoin configuration file

# Example bitcoin.conf for RaspiBolt

server=1

daemon=1

testnet=0

txindex=1

 

# Connection Settings

rpcuser=<USER_VALUE>

rpcpassword=<PASS_VALUE>

zmqpubrawblock=tcp://127.0.0.1:18501

zmqpubrawtx=tcp://127.0.0.1:18501

 

# Raspberry Pi Optimizations

dbcache=100

maxorphantx=10

maxmempool=50

maxconnections=20

maxuploadtarget=5000

 

# Exit user ‘bitcoin’ context

$ exit

 

Configure Bitcoin Service

Run the following commands to create and enable the Bitcoin service.

 

# Create the Bitcoin service

$ sudo nano /etc/systemd/system/bitcoind.service

 

# Add the following lines to the Bitcoin service file

[Unit]

Description=Bitcoin daemon

After=network.target

 

[Service]

User=bitcoin

Group=bitcoin

Type=forking

PIDFile=/home/bitcoin/.bitcoin/bitcoind.pid

ExecStart=/usr/local/bin/bitcoind -pid=/home/bitcoin/.bitcoin/bitcoind.pid

KillMode=process

Restart=always

TimeoutSec=120

RestartSec=30

 

[Install]

WantedBy=multi-user.target

 

# Enable the Bitcoin service on boot

$ sudo systemctl enable bitcoind.service

 

# Start the Bitcoin service and check latest debug status

$ sudo systemctl start bitcoind

$ systemctl status bitcoind

$ tail /home/bitcoin/.bitcoin/debug.log

 


 

Lightning Network Daemon

Install LND

Run the following commands to install the latest LND software (currently v0.4).

 

# Download the LND 0.14 software

$ wget https://github.com/lightningnetwork/lnd/releases/download/v0.4-beta/lnd-linux-arm-v0.4-beta.tar.gz

 

# Extract, install and verify the LND software

$ tar -xzf lnd-linux-arm-v0.4-beta.tar.gz

$ sudo install -m 0755 -o root -g root -t /usr/local/bin lnd-linux-arm-v0.4-beta/*

$ lnd –version

$ lncli –version

 

Configure LND

Run the following commands to configure the LND client. Note that <ALIAS_NAME> refers the user-specified alias of your LND node. <COLOR_VALUE> refers to the user-specified color of your LND node in hex format (e.g. #3399FF).

 

# Switch to user ‘bitcoin’ context

$ sudo su bitcoin

$ cd ~

 

# Create the LND configuration file

$ nano /home/bitcoin/.lnd/lnd.conf

 

# Add the following lines to the LND configuration file

[Application Options]

debuglevel=debug

debughtlc=true

maxpendingchannels=1

alias=<ALIAS_NAME>

color=<COLOR_VALUE>

 

[Bitcoin]

bitcoin.active=1

bitcoin.mainnet=1

bitcoin.node=bitcoind

 

[autopilot]

autopilot.active=1

autopilot.maxchannels=5

autopilot.allocation=0.6

 

# Exit user ‘bitcoin’ context

$ exit

 

Configure LND Service

Run the following commands to create and enable the LND service. Note that <X.X.X.X> refers to external IP address of your LND node. If your node is on an internal network, you should use the IP address assigned to your Internet router.

 

You can also obtain this IP address by running the command wget -q -O- http://ipinfo.io/ip from your Raspberry Pi. If the external IP address changes in the future, stop the LND service, update <X.X.X.X> and restart the service.

 

# Create the LND service

$ sudo nano /etc/systemd/system/lnd.service

 

# Add the following lines to the LND service file

[Unit]

Description=Lightning Network daemon

Requires=bitcoind.service

After=bitcoind.service

 

[Service]

PIDFile=/home/bitcoin/.lnd/lnd.pid

ExecStart=/usr/local/bin/lnd –externalip=<X.X.X.X>

Restart=always

RestartSec=60

User=bitcoin

Group=bitcoin

Type=simple

 

[Install]

WantedBy=multi-user.target

 

# Enable LND service on boot

$ sudo systemctl enable lnd.service

 

# Start LND service and check the latest debug status

$ sudo systemctl start lnd

$ systemctl status lnd

$ tail /home/bitcoin/.lnd/logs/bitcoin/mainnet/lnd.log

 

Using LND

The following covers the basics of LND command-line usage. For additional commands run the command lncli –help or see the link http://api.lightning.community/.

 

<PUBKEY> and <HOST> refer to the identity public key and external hostname or IP address of the external LND node you are connecting to. <PORT> is an optional value that refers to the port number that node is listening on. The default value is TCP port 9735.

 

<AMOUNT> refers to the amount of money in satoshis. <TXID> refers to the transaction ID of the channel’s funding transaction. <INDEX> is an optional value that refers to the output index for the funding output of the funding transaction.

 

<PAY_ID> refers to the zpay32 encoded payment request to fulfill.

 

# Switch to user ‘bitcoin’ context

$ sudo su bitcoin

$ cd ~

 

# View basic diagnostic information such as your identity public key

$ lncli getinfo

 

# Create a new wallet and backwards-compatible p2sh address

$ lncli create

$ lncli newaddress np2wkh

$ lncli walletbalance

 

# Opening, viewing and closing channels

$ lncli connect <PUBKEY>@<HOST>:<PORT>

$ lncli openchannel –node_key=<PUBKEY> –local_amt=<AMOUNT>

$ lncli listpeers

$ lncli listchannels

$ lncli closechannel –funding_txid=<TXID> –output_index=<INDEX>

 

# Creating and decoding invoices

$ lncli addinvoice –amt=<AMOUNT>

$ lncli decodepayreq –pay_req=<PAY_ID>

 

# Sending and viewing payments

$ lncli sendpayment –pay_req=<PAY_ID>

$ lncli listpayments

 

# Exit user ‘bitcoin’ context

$ exit


This guide was written by Edwin Kiaraho, a Community Member at BitHub Africa. Reach Edwin at ekairu(at)alumni.cmu.edu.