Lightning Network node (c-lightning) on RBP3

Damian Mee
13 min readJun 26, 2018

--

This is a 3rd part to the guide on setting up your own Bitcoin Full Node on Raspberry Pi guide.

Note: Inspiration for this guide was taken from this guide by Stadicus, this article from Odroid Magazine, a lot of Twitter interactions, c-lightning docs and LightningCommunity Slack.

This guide assumes you’re on MacOS, comfortable with terminal, already have a Bitcoin Full Node running on Raspberry Pi 3 (optionally with Tor) and now you want to also add a c-lightning node to it.

BTC & LN ssh login dashboard

Before starting

While the node will sit idle most of the time, it will experience spikes. And for these moments, do make sure you at least have SWAP configured and any heat sinks attached to your Pi.

Note: In code snippets with output, bold parts are the commands to run.

It is HIGHLY recommended you play with testnet nodes first, and only move to the world of real, mainnet money when you feel comfortable enough!

Connect to RBP

Quite necessary, ex:

ssh pi@192.168.1.102

Once you’re connected, run updates:

sudo apt update
sudo apt -y upgrade

Get c-lightning

The below steps are based on the official INSTALL.md instructions for Ubuntu.

Dependencies

Before we start, let’s make sure all required dependencies are installed, with:

sudo apt-get install -y autoconf automake build-essential git libtool libgmp-dev libsqlite3-dev python python3 net-tools zlib1g-dev

Get the source code

Thanks to Wladimir, there are now two ways to fetch c-lightning:

Either from GitHub, or if you followed my previous Tor guide, and you want to run your LN node anonymously, you can start here by fetching the source using a Tor-hosted repo:

Github
The traditional way 🤵🏻. Fetching it from the source over the clearnet:

cd ~ 
git clone https://github.com/ElementsProject/lightning.git
cd lightning

Tor
The cypherpunk way 👩🏻‍💻. Fetching it from a mirror via the darknet. Good start if you intent to run LN node anonymously or through Tor only:

git -c http.proxy=socks5h://127.0.0.1:9050 clone http://nxshomzlgqmwfwhcnyvbznyrybh3gotlfgis7wkv7iur2yj2rarlhiad.onion/git/lightning.git
cd lightning
git config --add remote.origin.proxy "socks5h://127.0.0.1:9050"

Optionally you can also add Github as backup, with:

git remote add github https://github.com/ElementsProject/lightning.git

What to compile

Whichever way to fetch it you’ve chosen, all following instructions are identical.

Just yesterday c-lightning has released their first Beta 🎉, and I suggest sticking to them.

Protip: If you’re on a latest Release, but you experience a bug preventing you from using your node, it’s very likely that there already is a fix on a master branch — might be worth trying.

This guide might be outdated by the time you read it, so make sure to visit Releases page, and see which one is the newest:

Latest c-lightning Release being v0.6

At the time of writing this, it’s v0.6, so:

git checkout v0.6

Protip: In these early days it is recommended to update the node with each new release, as new (compatibility) bugs are squashed all the time.

Compile

Once you’re on a correct branch, the installation is quite straightforward:

./configure
make
sudo make install

Voilà :).

Set things up

Now, before we put things in motion there’s a bunch of things that need to be done first.

Generate Bitcoin RPC password

Let’s start with making sure c-lightning will be able to communicate with Bitcoin node.

python3 ~/bitcoin/share/rpcauth/rpcauth.py lightning
String to be appended to bitcoin.conf:
rpcauth=lightning:b721f772112599d454e5192c345c68$bcf157cf3debaf85de0eefaf90b3565f90717c5029b520befa74fbf35f80d46c
Your password:
a11IIMZKndBeFBsGaFV81X-mwX14nIr8b0EN9ltuF7o=

Make sure you copy and save the password!

Important: Do not use the credentials generated above ;).

Enable Bitcoin RPC authentication

Having the credentials generated, you need to enable them in the Bitcoin Core client:

sudo su - bitcoin
nano ~/.bitcoin/bitcoin.conf

Paste the rpcauth=lightning:… line there, save the file, and exit to the pi user with:

exit

Now, restart Bitcoin Core so it acknowledges newly added credentials:

sudo systemctl restart bitcoind

Note: Restarting Bitcoin on the RBP can take up to a few minutes.

c-lightning user

Similarly to Bitcoin, c-lightning will run as a separate user. Create it with:

sudo adduser lightning
Adding user `lightning' ...
Adding new group `lightning' (1002) ...
Adding new user `lightning' (1002) with group `lightning' ...
Creating home directory `/home/lightning' ...
Copying files from `/etc/skel' ...
Enter new UNIX password:
securePasswordIveSavedToPasswordManager
Retype new UNIX password:
securePasswordIveSavedToPasswordManager
passwd: password updated successfully
Changing the user information for lightning
Enter the new value, or press ENTER for the default
Full Name []:
BlockStream Core
Room Number []:
666
Work Phone []:
Home Phone []:
Other []:
probably lizard people
Is the information correct? [Y/n]
y

Note: Pick a secure password and save it to your password manager.

Once the user is created, switch to it to configure the LN node:

sudo su - lightning

Create configuration file

Create c-lightning data directory, and open it’s config file, with:

mkdir ~/.lightning
nano ~/.lightning/config

Once there, start with putting the necessary things there:

daemon
network=bitcoin
alias=ExtraPointsForMakingThisCreative
rgb=000000
bitcoin-rpcuser=lightning
bitcoin-rpcpassword=a11IIMZKndBeFBsGaFV81X-mwX14nIr8b0EN9ltuF7o=

Note: Replace bitcoin-rpcpassword with the RPC password you’ve generated above.

Other optional, but useful:

  • network=testnet —use this instead of network=bitcoin, if you want to run the node on Bitcoin testnet instead;
  • log-level=debug — makes your node log a lot more information (useful to have this on when something goes wrong);
  • log-file=/home/lightning/.lightning/debug.log — moves your logs from syslog, to a file in c-lightning data directory.

Allow port on the router

The last thing to do is, allowing c-lightning port on the firewall:

sudo ufw allow 9735 comment 'c-lightning'

Should work now…

…, but it doesn’t yet (at least for me) 😬. I think this will be the end of the basic setup in the future, but for now some pieces are still missing, and a few additional steps that need to be taken first.

Additional Steps

Get your own IP

There are many ways to do it, but the one I find the easiest is:

curl ipinfo.io/ip
203.150.176.91

Use the IP and port

Once you know your IP, add this to your ~/.lightning/config file:

announce-addr=203.150.176.91:9735
bind-addr=0.0.0.0:9735

Protip: If you’ve set up a static IP for that RBP on your router, replace 0.0.0.0 with that IP.

Protip_2: If you don’t remember you local IP, you can get it with: ip route get 1 | awk '{print $NF;exit}'.

Configure router

You can configure forwarding on your router manually (left as an exercise for the reader), or you can have it automated using MiniUPnP:

Important: Make sure your router supports UPnP and has it enabled!

First return to the pi user with:

exit

Once there, make sure you’re on the correct user:

whoami
pi

Install the binary that will be doing all the heavy lifting for you:

sudo apt install miniupnpc

Create a port-setting script:

mkdir ~/bin
nano ~/bin/set_ports.sh

And in there, put:

#!/bin/shupnpc -e "c-lightning" -a $(ip route get 1 | awk '{print $NF;exit}') 9735 9735 TCP

Make the script executable with:

chmod +x ~/bin/set_ports.sh

Once created, it needs to be added as a cron job:

crontab -e

If you don’t have preference, choose nano as the editor, and there, input:

@reboot       /home/pi/bin/set_ports.sh
*/10 * * * * /home/pi/bin/set_ports.sh

This will automatically setup port forwarding on your router every time your RBP boots, and then will make sure it’s still setup every 10 minutes.

Add Tor

While the Tor instructions aren’t exactly crystal clear yet, c-lightning supports almost all imaginable network combinations.

If you want your node running on clearnet (IPv4/IPv6) only, and being discoverable, you can skip this whole section.

Authentication

First, allow user lightning to control Tor with:

sudo usermod -a -G debian-tor lightning

You can verify it worked with:

id lightning
uid=1002(lightning) gid=1002(lightning) groups=1002(lightning),113(debian-tor)

Choose

At this point you need to choose the setup you want (and the options are plenty!). Some of them are:

  • you want your node to be Tor v3 address only;
  • you want your node to be discoverable only as Tor v2, but also able to communicate over clearnet;
  • you want you node to be available through all possible networks;

Note: Tor addresses v3 are more secure, and you can read up about them here.

Tor hidden services

The process of adding v2 and v3 is very similar, so both will be described here together.

First, open your torrc file:

sudo nano /etc/tor/torrc

And add this there:

HiddenServiceDir /var/lib/tor/ln-service-v3/
HiddenServiceVersion 3
HiddenServicePort 9737 127.0.0.1:9737

If you want to use v2 instead, replace the bold 3 with 2 in both places.

Protip: You can add this section twice, once with 2, and once with 3, to support both v2 and v3 addresses.

After adding all hidden services you want, restart Tor with:

sudo systemctl restart tor@default

Once the restart is done, you can get the .onion addresses of generated hidden services, with:

sudo cat /var/lib/tor/ln-service-v2/hostname
3fogovde3pptrkub.onion
sudo cat /var/lib/tor/ln-service-v3/hostname
6g3y7ahr5uxjzedgmu5etxtrc6hqmb2bl7kyipl3nzrcnyp64afrfwyd.onion

Note: Take note of those, as you’ll need them in the next step

Add hidden services to c-lightning config

First, change to lightning user, with:

sudo su - lightning

Open config with:

nano ~/.lightning/config

And append the following (replace .onion addresses below with your own):

announce-addr=3fogovde3pptrkub.onion
announce-addr=6g3y7ahr5uxjzedgmu5etxtrc6hqmb2bl7kyipl3nzrcnyp64afrfwyd.onion
proxy=127.0.0.1:9050
always-use-proxy=false
bind-addr=127.0.0.1:9737

Note: Some options (announce-addr orbind-addr) can and will appear multiple times in your config file.

Disable clearnet

Add this to your config file:

always-use-proxy=true

And remove announce-addr of the clearnet address and any address binding other than bing-addr=127.0.0.1:9737.

Done

Note: If you struggle with setup, here’s a few network configs, to give you an idea on how it’s supposed to look like.

Once the Torification is done, exit back to the pi user with:

exit

Create lightningd service

The last required thing to do here, is creating a service file for c-lightning:

sudo nano /etc/systemd/system/lightningd.service

And there, put:

[Unit]
Description=c-lightning Daemon
Requires=bitcoind.service
After=bitcoind.service

[Service]
ExecStart=/usr/local/bin/lightningd --pid-file=/home/lightning/.lightning/lightning.pid
PIDFile=/home/lightning/.lightning/lightning.pid
User=lightning
Type=forking
Restart=on-failure
# Hardening measures
####################
# Provide a private /tmp and /var/tmp.
PrivateTmp=true
# Mount /usr, /boot/ and /etc read-only for the process.
ProtectSystem=full
# Disallow the process and all of its children to gain
# new privileges through execve().
NoNewPrivileges=true
# Use a new /dev namespace only populated with API pseudo devices
# such as /dev/null, /dev/zero and /dev/random.
PrivateDevices=true
# Deny the creation of writable and executable memory mappings.
MemoryDenyWriteExecute=true
[Install]
WantedBy=multi-user.target

Once that’s saved, ensure that the service will start on system boot with:

sudo systemctl enable lightningd

Having the service created and setup, you can either start it manually with:

sudo systemctl start lightningd

or sudo reboot your Pi to make sure everything starts correctly upon reboot.

Verify it’s up and running

The easiest way to do it, is:

sudo su - lightning
lightning-cli getinfo | jq

If you have output with id and addresses, all should be good.

You can also see if there’s a movement in logs, with:

tail -n 100 -f ~/.lightning/debug.log

And here’s a few of handy commands that you can later use:

lightning-cli getinfo
listfunds
listconfigs
listpeers
listpayments

I don’t remember how it worked on mainnet, but on testnet the node is not connectected anywhere by default. Here’s how to change it:

For mainnet: either go here and pick a node, or connect to my Pi, with:

lightning-cli connect 032260c3b64b471b7eb0630b4af5d07ca94ff4e759573cbbe1bfb25845c375ed6e@o3s5j4j37nbyzgvbngn3ahpmttvviyensw34klhqzw7in7vfzz646lqd.onion:9735

For testnet: either go here and pick a node, or connect to my Pi, with:

03f156811eee5078add53d46ef9b00cf1ab9a1c43fc74d3db64312cb65815f3a99@6g3y7ahr5uxjzedgmu5etxtrc6hqmb2bl7kyipl3nzrcnyp64afrfwyd.onion:9735

Once you connect, the nodes will start to gossip about the state of the network, learning about other nodes, and the channels they have open.

Protip: Connect to multiple nodes.

Fund your node

Before you start sending and receiving Lightning Network transactions, you need to setup your channels. Being able to send payments is as easy as opening a few channels to some better connected nodes. Receiving payments is a little bit more tricky, because you need channels open towards you. Alternatively, if you open channels, and then keep spending from them, eventually you’ll also be able to accept payments through them.

Deposit coins

The very first step to opening a channel, is having funds in your LN wallet, and to do that you need a deposit address, here’s how you can get it:

lightning-cli newaddr bech32
bc1qtuky38xfqja4e8yymvgj0m07ykrqvr68lhhfec
tb1qvr5y9da90eq95k64udh8q9hh5m0yuemt0k8kej

Note: mainnet Bech32 addresses start with bc1 and testnet with tb1.

Protip: To get a legacy Bitcoin address for wallets that still haven’t updated, drop bech32 from the command above.

Once you have the address, send there some Bitcoin. Keep in mind that the technology is still in active development, so don’t deposit there more than you can swallow losing.

Protip: If you’re running a testnet node, you can get free testnet Bitcoins from faucets like this, this or this.

Open channels

Once funds gain at least one confirmation, you can start opening channels. The peers you choose to open channels with are completely up to you, but there’s a few good rules of thumb:

  • open channels with nodes you transact with frequently, ex. Bitrefill, Blockstream, TorGuard VPN, etc…;
  • open channels with nodes that seem well connected. Ideally not the biggest ones on the network, but ones that are closest to nodes you might transact with;
  • open channels to at least 2–3 nodes, and make sure they are all in different partitions of the network;
  • open channels with other RBPs :) (this is my node, leave your connect strings in comments below along with a mainnet/testnet note).

Once you’ve chosen your peers and decided on the amount, you can open channels to them using:

lightning-cli fundchannel 032260c3b64b471b7eb0630b4af5d07ca94ff4e759573cbbe1bfb25845c375ed6e 100000

Where that long 032260c… string is a node id, and 100000 is amount in satoshis.

Reminder: 1 satoshi equals 0.00000001 BTC.

Use your node

Lightning Network works a little different than on-chain Bitcoin transactions:

  • While Bitcoin node can be offline while receiving a payment, LN one needs to be online and communicating;
  • While you can pay anyone on-chain whether they like it or not, on LN you need to obtain an invoice for each payment first;
  • While on-chain transactions can take up to 128 hours 39 minutes and 20 seconds to confirm, LN transactions are instant.

Decode Invoice

So assuming you got an invoice that you want to pay, say:

lnbc900u1pdnyugcpp59xh3dkm545rjserwtayjyvy7d59f3m4lgep6fk0m5s4xhju7fm5qdzhw35xjueqd9ejqctwyp5kuan0d93k2grrwfjkzar9vssxvmmjypjx2mt0deehgunpvd6xjmmwypc82unsdaek2ucxq97rplqcqp25faxg3gr9sxgd6x4d2jvxus8nmurw98qdkenfpsckv50ttsafqn3gayvrszd55sgsgrxc9tmq9m2czuyk4yh5f50lrepv3hq0z87klsq4xsnda

it’s a good idea to first see if everything’s alright.

There are actually two things you can verify, before you even reach for any tools. To do that, let’s take a closer look at the part of the invoice I’ve made bold:

lnbc1m1

This part is called “Human-Readable Part” (HRP) for a reason, let’s split it into chunks:

  • ln — this one just indicates it’s a Lightning Network invoice;
  • bc — indicates what currency the invoice is for (bc stands for Bitcoin, ltc for Litecoin, etc…);
  • 900u — is an encoded amount. To get a one that’s easier to understand, you need to separate number 900 from a multiplier u. In this case u stands for μ/micro, ergo 0.000001, so 900 * 0.000001 = 0.0009 BTC. All multipliers are regular metric prefixes, so: m: 0.001, u: 0.000001, n: 0.000000001, and p: 0.000000000001.
  • 1 — the last 1 in the HRP is just a separator, between HRP and machine stuff.

Exercise: What can you say about this invoice:

lnltc130299u1pdnymugpp56qq62vn34qf70f2he0d0smwycl92nnarwpuz94s29yk9wxh6lhaqdphgf5hgun9ve5kcmpqx43rxv3kvcurwctyxs6kgvesxqcrgdnxx9nxgeqcqzjqxqrpcg42vfd9eu5jysmzp758s4pxhqkln6hr0xevj2pcgnxuj9e0fza5ej9u5tjhm0vuny408y97qqy0gdvxnu69yz9zhdvrrstt56pfrljkspgd5wks

If you want to dive deeper you can use a decodepay command:

lightning-cli decodepay lnbc900u1pdnyugcpp59xh3dkm545rjserwtayjyvy7d59f3m4lgep6fk0m5s4xhju7fm5qdzhw35xjueqd9ejqctwyp5kuan0d93k2grrwfjkzar9vssxvmmjypjx2mt0deehgunpvd6xjmmwypc82unsdaek2ucxq97rplqcqp25faxg3gr9sxgd6x4d2jvxus8nmurw98qdkenfpsckv50ttsafqn3gayvrszd55sgsgrxc9tmq9m2czuyk4yh5f50lrepv3hq0z87klsq4xsnda | jq
{
"currency": "bc",
"timestamp": 1530032408,
"created_at": 1530032408,
"expiry": 31557600,
"payee": "032260c3b64b471b7eb0630b4af5d07ca94ff4e759573cbbe1bfb25845c375ed6e",
"msatoshi": 90000000,
"description": "this is an invoice created for demonstraction purposes",
"min_final_cltv_expiry": 10,
"payment_hash": "29af16db74ad0728646e5f4922309e6d0a98eebf4643a4d9fba42a6bcb9e4ee8",
"signature": "3045022100a27a6445032c0c86e8d56aa4c372079ef83714e06db3348618b328f5ae1d4827022014748c1c04da520882066c157b0176ac0b84b5497a268ff8f21646e0788feb7e"
}

Send transactions

Once you’ve confirmed that the invoice is issued for the right amount and contains everything that’s necessary, it’s time to pay it:

lightning-cli pay lnbc900u1pdnyugcpp59xh3dkm545rjserwtayjyvy7d59f3m4lgep6fk0m5s4xhju7fm5qdzhw35xjueqd9ejqctwyp5kuan0d93k2grrwfjkzar9vssxvmmjypjx2mt0deehgunpvd6xjmmwypc82unsdaek2ucxq97rplqcqp25faxg3gr9sxgd6x4d2jvxus8nmurw98qdkenfpsckv50ttsafqn3gayvrszd55sgsgrxc9tmq9m2czuyk4yh5f50lrepv3hq0z87klsq4xsnda

Receive payments

To receive payment, you need to generate an invoice and deliver it to the person paying you. To do it, just:

lcli invoice 1000 "test-invoice" "For generating a test invoice" | jq
{
"payment_hash": "ce44137a5589f811eeb0ca0d0ae194f50aa2d83dba91707fcb1bede49f53f45a",
"expiry_time": 1530037058,
"expires_at": 1530037058,
"bolt11": "lnbc10n1pdnyafjpp5eezpx7j438uprm4segxs4cv575929kpah2ghql7tr0k7f86n73dqdp0gehhygr8v4hx2unpw35kueeqvys8getnwssxjmnkda5kxegcqp2u7mmum0enmlx24chsumdzgvfq565jve5mtf6lfsj2nagsup67uyqh0pch7ukadpxlymdt0ls6r4dh89syj8tsfvpahj8wcj026mejhgqy492cq"
}

What you need to deliver to the other person, is the content of the bolt11 field:

lnbc10n1pdnyafjpp5eezpx7j438uprm4segxs4cv575929kpah2ghql7tr0k7f86n73dqdp0gehhygr8v4hx2unpw35kueeqvys8getnwssxjmnkda5kxegcqp2u7mmum0enmlx24chsumdzgvfq565jve5mtf6lfsj2nagsup67uyqh0pch7ukadpxlymdt0ls6r4dh89syj8tsfvpahj8wcj026mejhgqy492cq

All the rest

With all these basics covered, I’m sure you can master operating your LN node in a no time ;).

Other thingies

Make ssh welcome message pretty

The dashboard we’ve added in the Bitcoin guide, has served us well, but it’s time for a new, refreshed and pumped one now.

TL;DR:

wget -qO- https://gist.githubusercontent.com/meeDamian/0006c766340e0afd16936b13a0c7dbd8/raw/c9ebf744372325e8b5c42f271fb046a6eebcaf14/na%25C3%25AFve-rbp-btc.sh | sudo sh

Manual

Save all the files starting with numbers from here, to:

/etc/etc/update-motd.d/

And make them all executable, with:

cd /etc/etc/update-motd.d/
chmod +x 10-uname 20-raspberry-bitcoin 26-raspberry-lightning 30-swap-warning

You can summon the view above at any time with:

run-parts --lsbsysinit /etc/update-motd.d

Note: If you configured SWAP on an external device as instructed above, you might want to also run sudo chmod -x /etc/update-motd.d/30-swap-warning to disable SWAP warning on ssh login.

Update c-lightning Node

Check exactly what version you’re updating to, on the Releases page. Assuming it will be v0.6.1 (not released as of writing this):

sudo systemctl stop lightningdcd lightning
git fetch origin master
git checkout v0.6.1
./autogen.sh
make
sudo make install
sudo systemctl start lightningd

Where to get help or knowledge?

I find Twitter and Github to be the best sources of information. On Twitter you might want to follow Rusty Russell and Christian Decker, @rusty_twit and @Snyke respectively. On Github the issues section and doc/ folder are a good start. Another place with responsive people and good information is: Lightning Community Slack.

Mistakes? Improvements? Tips?

If you’ve found anything incorrect in this guide, or have an idea on how to improve it, feel free to either leave a comment, btc AT meedamian DOT com or @meeDamian me.

If you liked the guide, it helped you or you just want to contribute to my ticket to 🚀 Mars, you can do it either through my PayNym: +quietmath379, or more traditionally: bc1qm2rhkaj9s45p8dfkcjulqrusex6avyvhrfm9l4. Link to LN invoices self-generator coming soon.

Edits

2018–06–27

Added more detailed LN balances to dashboard, together with max payment possible given currently open channels.

Other Guides…

This is a third guide in a series of planned:

  1. Litecoin Full Node on RBP3,
  2. (obsolete) Bitcoin Full Node (with or w/o BIP148 UASF 🙊) on RBP3,
  3. Bitcoin Full Node on RBP3 (revised),
  4. Bitcoin through Tor on RBP3,
  5. Lightning Network (c-lightning) on RBP3,
  6. Lightning Network (lnd) on RBP3.

--

--

Damian Mee

Bitcoin. Lightning. Golang. Applied cryptography, not Blockchain. https://keybase.io/meedamian . PGP: D8CA 1776 EB92 6549 1D07 CE67 F546 ECBE A809 CB18