Ereignishorizont
LNbits Server

LNbits Server

LNbits – The platform for the third level

If you’ve been paying a bit more attention to Bitcoin and especially Lightning, you’ve probably come across LNbits. While Bitcoin can be described as the hardest foundation for digital money, the Lightning ⚡ Network is the scaling transport layer on top of Bitcoin. On the Lightning layer, Bitcoin sats (satoshis) can be used for payment quickly and more efficiently than in the first layer (Bitcoin onchain). The advancement on the second layer is decoupled from the maximum security on the base layer and therefore we have more freedom there. We bind first layer Bitcoin, through Lightning Channels (payment channels between two nodes), to the second layer, the Lightning ⚡ Network (offchain). By doing this, we have elevated the value of bitcoin to the second level, but we are freer and more flexible to evolve because we are no longer directly using or interfering with the first level. Only when we dissolve the payment channel between the nodes again, the value is split and written as two separate unspent transaction outputs (UTXO) in the blockchain (onchain).

LNbits is built on Lightning technology and uses the Lightning ⚡ Network. You can think of LNbits as a platform for another layer, the application or application layer. LNbits itself is a wallet and account system with a funding source in the background, such as a Lightning ⚡ Node. But what makes LNbits really special, it is also a platform for small applications called extensions. These are small programs that link to LNbits accounts and also, through interfaces, interact with other systems to perform certain functions with them.

While Bitcoin in the blockchain can be called gold to store values like working time in it, Bitcoin in the second level can be understood as a digital cash. And LNbits is then the platform for the marketplace where you can use the digital cash. With LNbits, one creates dedicated accounts that can have a direct connection to stores, vending machines, exchange platforms, service functions, vouchers, etc.

Content

  Bitcoin – The foundation of a new value and financial system

    Lightning ⚡ Network – The scaling layer / The infrastructure on which Bitcoin scales

      LNbits – The Lightning ⚡ Account System with extensions / The application layer

      • bitcoinSwitch – An electronic switch activated by Lightning ⚡ Payments
      • Hardware Wallet – Interface to an ESP32 hardware wallet
      • Split Payments – Split ⚡ Payments across multiple wallets
      • Bolt Cards – NFC technology / pay and receive with a chip card
      • LNPoS – A Bitcoin & Lightning ⚡ Point of Sale Terminal (online/offline)
      • Cashu – A Mint for Chaumian ecash / Privacy & anonymous Lightning payments
      • OfflineShop – Receive ⚡ payments for products offline and without additional hardware
      • Marketplace – Webshop / marketplace that can leverage Nostr’s resilient infrastructure
      • SatsPay Server – Integrate Bitcoin on/offchain ⚡ payment on your website
      • and much more

You can also see LNbits as a Swiss army knife or a multitool with the option of plugins for Lightning ⚡ applications. It can have countless tools and thus function possibilities. All packed in small apps/plugins like electronic counter, online/offline checkout terminal, paywalls, split payments, event tickets, marketplace, NFC card wallets and vouchers, ecash mint, etc. We can now use the full potential of Bitcoin ⚡ Lightning and take it to the next level to enable completely new applications.


LNbits Applications

"Be your own bank" was yesterday, now it’s "Be a bank AND marketplace for your family & friends" . Because LNbits is a technology hub for Lightning ⚡ applications. Those that are not possible with the existing fiat money system and certainly not without trust and intermediaries. And that’s exactly what’s changing with LNbits, because we now have the ability to sovereignly control technical financial services for the first time.

Who would have thought what would one day emerge from the Internet and what everything would be based on it? We now have the opportunity to really exploit the power of Bitcoin ⚡ Lightning and thus raise the potential for our future. Because payments will become cheaper, faster, we can control it ourselves and incorporate it into our digital world quite easily. The development will proceed quickly and ultimately exponentially. If you don’t just want to watch but also participate, I will show you in this tutorial how to do this with LNbits.

1. About this tutorial

Nice that you are interested and want to take a deeper look at LNbits. I won’t show you here how LNbits works or what you can do with the extension, because there are already many good tutorials for that. Just have a look at the LNbits Wiki page. You will definitely find something there.

In this tutorial I will only show what LNbits is, how you can use it and then move on to what options you have to run LNbits yourself. Because there are quite a few options. From full custody service (the funds and LNbits are under someone else’s custody), to half custody, so that at least LNbits is under your own responsibility, to self-sovereign hosting and running LNbits and the funding source you need.

The tutorial is for all interested people and those who want to run LNbits themselves. It is very technical and the implementation takes time and care, but you will be taken by the hand and every step is explained in detail. From my own experience I know how difficult it is when parts of the documentation are missing and you don’t know where to go from there, so I paid close attention and explained every step.

2. What is LNbits and where do I start?

LNbits is a Free and Open Source Ssoftware (FOSS). LNbits is therefore freer and can grow more flexible and faster than proprietary systems. The more efficient solution will always prevail. And because LNbits is a FOSS, you have the possibility to build and run your own version of a LNbits server. LNbits itself is "just" a small (Python) program with a database that performs the function of an account system for Lightning ⚡ wallets. For this purpose, LNbits always needs a funding source, i.e. a wallet. The special feature of LNbits is the large number of extensions, which often also use the Lightning protocol LNURL. This enables applications that would not be possible with the pure standardized Lightning Netzwork Technology (Basis Of Lightning Technology (BOLT)) and enables the linking of different applications with Lightning payments.

The first and easiest way to use LNbits is a custody service, like the free demo server legend.lnbits.com. This is a good way to get your first experience with LNbits. Try it out, play around with it. The server is always up to date. You can get help with questions in English in the LNbits Telegram group. Please keep in mind that the Legend server is a custody service and is used experimentally by the developers from time to time, as updates are tested here. So it is not recommended to consider the server as a "productive" instance, because it is a demonstration server with full functionality, but where there is no guarantee of function or funds. If you are looking for something more "reliable", you can either use a friend’s system, or host your own LNbits server with funding source right away. Only then you are really sovereign and have full control over LNbits and the funding source. But it doesn’t have to be black or white, sometimes there is a spectrum.

3. The options to operate LNbits

You have just learned about full custody, but there are several other ways to set up LNbits. We always needed a wallet and a platform on which LNbits runs. This could be your Lightning ⚡ node on a Raspberry PI, a separate PC or a server in the cloud.

Most nodes like Raspiblitz and Umbrel support LNbits and they have the funding source already on board. For testing and for pure use in the home network, this is also perfectly sufficient. But if you want to use your LNbits or functions of LNbits from outside the local network, i.e. inside the internet, then it gets more difficult. Most people won’t get a fixed IP from their internet service provider or will be afraid of the costs. But you would be doxing your location, which is not recommended, considering that this is a private bank.

There are solutions for this, such as using a dynamic DNS service, but even for this you have to enable incoming traffic on your router again and the DNS service should also always be updated promptly. Using the Tor-only connection, accessing the LNbits site works, but Tor has a very high latency, is unreliable and you always need a Tor-enabled browser and most of the users’ (clients’) wallets will not be able to handle it.

An elegant solution seems to be using services like Cloudflare as a tunnel supporter. It’s manageable to set up and even free. But then you make yourself dependent on third parties again and Cloudflare can see or even change all your traffic, as it acts as an intermediary between the client’s browser and your local server.

A basically good solution is to set up a reverse proxy. There you put a server between your node and the internet, to which the node connects to the reverse proxy server via Clearnet (normal internet) or Tor (commonly known as Darknet). Requests to the node are forwarded to the node via the proxy server. At least the Clearnet variant is not that bad, but it is also technically demanding. In this case, all communication between the node and the proxy server continues via Tor.

Then there are combinations where the node or wallet and the LNbits application are separated from each other. Personally, I find this the most attractive solution, as it allows me to run my LNbits independently of the funding source and even easily switch between different instances in case of an error. This makes the whole thing a bit more decentralized and resilient. It’s not necessarily the easiest or cheapest solution, but one that offers the most control, security, flexibility and scalability possible. Running my own Virtual Private Server (VPS) running LNbits and being able to choose which wallet or node I connect my LNbits to is quite fascinating.

I’m sure that not all possibilities and options have been considered here, but only the most common and known to me so far.

4. The choice of the LNbits server

After a long search I found the GitHub page of TrezorHannes. He created a big tutorial (vps-lnbits) out of several single puzzle pieces (tutorials). The core of the tutorial is a Virutal Private Server (VPS) running an LNbits instance. A Lightning ⚡ node is used as the funding source, more specifically an LND node. The VPS establishes a Virtual Private Network (VPN) with the Node and sends all traffic from the Node over the VPN tunnel to the VPS and on to the Internet and back again. The Node has thus been given a hybrid mode. It is thus accessible via both Tor and Clearnet. 🤩

The VPS has its own public IP address and so does the Node, which is tunneled through the VPS. This optimizes the connectivity of the node, because over the Internet the connection is more stable and faster than only over Tor. The location is still protected because only the IP address of the VPS can be seen from the Internet.

The connection between the Node and the VPS is called a Virtual Private Network (VPN) because the communication is encrypted. The connection is also called a VPN tunnel. The LNbits instance in this scenario can communicate with the Node via the same tunnel. And there you go, we have a secure, flexible and scalable system that we fully control ourselves.

The cloud service provider is just one provider of many that can be changed quickly. The separation of node and LNbits allows the funding source to be quickly swapped out if the node ever fails or the underlying funding source needs to be changed. LNbits allows the use of e.g. LightningTipBot or a Custody LNbits Wallet. One only has to adjust the interface data of the funding source in the configuration file of LNbits. This increases the availability tremendously.

It’s also more scalable because you can simply add CPU, RAM, disk or bandwidth to your VPS at the cloud service provider. It’s fail-safe because the servers our VPS runs on are professionally managed and you can easily take snapshots / backups of the VPS. For me, all these reasons spoke in favor of choosing this option. And with $6 / month, I think it also has an acceptable price.

Another hint: If you don’t have your own node, or if the whole thing is too much technology for you, you can also try a slimmed down version. You could just set up the virtual private server with LNbits and then link it to a custody wallet like LightningTipBot. Then you also have your own LNbits website, only the funding source is in custody. This makes the whole installation much easier. You only need the chapters 7.1 to 7.2. and 7.9 to 7.12. The really complicated part is excluded.

5. A few general information

The template from TrezorHannes is really very good, but the whole thing is also very demanding, because you partly have to understand the background. Many disciplines come together here. You read in both of our tutorials about Ubuntu, VPS, VPN tunnel, firewall, port forwarding, API, Macaroon, domain hosting, web server, database and so on. This can make you sweat quite a bit and holds many stumbling blocks where you quickly seem powerless. But with a little curiosity, will and the right clues, anyone can actually manage it.

If you follow the instructions step by step and take care that you copy the commands correctly and adjust them if necessary, you will reach your goal. To keep the scope as small as possible, I will only give a basic hint of the technique behind the function. If you want to understand more why and how, I recommend you to have a look at the references in the appendix. This tutorial can be seen as a kind of script that you only have to work through.

6. General disclaimer

There is always a risk as soon as you install additional software on your node or make adjustments. The function of the node can be disturbed or even worse, you build doors and gates in your protective wall, which can be exploited by attackers.

LNbits needs the admin macaroon of the node or wallet, which is the access key to your funds, to send and receive payments. For example, the VPS could be hacked and someone gets access to the Macaroon. Also, your Node is a hot wallet or a soft wallet. The more you expose the Node, the higher the risk. In this tutorial some security features are included, the risk is minimized as much as possible, but it is not zero. So think carefully if you want to expose your node to this risk. Consider what options you have to harden the system and further minimize the risk or limit the potential damage.

Also, I wrote this guide to the best of my knowledge. I have tested it several times and it worked for me. But I can’t guarantee that I didn’t miss any bugs or that something unexpected won’t happen on your systems. Please forgive me, that I can’t take any guarantee or warranty for this.

Another note about the license & copyright. Everything is published under the MIT license. If you want, you can copy, change and distribute parts or the whole article, even under your own name. But I do not assume any liability or warranty. And of course I would be happy if you refer to this tutorial.

7. The construction of a LNbits server

The tutorial is based on a Raspiblitz v1.8.x with LND Node v0.15.5. With an Umbrel v0.5.x this is also possible, in the appendix you will find a "Path and Commands Reference Table". With a Citadel and a Core Lightning Node this should work as well, if you adapt it accordingly.

Tips and hints for using the tutorial:

  • If you’re not 100% familiar with Linux, I recommend "The Linux command line for beginners". Watch the tutorial once. A really well-written tutorial to brush up on the basics.
  • Usually a command is preceded by a $ character. So that the commands can be copied better, I have mostly dispensed with it here. However, I have sometimes included comments in the command line. These are then marked with the hash #. Everything behind it is only information and no part of the command.
  • The IP address of your VPS is shown in this document with 111.111.111.111. Exchange it with your own.
  • I recommend everyone to get used to a multi-window system, because you have to switch between windows a lot to look up or copy something. It is best to use two monitors and/or split the window. In Windows this is made possible by pressing the Windows key and using the arrow keys at the same time.
  • Good practice with Virtual Private Servers (VPS) is to use SSH key authentication with passphrases. Simple logins with a password can in principle be cracked by brute force. The handling of SSH keys is not always easy, that’s why I use login by password for this tutorial. If you are not experienced in using SSH keys, you should use a long and wild password with many special characters for this tutorial. You should not be able to remember the password and you always have to paste it by copy & paste or password manager. But if you want to learn the good practice, I can recommend this article. Otherwise, I have also added a chapter in the appendix under 9.9.10 Securing the server with SSH keys, in which I describe how to set this up later.
  • I can also recommend to create a digital notebook for this tutorial, where you can store your remarks, shortcuts and especially passwords. You need the login, the IP and especially the passwords several times in the course. Please don’t use a classic service provider like Google or Apple for your digital notebook, but another provider that is open source, encrypts your data with strong cryptography end-to-end and is therefore secure. Like standardnotes.com. The free version is also perfectly adequate. As an example here is a digital note, how it could look like. From it you can then work quite comfortably with copy & paste.

      VPS IP address: 111.111.111.111 (You get the IP from your VPS service)
      ssh root@111.111.111.111 (Root Login)
      root Passwort: s/(lkk933#Ä>sS33in@fs&7pAY (Root password with many wild characters)
      ssh synonym@111.111.111.111 (Standard user login)
      synonym Passwort: 3#Ä=$s93@fsKws/(lkPOp693i (That means used password))
      New CA Key Passphrase (ca.key): $sSA9s/(lkK93@fs (This is what you need in Docker)
      Common Name: myvps (you can choose freely)
      Docker ID: 9995469d1054 (You will get the ID later)

And now I wish you a lot of fun and above all success!

7.1 – General – Setting up a Virtual Private Server (VPS)

The first thing you need is a virtual private server (VPS). It doesn’t have to be a very powerful one. However, at least 1 GB of RAM and the Linux distribution Ubuntu (LTS) v22.04 as operating system. It costs about $6 a month and everything else you could upgrade later if you need to. You may also already have a managed server or cloud hosting provider. It should only offer Ubuntu v22.04 for full compatibility with this guide.

If you don’t have a preference yet, feel free to check out digitalocean.com (affiliate link). I’m quite happy with it. Fair price, technically sound and they have very good tutorials. Currently they also have an offer that gives us both a little bonus. You get $200 credit for the first 60 days and you can try everything. And if you stay on the ball and your payments eventually accumulate to $25, then I get a one-time $25 credit for my account. Of course you can also use any other alternative.

DigitalOcean Referral Badge

The setup and installation is best described with a few pictures that I hope are self-explanatory. At the first moment the interface is a bit hard to get used to. First you have to create a new project and then click on Spin up Droplet at Welcome to DigitalOcean! to set up a Droplet, a Virtual Private Server (VPS). Everything else is shown in the pictures. Choose the region closest to you, Ubuntu as operating system, Shared CPU Basic, the regular CPU and for the authentication method you have the choice. If you are familiar with SSH keys, choose this. It is the safest, but not necessarily the easiest method. If you are not sure, it is better to choose a very strong password. Activate the free monitoring, because it gives you a good overview about the state and the used resources of the VPS. Then assign a hostname of your choice and select Create Droplet. That was it. Now you have your own Virtual Private Server.

The last image shows how you can take a snapshot of your VPS, i.e. a backup of the current state. To do this, shut down your VPS first, so that you get a clean backup of a resting system.

7.2 – VPS – Basic settings of the Virtual Private Server

Here we go! First, you log in and make a few basic adjustments. Since in this tutorial you often have to jump from the VPS and then back to the Node, I have always noted in the heading first, where the adjustments must be made. VPS, Node or General.

Log in on the VPS with your "root" user.

ssh root@111.111.111.111

Perform update and upgrade

apt update && apt upgrade -y

-> If you are ever asked during the update, press ENTER

Install and set up UncomplicatedFirewall (UFW)

apt install ufw
ufw default deny incoming
ufw default allow outgoing
ufw allow 22 comment 'OpenSSH'
ufw allow 80 comment 'Standard Webserver'
ufw allow 443 comment 'SSL Webserver'
ufw allow 9735 comment 'Node1' 
ufw enable   # -> y
ufw status   # -> Check whether OpenSSH or 22/tcp is included!

SWAP (Will help your system in case it would be running low on memory)

fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
swapon -s

Make sure SWAP will persist through reboot

sudo nano /etc/fstab
  • -> And add following line to the end of the configuration
# For persist SWAP through reboot
/swapfile swap swap defaults 0 0
  • -> save and close with CTRL+x -> y -> ENTER

Check with HTOP if 2GB SWAP is active

htop
  • -> See under CPU/Mem/Swp the 2GB
  • -> Exit with F10
  • -> If HTOP was not yet installed: $ sudo apt install htop

Fail2ban (Protects against brute force attacks)

apt install fail2ban -y # press ENTER 2x
systemctl enable fail2ban
systemctl start fail2ban
systemctl status fail2ban

For your information, the default settings are:

bantime = 10m ("bantime" is the number of minutes that a host is banned.)
findtime = 10m (A host is banned if it has generated "maxretry" during the last "findtime")
maxretry = 5 ("maxretry" is the number of failures before a host get banned.)

Create the new user synonym and assign root privileges

adduser synonym # -> assign a very good password, 5x ENTER, y
usermod -aG sudo synonym

Note: You can of course customize the user. But it is used very often in this tutorial and also in paths. Customizing is thus a lot of work and may lead to errors, so watch out.

Recommendation: Take a snapshot of the VPS now

systemctl poweroff
  • Create snapshot in DigitalOceans under: Projects/my-project/droplet/Snapshots.
  • When the snapshot is created, press the Turn on Button of the VPS.
  • This will give you a very good basis for a new start later on.

From now on log in only with your new user!

ssh synonym@111.111.111.111

From now on we will often prescribe the command sudo to give our user administrator rights. You will often be asked for the user password.

7.3 – VPS – Install and set up Docker

Install Docker

sudo apt-get install docker.io tmux -y
sudo systemctl status docker.service

-> Quit -> q

Assign a global name for the data volume container.

export OVPN_DATA="ovpn-data" 

-> Assigns the content ovpn-data to the global variable `OVPN_DATA

To make the name available even after a reboot.

nano .bashrc
  • Append export OVPN_DATA="ovpn-data" to the end.
  • CTRL+x -> y -> Enter to save and close the editor

Create Docker Container

sudo docker volume create --name $OVPN_DATA 

Initialize the container

Attention: Customize IP

sudo docker run -v $OVPN_DATA:/etc/openvpn --rm kylemanna/openvpn ovpn_genconfig -u udp://111.111.111.111
sudo docker run -v $OVPN_DATA:/etc/openvpn --rm -it kylemanna/openvpn ovpn_initpki 

The container prompts for a CA Key Passphrase to protect the private key used by the newly generated certificate authority. Additionally, a common name (e.g. "myvps") must be assigned and then confirmed twice with the CA Key Passphrase.

Note: The container contains the configuration files and certificates. The certificates have a validity of 825 days.

Starting the OpenVPN server process

sudo docker run -v $OVPN_DATA:/etc/openvpn -d -p 1194:1194/udp -p 9735:9735 -p 8080:8080 --cap-add=NET_ADMIN --restart unless-stopped kylemanna/openvpn

Note: Port 1194 ist the Port for the Tunnel. The port 8080 is for the LNbits REST API of node 1. If you want to tunnel two nodes with one VPS, you could extend the line above with port 9736 (LND) and port 8081 (REST) for a second node. A more detailed description in the appendix under Miscellaneous, chapter "Multiple Nodes on a Virtual Private Server".

Generating a client certificate without passphrase for node1

sudo docker run -v $OVPN_DATA:/etc/openvpn --rm -it kylemanna/openvpn easyrsa build-client-full node1 nopass

-> Confirm once with the CA Key Passphrase.

Retrieve client configuration with embedded certificates for node1.

sudo docker run -v $OVPN_DATA:/etc/openvpn --rm kylemanna/openvpn ovpn_getclient node1 > node1.ovpn  

Assign a fixed IP to the VPN tunnel

sudo su
nano /var/lib/docker/volumes/ovpn-data/_data/ccd/node1
  • with the following content: ifconfig-push 192.168.255.6 192.168.255.5
  • CTRL-x -> y -> ENTER
  • Now restart the server $ sudo reboot and log in again
  • Now the node has always the 192.168.255.6 and the server has this tunnel the .5

Note: After you have installed and set up OpenVPN on the node, you can use the command $ ip add show tun0 to check whether you have been assigned the correct IP.

Show the path to the node1.ovpn file and remember it

ls # -> Should now show the node1.ovpn file
pwd # -> Show the current path

Display the container ID and remember it

sudo docker ps # -> shows the status, the container ID and the ports

Call the Docker shell once

Caution: Adjust the Docker ID beforehand

sudo docker exec -it b7a78bb8b394 sh

Display the network adapters of Docker.

ifconfig

Under eth0 you should see IP = 172.17.0.2, this is the IP of the Docker port.

Exit Docker Shell

exit

Check Docker settings once

sudo systemctl status docker.service # -> q

7.4 – Node – Set up OpenVPN

Log in to the node

ssh admin@192.168.x.x

-> On the Raspiblitz click on Exit in the menu to get to the command line interface

Create a VPNcert folder

pwd # -> Show the current path
mkdir VPNcert # -> Create a VPNcert directory

Download the OpenVPN certificate from the VPS

Caution: Adjust IP and paths if necessary

scp synonym@111.111.111.111:/home/synonym/node1.ovpn /home/admin/VPNcert/

You have to confirm the new "fingerprint" once and then enter your user password

Restrict read and write permissions to the current user

sudo chmod 600 /home/admin/VPNcert/node1.ovpn

Install and set up OpenVPN

Attention: Also here adjust the path and file name if necessary

sudo apt-get install openvpn -y
sudo cp -p /home/admin/VPNcert/node1.ovpn /etc/openvpn/CERT.conf
sudo systemctl enable openvpn@CERT
sudo systemctl start openvpn@CERT
sudo systemctl status openvpn@CERT 

Pay attention to the following lines:

..
net_iface_up: set tun0 up
net_addr_ptp_v4_add: 192.168.255.6 peer 192.168.255.5 dev tun0
..
  • Exit with q
  • The IP = 192.168.255.6 is the client IP provided by the tunnel for the first node. If you add another node, this can be e.g. the IP 192.168.255.10. More about this in the appendix under Miscellaneous, chapter "Multiple Nodes on a Virtual Private Server".

Note: With the command $ ip add show tun0 you can also display the IP afterwards.

Connection test

ip route get 8.8.8.8

-> You should see 8.8.8.8 via 192.168.255.5 dev tun0 src 192.168.255.6

Check if you can ping Google through the tunnel

ping -c 3 google.com

Query the log files, to display the last messages

sudo journalctl -u openvpn@CERT -f --since "1 hour ago" 

-> CTRL+c

7.5 – VPS – Set package rules for Docker

Call Docker Shell

sudo docker ps # -> show the ID again
sudo docker exec -it 8c5c4bf6c634 sh # -> start shell

Info: An alternative command is $ sudo docker container ls. With the slightly extended command $ sudo docker ps -a, you can also view unstarted containers and their status.

In Docker, set the package rules for the firewall.

Caution: Remember to check the IP (see previous chapter) and the ports.

iptables -A PREROUTING -t nat -i eth0 -p tcp -m tcp --dport 9735 -j DNAT --to 192.168.255.6:9735
iptables -A PREROUTING -t nat -i eth0 -p tcp -m tcp --dport 8080 -j DNAT --to 192.168.255.6:8080
iptables -t nat -A POSTROUTING -d 192.168.255.0/24 -o tun0 -j MASQUERADE

Note: If you want to run more than one node over the same VPS, you first have to assign a fixed IP for each node and extend iptables with the lines. An example excerpt for e.g. three nodes can be found in the appendix under Miscellaneous.

Save the rule permanently

To make sure that the package rules are loaded after the next reboot, we stay in the Docker Shell and still have to edit the script file ovpn_env.sh.

cd /etc/openvpn
vi ovpn_env.sh # -> editor opens

Now the vi editor has been opened. The commands and handling is a bit unusual, but if you follow the steps exactly, you should reach your goal. You can find a command overview here.

For practice, leave the editor right away:

  • ESC -> :q! -> ENTER -> Exit without save
  • You really have to enter the :q! like this

Now open the editor again:

  • vi ovpn_env.sh
  • set the cursor to the last line -> G (=> capital "G" -> Shift+g)
  • go into edit mode -> a (small "a")
  • wrap one line -> ENTER
  • now copy the three "iptabels" line from above into it
  • ESC -> leave edit mode
  • :wq -> save changes and close the window

When you are done, exit the Docker Shell again as well:

exit

7.6 – Node – Modify the lnd.conf file

Caution: The file lnd.conf is the heart of your Lightning Node. If you make mistakes there, you can cripple your node. So be careful what you do and make a backup before. Better leave the editor with STRG-x -> n -> ENTER than saving something wrong.

Create a backup of the LND.conf

cd /mnt/hdd/lnd/
sudo cp lnd.conf lnd.conf.backup
ls -l # -> check backup date

LND.conf edit

sudo nano lnd.conf
# direct: sudo nano /mnt/hdd/lnd/lnd.conf

Check the following lines and adjust if necessary:

[Application Options]
..
nat=false # -> check and set to false
listen=0.0.0.0:9735 # -> check it
restlisten=0.0.0.0:8080 # -> check it
externalip=111.111.111.111:9735
tlsextraip=172.17.0.2
..
[tor]
..
tor.streamisolation=false
tor.skip-proxy-for-clearnet-targets=true
  • Be careful that you don’t have a double assignment with contradictory values
  • Funfact: In the appendix I show you how you could "tune" the alias name here 😉
  • CTRL+x -> y -> ENTER

Note: If you want to understand the settings a bit more detailed, have a look here.

Special: ONLY for the Raspiblitz

The lnd_check.sh script checks the lnd.conf and can overwrite your settings when starting the LND. Therefore you have to comment out a few lines here, so that this does not happen.

Call in the script the lines from 184:

sudo nano +184 /home/admin/config.scripts/lnd.check.sh

Comments out the following line with #:

# # enforce PublicIP if (if not running Tor)
# if [ "${runBehindTor}" != "on" ]; then
# setting ${lndConfFile} ${insertLine} "externalip" "${publicIP}:${lndPort}"
# else
# # when running Tor a public ip can make startup problems - so remove
# sed -i '/^externalip=*/d' ${lndConfFile}
# fi

-> save and close with CTRL+x -> y -> ENTER

Note 1: A bit further up it also says # enforce LND port is set correctly. If you use a port other than 9735 for LND, these lines must also be disabled or adjusted. The same applies to the REST API port 8080, you can find it one more line above at # make sure API ports are set to standard.

Note 2: You can update Bitcoin Core, LND and other applications manually, but a complete update of your node, to a new version, will probably be overwritten exactly this file and your node will only run over Tor gate! And if you have more than one node running over the VPS, or if you have assigned induvidual ports in general, the LND.conf will be overwritten automatically for the nodes which have another LND port than 9735 or REST port than 8080. The node still works, but only via TOR and the LNbits logs show Retrying connection to backend in 5 seconds... | The backend for LndRestWallet isn't working properly. So keep this in mind, this is a sneaky error. If the port is free, you could test e.g. herewith.

Restart the LND once

sudo systemctl restart lnd.service 

-> This may take some time, be patient

Check if the certificate and the key has changed

ls -l 

-> Check date and time (GTM) of tls.cert and tls.key. The files must have updated if you made a change to tlsextraip or tlsextradomain.

Connection test

Test if you can reach the Google server:

ip route get 8.8.8.8

-> You should get back 8.8.8.8 via 192.168.255.5 dev tun0 src 192.168.255.6.

Now ping the VPS Docker again:

ping 172.17.0.1

-> abort with CTRL-c

If everything looks good, then your node is reachable in Clearnet from now on! 🎉

7.7 – General – Checking the connection

Here I will show you different ways to check if your node is really reachable from the clearnet.

With the Raspiblitz it is very easy, look in the status screen

At the bottom behind the Node ID you should see the IP address of the VPS instead of the ".onion". Don’t worry, the onion connection will still work.

LND Show information

lncli getinfo
  • Under uris: you can now see both connection options of your node
  • Once the Tor Onion and now the new Clearnet IP address

Check with external services

Through the Gossip Protocol of the Lightning network your new connection data will be shared. The propagation of the new connection may take a few hours, depending on how well connected your node is. So be patient! Use the following services and search for your node alias name or node ID.

https://1ml.com/

https://amboss.space/

https://lightningnetwork.plus/

https://lnrouter.app/

There you should enter as server location e.g. Frankfurt am Main and/or the IP address of your Virtual Private Server.

Info: Another possibility to test the connection is to use the "Telegram Ping Bot". Please have a look at the appendix under miscellaneous.

7.8 – Node – Provide LND certificate and Macaroon for LNbits

Transfer the LND certificate to the VPS.

Caution: Check the path, the IP and the username

scp /mnt/hdd/lnd/tls.cert synonym@111.111.111.111:/home/synonym

-> Confirm the transfer with the password of the VPS

Next read out the admin macaroon of the LND.

Attention: This is your Admin API Key for the LND Wallet, please keep it very confidential!

xxd -ps -u -C ~/.lnd/data/chain/bitcoin/mainnet/admin.macaroon

You should now see a long code that you copy afterwards into the setup file ".env" on your VPS in the LNbits folder.

Attention: the macaroon is the key to your LND and therefore to your funds. Take good care of it.

Tip1: Copy the HexString into a temporary Notepad window and take out the line breaks carefully. If you don’t do this, the Macaroon may be misinterpreted by LNbits and you won’t get a connection to LND.

Tip2: Alternatively, you can copy the whole macaroon to the VPS and just link it in the .env file. With Umbrel this is even necessary.

scp ~/.lnd/data/chain/bitcoin/mainnet/admin.macaroon synonym@111.111.111.111:/home/synonym

7.9 – VPS – Install and set up LNbits

Check if the certificate and the Macaroon have been transferred

ls -l

Check if the SSL connection to the node is up

curl https://172.17.0.2:8080 -v --cacert /home/synonym/tls.cert 

If everything worked, you should find the following lines in the output:

 ..
 subjectAltName: host "172.17.0.2" matched cert's IP address!
 ..
 SSL certificate verify ok.
 ..
 Connection #0 to host 172.17.0.2 left intact
 ..

LNbits clone and install prerequisites

cd   
git clone https://github.com/lnbits/lnbits.git
cd lnbits
sudo apt update
sudo apt install software-properties-common  
sudo add-apt-repository ppa:deadsnakes/ppa # -> ENTER
sudo apt install python3.10
sudo apt-get -y install python3-distutils 
curl -sSL https://install.python-poetry.org | python3 -

Important: During the installation you will be shown the "poetry path" (e.g. /home/synonym/.local/bin). And this is followed by a whole command after "Add". This is the path for the "Poetry environment variables" and to announce the global variable you have to copy it once into the terminal window and press ENTER.

export PATH="/home/synonym/.local/bin:$PATH"

Make the label permanently available as a global variable.

To do this, open .bashrc once

nano /home/synonym/.bashrc 

And at the very end insert the following line

export PATH="/home/synonym/.local/bin:$PATH"

-> CTRL+x -> y -> ENTER

Poetry install and launch in a virtual environment

poetry env use python3.10 
poetry install --only main # -> This may take some time now 
mkdir ~/lnbits/data # This will be the folder for the LNbits database

Note: I once tried a VPS with 0.5 GB RAM. The installation was aborted in the middle. So I recommend at least 1 GB RAM.

Create and edit the LNbits setup file .env

cd ~/lnbits # -> Call the LNbits directory
ls -la # -> Show you all files
cp .env.example .env # -> create the .env from the example
nano .env # -> Open the file for editing

Settings to make in the .env file:

..
# Choose from LN..
LNBITS_BACKEND_WALLET_CLASS=LndRestWallet
..
# LndRestWallet
LND_REST_ENDPOINT=https://172.17.0.2:8080/
LND_REST_CERT=/home/synonym/tls.cert
LND_REST_MACAROON=0201036C6E6...
# Alternative: LND_REST_MACAROON=/home/synonym/admin.macaroon
..
  • You have to be very careful here, better check everything twice.
  • CTRL+x -> y -> ENTER

Tip 1: The exclamation marks "" behind the entries LND_REST_CERT= and LND_REST_MACAROON= are in the .env.example, but they always caused trouble for me. So better leave them out.

Tip 2: If you don’t have a node yet, or if your node fails, you can quickly add another source of funding here, so that your LNbits is still liquid. Just enter the appropriate wallet in the .env under LNBITS_BACKEND_WALLET_CLASS. And a bit further down, enter the admin key and the endpoint. E.g. for the LightningTipBot (LnTipsWallet) you get the API Key with the command /api and the Endpoint is https://ln.tips. And for a Custody LNbits Wallet from e.g. the legend-lnbits.com Demo Server (LnbitsWallet) LNBITS_ENDPOINT = https://legend.lnbits.com and LNBITS_KEY = LNBITS_ADMIN_KEY = in the Wallet under API Info the Admin key.

A test run

Make sure you have lnbits in your directory and then start an LNbits instance

poetry run lnbits # Exit -> CTRL-c

If you see Backend LndRestWallet connected and your Wallet Balance, congratulations, you win! 🔥

If you see Retrying connection to backend in 5 seconds..., something is wrong with the connection to your funding source (LND Wallet). Check the .env configuration file and specifically the LND_REST_MACAROON, LND_REST_CERT and the LND_REST_ENDPOINT.

Tip: If you think that everything is correct and it still doesn’t work and you used the "Macaroon HexString", then try to use the admin.macaroon directly by setting only a link to the file in the .env. Once I had the problem with the Umbrel, the "Macaroon HexString" did not work. Only when I used the Macaroon directly, the connection was established. How to copy the admin.macaroon to your VPS, I described at the end of the previous chapter. In the .env file you can link it e.g. with LND_REST_MACAROON=/home/synonym/admin.macaroon.

Option: Temporarily display the LNbits page

If you want to see your LNbits webserver already, you have to release port 9000 temporarily.

sudo ufw allow 9000 comment 'LNbits Test' 

Now you can assign LNbits your default route 0.0.0.0 on port 9000:

poetry run lnbits --port 9000 --host 0.0.0.0

Note: The command only works from the LNbits directory lnbits.

And now open a web browser and enter the IP of your VPS with port 9000:

111.111.111.111:9000

-> Et volia, your LNbits! 👀

The request IP:Port was pointed to the default route 0.0.0.0 of the VPS. There was the web page of the LNbits instance. Your browser surely warned you that the page was not secure. But this is normal, because the page does not have a valid SSL/TLS certificate. The point comes later with the web server, after we have set up a domain and it then points to the IP address of our VPS through a domain name system (DNS) entry. Then we can request a certificate for HTTPS (Hyper Text Transfer Protocol Secure) for the connection.

-> Exits LNbits again with CTRL+c

Closes the temporary port 9000 again and checks the setting of the UFW once

sudo ufw deny 9000
sudo ufw status

Recommendation: OpenSSL customization for the extension Onchain Wallets

LNbits uses a specific hash algorithm (ripemd160) in the Onchain Wallets extension. In the Python version 3.10 used here, the hashlib command uses the Open SSL software library. The library was updated Nov. 2021 and does not support the used hash algorithm ripemd160 by default. However, it is possible to re-enable this feature in a configuration file for OpenSSL. We have to do this once now, so that we can use the extension Onchain Wallets as well. First call the file openssl.cnf.

sudo nano /usr/lib/ssl/openssl.cnf

Checks the existence and extends the following lines if necessary:

openssl_conf = openssl_init

[openssl_init]
providers = provider_sect

[provider_sect]
default = default_sect
legacy = legacy_sect

[default_sect]
activate = 1

[legacy_sect]
activate = 1

-> CTRL+x -> y -> ENTER

More info about this problem and the solution can be found here.

Note: Activate LNbits debug mode

If you get an error when starting LNbits, which you can’t solve this way, you can activate debug. Open the .env file and -> set DEBUG=true and then start LNbits in debug mode.

$ poetry run lnbits --debug

7.10 – VPS – Set up LNbits Autostart

Check the "poetry path" once.

which poetry

-> If you used the same user: /home/synonym/.local/bin/poetry.

Check in the lnbits.service file that the path is correct.

Create the lnbits.service file

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

Fill the lnbits.service file with:

# Systemd unit for lnbits
# /etc/systemd/system/lnbits.service 

[Unit]
Description=LNbits

[Service]
# replace with the absolute path of your lnbits installation
WorkingDirectory=/home/synonym/lnbits
ExecStart=/home/synonym/.local/bin/poetry run lnbits --port 5000
User=synonym
Restart=always
TimeoutSec=120
RestartSec=30
Environment=PYTHONUNBUFFERED=1

[Install]
WantedBy=multi-user.target

-> Check the Poetry path (ExecStart), User and WorkingDirectory

-> Then CTRL+x -> y -> ENTER

Start service and check

sudo systemctl enable lnbits.service
sudo systemctl start lnbits.service
sudo systemctl status lnbits.service # -> q

-> you should get an active (running) and a Backend LndRestWallet connected as feedback

Tip: With the command $ sudo systemctl restart lnbits.service you can restart LNbits if you have made a change in the LNbits configuration file .env and want to apply it.

7.11 – General – A domain for your LNbits server

Congratulations on making it this far, that’s quite an accomplishment. You now have your own Virtual Private Server with VPN tunnel to the node to make your node accessible from the clearnet. You also have LNbits connected to your Lightning Node via the VPN tunnel, so that’s awesome! 🤜🤛

But what’s missing now is the step to make your LNbits reachable from the Clearnet as well and that’s already a small world of its own, the world of webhosting, domains, certificates and web servers.

If you already have your own web domain, you can set a ‘DNS entry type A’ for the domain (or subdomain) under ‘DNS / Nameservers’ to the IP address of the VPS. This will forward all requests to the (sub)domain directly to the LNbits server. Note, you may have to disable the automatic SSL certification for the (sub)domain of your host provider. We will do that ourselves later.

If you don’t have your own domain yet, you can get a free subdomain from e.g. DuckDNS.org. The setup is not very difficult:

  • Go to the page duckdns.org.
  • Register with one of the many options
  • Choose a subdomain.duckdsn.org
  • Set the IP address of your VPS for redirection

From now on, all requests you send to the domain will be automatically forwarded to your VPS.

7.12 – VPS – Set up Caddy Webserver

Caddy is an open source web server with automatic HTTPS certification and beams the web interface of your LNbits instance to Clearnet. It really takes care of everything very efficiently, including certificates and updating. You just have to let the DNS entry of the (sub)domain point to the IP address of the VPS, this was described in the previous section as ‘DNS entry type A’, the rest is done by Caddy.

Preliminary: Check DNS entry

Check first if the DNS entry works and the webdomain is forwarded directly to the IP address of your VPS. With DNS Lookup or whatsmydns.net. Remember that the update may take a few hours and then install Caddy.

Caddy install

cd ~
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy

Create the caddyfile

sudo caddy stop
sudo nano /etc/caddy/Caddyfile

Note: The file is filled with default values, you can delete them.

Now fill the caddyfile with this section

Attention: Adjust the domain address lnbitshero.duckdns.org for you beforehand

lnbitshero.duckdns.org {
  handle /api/v1/payments/sse* {
    reverse_proxy 0.0.0.0:5000 {
      header_up X-forwarded host lnbitshero.duckdns.org
      transport http {
         keepalive off
         compression off
      }
    }
  }
  reverse_proxy 0.0.0.0:5000 {
    header_up X-forwarded host lnbitshero.duckdns.org
  }
}

-> CTRL+x -> y -> ENTER

Note: Caddy obtains the certificate in this example only for the domain demo.ereignishorizont.xyz and not for subdomain www, e.g. www.demo.ereignishorizont.xyz. You need to keep this in mind.

Add Caddy Autostart Service

So that the caddy service will start after the next reboot of the VPS.

Note: ☝️ The Caddy Service now seems to be set up automatically during the standard installation. You can check whether the service is already running with $ sudo systemctl status caddy.service. If that is the case, you can skip this paragraph.

Create the file caddy.service:

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

Fill the file with:

# caddy.service

[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target

[Service]
Type=notify
User=caddy
Group=caddy
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile --force
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateDevices=yes
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target

-> After that: CTRL+x -> y -> ENTER

Release service, start and check

sudo systemctl enable caddy.service
sudo systemctl start caddy.service
sudo systemctl status caddy.service # -> q
sudo journalctl -u caddy -f --since "2 hour ago"  # -> CTRL+C

Your LNbits server should now be accessible under your web domain and hopefully working. 🚀

Is it still not working? I have attached a troubleshooting help for the error possibilities known to me.

Otherwise one last important note -> Set up the Admin UI with the Super User

You can also control your LNbits instance via the web interface. But you have to activate it first and generate the link to your super user account. How to do that, I show you in the appendix, under chapter `9.9.6 Admin UI & Super User.

Mission completed! 😄

8. Conclusion and summary

Hopefully, by the time you get here, you’ll be the proud owner of a globally accessible small private bank, with a Lightning ⚡ technology hub attached, and you’ll be able to help shape the future. 🥂 When you first see your own LNbits website in your browser, it’s an incredibly great feeling. The Lightning ⚡ technology makes us independent and thanks to LNbits we can offer people close to us a confidential environment for financial technologies and be their bank, so they don’t have to trust a stranger.

"Be a bank AND marketplace for your family & friends"

Bitcoin ⚡ Lightning network and the functions built on it will undoubtedly revolutionize the world. It just works. Sure, there are still plenty of problems to be solved and no one really knows where the journey is going, but it is being worked on manifold and open source at all levels. If you look outside the box, you can see that Bitcoin ⚡ Lightning is not just a simple payment system, but it is something completely new. Bitcoin ⚡ Lightning is natively digital and its inherent value, in the form of Bitcoin Satoshis, can be incredibly well processed digitally and processes can be automated with it. We don’t even need a middleman anymore and can send the best money we have to someone else directly, cheaply, quickly, across borders and at any time. This takes us to a whole new level of financial technology that was not possible before.

On October 31, 2008, Satoshi Nakamotor published the idea of Bitcoin with the whitepaper. On January 3, 2009, he made the heart of Bitcoin beat for the first time. Then in 2018, the Lightning ⚡ Network was added and the development continued to pick up speed. Now comes the third layer with LNbits as a platform for applications. And probably, there will be the fourth or fifth layer at some point, who knows. It will be very disruptive, but not radical. Everybody can join in, nobody has to. But it will make many monetary things easier, faster, cheaper, more scalable, more global, more independent, more resilient, and more flexible.

Forget Shitcoins and CBDC, forget DeFi, Web3, NFTs or Ordinals, and forget Metaverse. We still live in the real world. We now have digital cash and a working platform to build all sorts of things on. Our money has arrived in the 21st century.

My thanks go of course to Ben Arc who launched LNbits. But also to all the other developers who have helped and are constantly working on making LNbits grow and adding new features. Since LNbits is a free and open source project, everyone can contribute. Be it writing code, reporting a bug, testing something or maybe just writing some documentation.

Especially I want to thank TrezorHannes aka HODLmeTight who created the basis for this tutorial. He also had his sources, which again live the idea of Free and Open Souce Software. Software is information, information is knowledge and knowledge must be free so that society can get the best value for all from it.

You can get more information or help here:

Thanks a lot for your attention! I hope you enjoyed my tutorial and I could help you to host your own LNbits, so you are prepared for the future. Because with Bitcoin, Lightning ⚡ and LNbits, the future is guaranteed to be exciting.

If you liked my article or the tutorial or if it could even offer you some added value, I would be happy if you use Bitcoin ⚡ Lightning and send me some Satoshis in appreciation. You can find ways to do so on my contact page.

Stay curious and until the next tutorial

Axel

9. Appendix

9.1 Troubleshooting tips

  • Check the certificate of your domain: https://www.ssllabs.com/ssltest/

  • If there is something wrong with the certificate, check again your caddyfile and if the forwarding of your DNS entry works: whatsmydns.net

  • If you see Retrying connection to backend in 5 seconds... in the terminal window when you start LNbits via poetry command, then probably something is wrong in the .env file. Check the Macaroon, the Cert and the Endpoint.

  • If you get the message HTTP ERROR 502 then maybe your LNbits instance is not started. You can check this by checking the status of the lnbits.service: $ sudo systemctl status lnbits.service or sudo journalctl -u lnbits -f --since "2 hour ago". There you can also see if there is an error with the connection to your node. This can be caused by an error in the configuration file .env. Check which LNBITS_BACKEND_WALLET you have set and the corresponding data like LND_REST_MACAROON, LND_REST_CERT and LND_REST_ENDPOINT. What is also possible, maybe something is wrong with your PostgreSQL database or the LNBITS_DATABASE_URL link in the .env.

  • The call with the subdomain www. does not work. You would have to put in some extra work for that. So always enter your web address without the www in front of it.

  • The message ERR_CONNECTION_REFUSED appears if your caddy server is down. Check if the service is started: $ sudo systemctl status caddy.service.

  • If you see the message 500 on the LNbits page, then the connection to your node may be down. Maybe it is down or has no internet access at the moment?

  • If you get the error message All connection attempts failed 500 on the LNbits page, then your Docker may be down for the tunnel to the node.

    • Check if the Docker application is "active (running)": $ sudo systemctl status docker
    • Checks if your Docker container is also active: $ sudo docker ps -a
    • If you see STATUS / Exited, then the container seems to be down. Restart it again: $ sudo docker start < Docker ID >
    • If you haven’t already, add the autostart service: $ sudo docker update --restart unless-stopped < Docker ID >
  • If you get the message ERR_FAILED when you go to the page, then your VPS droplet is probably down.

  • The message 520 indicates that your LNbits server has switched to Voidwallet. If something is wrong with the set funding source, e.g. with the node, then it will automatically switch to the voidwallet. This is not a real wallet, it is more of a protection feature. LNbits can then still start normally, but then no deposits or withdrawals are possible. In this case, check the funding source. And if you want to know the reason for the changes, you should find it in the logs.

  • If you get the error 400 unspported hash type ripemd160 in the extention Onchain Wallet, then this is due to a compatibility error. You can find a solution here.

9.2 Perform LNbits update

LNbits stop and perform update

sudo systemctl stop lnbits.service
cd ~/lnbits
git pull
poetry self update
poetry install --only main

LNbits restart and read logs

sudo systemctl start lnbits.service
sudo journalctl -u lnbits -f --since "2 hour ago"

Check if your LNbits server was started correctly in the logs (journal) and on the website.

Possibilities to check the version

If the update was successful, you can see on the LNbits website at the bottom left. There you can see e.g.

LNbits🕳️🐇, LNbits Instanz von ereignishorizont.xyz LNbits version: 0.10.10, Commit version: fb98576431cb4096d92e2691c1dcb5ea5201befb

You can check which "version" is current. Execute the command $ git show. As result you get Merge pull request #1234 ... This is the number of the last pull request that was merged. If you now go to the GitHub page of LNbits, you can see there which PR was the last merge. This is a good way to see how far behind you are. You can get out of "git show" with q.

Are new functions added? Then check the .env file once.

With an update only the code of LNbits is updated, but not your database or configuration file .env. If there were changes / extensions, you must check independently or take the file from the .env.example as a template and create the .env again. You could compare the content very well by opening the .env file once with $ sudo nano ~/lnbits/.env and looking in a second window at the last .env.example state on GitHub.

Alternatively, you can do this manually:

cd ~/lnbits
ls -la
cat .env # -> old active file
cat .env.example # -> new one with possible changes
cp .env .env.bak # -> make backup
sudo nano .env # -> merge changes

restart LNbits with $ sudo systemctl restart lnbits.service

9.3 LNbits Option – PostgreSQL Database

The SQLite database installed by default is good and sufficient for getting started. But if you want to scale LNbits, you should switch to the more powerful PostgreSQL database. The data from the SQLite database can be transferred to the new PostgreSQL database quite easily. To be on the safe side, it is better to take a snapshot of your Droplet beforehand.

Before we start, here are two entries for the password list:

PostgreSQL User: postgres (Change it only, if you can keep the overview in the following) Password for user "postgres": myStrongPassword (Choose a strong password)

Install prerequisites

sudo apt-get update
sudo apt install python3-pip -y
pip install psycopg2-binary

Info: "pip" is a packing program and "Psycopg" is a PostgreSQL database adapter for Python

PostgreSQL installation and setup

sudo apt-get -y install postgresql
sudo -i -u postgres
psql
ALTER USER postgres PASSWORD 'myStrongPassword'; # -> Set a strong password!
\q
createdb lnbits
exit

Setting in the LNbits configuration file .env

cd ~/lnbits
sudo nano .env

-> # LNBITS_DATABASE_URL=.. Find entry and replace it with the following line

..
LNBITS_DATABASE_URL="postgres://postgres:myStrongPassword@localhost:5432/lnbits"
..
  • Syntax: "postgres://user:password@host:port/database_name"
  • At least adjust myStrongPassword.
  • CTRL-x -> y -> ENTER

LNbits stop once, start and test

sudo systemctl stop lnbits.service
cd ~/lnbits
poetry run lnbits # -> CTRL+c

-> Now no error message should be displayed and LNbits page should be available again

Note: LNbits is now working again, but all accounts and wallets are still in the old database. Therefore you have to transfer the data to the new database first.

Migrating the data from the old SQLite database to the new PostgreSQL

sudo systemctl stop lnbits.service
poetry run python tools/conv.py

Restart and test LNbits

sudo systemctl start lnbits.service
sudo systemctl status lnbits.service

-> Now LNbits should run as usual and all accounts, under Info you will see "Database: PostgreSQL" and the LNbits page will be available again.

Info: Show status of PostgreSQL

sudo systemctl status postgresql.service

9.4 LNbits – Databases Backup & Restore

9.4.1 Simple backup of a SQLite database

For occasional backups of SQLite you can simply backup the whole folder ./lnbits/data. To do this, change to the LNbits folder, where the folder ./data is located. It is best to enter a meaningful name, with date in the format "yy/mm/dd", then the backups sort themselves better in the view.

cd ~/lnbits
tar cfv data_backup_jjmmdd.tar ./data

Now TAR archive files have been created in the directory ./lnbits/. You can check this with $ ls -la.

Note: If you want to download the file to your PC, use for example this command:

$ scp synonym@111.111.111.111:/home/synonym/lnbits/data_backup_jjmmdd.tar ./`

9.4.2 Restoring a SQLite Database

Stop LNbits once before unpacking. It will then unpack to the same folder ./data. All files will be overwritten.

sudo systemctl stop lnbits.service
cd ~/lnbits
tar -xvf data_backup_jjmmdd.tar
sudo systemctl start lnbits.service

Note: To copy a backup file from your PC to your VPS, you can use this command:

scp data_backup_jjmmdd.tar synonym@111.111.111.111:/home/synonym/lnbits/

9.4.3 Simple backup of a PostgreSQL database

To make a backup of the database, you must first log in with the assigned user, e.g. postgres, with which you created the database lnbits. The file lnbits_jjmmdd will be created in this folder.

# LOGIN AS USER POSTGRES
sudo -i -u postgres
# BACKUP LNBITS DATABASE
pg_dump lnbits > lnbits_jjmmdd.sql
# CHECK BACKUP
ls -la
# EXIT USER POSTGRES
exit

9.4.4 Restoring a PostgreSQL database from a backup

To restore the backup, you need to do a few intermediate steps.

# STOP LNBITS
sudo systemctl stop lnbits.service
# LOGIN AS USER POSTGRES
sudo -i -u postgres
# LOGIN POSTGRES FRONTEND
psql
# SHOW LIST OF DATABASES
\l
# CONNECT FROM LNBITS TO POSTGRES DUMMY DATABASE
\c postgres
# DROP LNBITS DATABASE
DROP DATABASE IF EXISTS lnbits;
# QUIT POSTGRES FRONTEND
\q
# CREATE LNBITS DATABASE FROM TEMPLATE
createdb -T template0 lnbits
# RESTORE LNBITS DATABASE 
psql --set ON_ERROR_STOP=on lnbits < lnbits_jjmmdd.sql
# LOGIN POSTGRES FRONTEND
psql
# CONNECT FROM POSTGRES DUMMY TO LNBITS DATABASE
\c lnbits
# QUIT POSTGRES FRONTEND
\q
# EXIT USER POSTGRES
exit
# START LNBITS
sudo systemctl start lnbits.service
# CHECK JOURNALCTL
sudo journalctl -u lnbits -f --since "2 hour ago"

-> CTRL+c

Note: If you transfer the database from one system to another, there may be complications with the funding source and your Admin_UI may not work properly. Unfortunately you can’t easily change this afterwards, because you don’t have access to the Admin_UI anymore. Therefore you have to change it directly in the PostgreSQL database. How to do that I show in Chapter 9.9.6 Admin UI.

Note: If the database is installed on a new system, it may be that certain components, such as the BoltzClient is called in the new database, but has not yet been installed. Therefore one should make afterwards, a poetry install in the lnbits directory, in order to install all necessary components.

9.4.5 Auto Backup PostgreSQL Database Using a Cron Job

Preparation: Enable md5 hash function for password query

For the cron job you have to set the Message-Digest Algorithm 5 (MD5) as hash function for the PostgreSQL password request. Without this you will get a Peer authentication failed if you want to write something across domains (Ubuntu/Unix) or the password for your postgres is shown as incorrect. You have to edit two lines in the pg_hba.conf and restart the PostgreSQL service once. After that you have to renew the password hash by generating a new password (can be the same). But first check the version of PostgreSQL and if necessary change the path, here version 14 = ./14/., for your version.

psql -V
sudo nano /etc/postgresql/14/main/pg_hba.conf

Exchange peer for md5 in two places. Here is how it should look like.

..
# Database administrative login by Unix domain socket
local all postgres md5 

# TYPE DATABASE USER ADDRESS METHOD

# "local" is for Unix domain socket connections only
local all all md5 
..

restart PostgreSQL once

sudo service postgresql restart

Renew password hash

sudo passwd postgres
exit

-> Just enter the same password (myStrongPassword) again.

Test the new password once, with a login to the PostgreSQL frontend.

# DIRECT LOGIN TO THE FRONTEND (PSQL) OF POSTGRESQL
sudo psql -U postgres -W postgres
# LIST DATABASES
\l
# LOGOUT FROM FRONTEND (PSQL) AND FROM USER POSTGRES 
\q

Option: Changing the password for the PostgreSQL database

For the user postgres there are two passwords. One for the Ubuntu user and one for the PostgreSQL database user. If you want to change the password for the database, do the following. But beware, this can have an impact on the database. To be on the safe side, take a snapshot of the Droplet beforehand and also remember to change the password in the .env file under LNBITS_DATABASE_URL="postgres... If you forget this, your LNbits will no longer have access to the database.

# LOGIN LOGIN TO THE FRONTEND (PSQL) (USE OLD PASSWORD)
sudo -i -u postgres psql
# CHANGE PASSWORD
\password postgres
# LOGOUT FROM FRONTEND
exit

create the password file .pgpass for the automatic CronJob

# LOGIN AS USER POSTGRES
sudo -i -u postgres
# CREATE PASSWORD FILE
nano .pgpass

-> fill with hostname:port:database:username:password

localhost:5432:lnbits:postgres:myStrongPassword

"read/write" Restrict file permissions to the active user postgres:

chmod 0600 ~/.pgpass
exit

Cron job setup

# LOGIN AS USER POSTGRES
sudo -i -u postgres
# CREATE FOLDER BACKUPS
mkdir backups
# CREATE CRONJOB
crontab -e
# LOGOUT FROM USER POSTGRES
exit

-> In the crontap editor add the following lines as an example:

*/5 * * * * pg_dump -U postgres lnbits > ~/backups/lnbits.bak 
0   0 * * * pg_dump -U postgres lnbits > ~/backups/lnbits_$(date +\%Y\%m\%d).bak
0 */1 * * * pg_dump -U postgres lnbits > ~/backups/lnbits_$(date +\%H\%M).bak
0 */6 * * * pg_dump -U postgres lnbits > ~/backups/lnbits_$(date +\%Y\%m\%d_\%H\%M).bak

-> With CTRL+x -> y -> ENTER and then $ cd backups and $ ls -la. After 5 minutes the first backup should appear. Then $ exit.

  • The first entry is for testing the cronjob. It saves the database every 5 minutes to the file lnbits.bak.
  • The second entry writes the database every day at 00:00 to the file named lnbits_YYYYMMDD.bak.
  • The third entry writes the database recursively every hour to the file named lnbits_HHMM.bak.
  • The fourth entry writes the database every 6 hours to the file according to the format lnbits_YYYMMDD_HHMM.bak.

    Recommendation: Two and three for continuous operation

Time intervals, from left to right the asterisks/numbers mean:

  • Minutes , indicated as a number from 0 to 59.
  • Hours , indicated as numbers from 0 to 23.
  • Days of the month** , indicated as numbers from 1 to 31.
  • Months** given as numbers from 1 to 12.
  • Days of the week , given as numbers from 0 to 7, with Sunday represented as either 0 or 7.

Other: = execution always (at every…) and /n = execution of all n.

Which backup version you prefer and how you manage the maintenance, that you have to decide yourself. Also a CronJob for copying to another drive makes sense. But I am not that far yet. But to pull a simple backup to the PC and restore it once, you can use the following commands from the terminal of the PC:

# COPY BACKUP TO PC
scp postgres@111.111.111.111:/var/lib/postgresql/backups/lnbits.bak C:\Users\User
# COPY BACKUP TO VPS
scp C:\Users\User\lnbits.bak postgres@111.111.111.111:/var/lib/postgresql/

For restoring see: "9.4.4 Restoring a PostgreSQL database from a backup". The file is deliberately not copied to the "backups" folder, because the 9.4.4 instructions start from the "postgresql" folder.

Note: Because it is possible to access the PostgreSQL files from outside, it also makes sense to change the user postgres if you can handle it. But even more important is a very strong password!

Possible quicklinks from the root directory:

  • Show the content of the folder backups: sudo -i -u postgres ls -la backups
  • Display the crontab once: sudo -i -u postgres crontab -l
  • edit the crontab: sudo -i -u postgres crontab -e

More info about Cron can be found here.

9.4.6 Backup to an external drive via CronJob

Preparations on the target (the external storage, here another VPS)

Log in on the external machine and create a new user there, e.g. "userbackup", assign a password and create the folder "backups". The user does not need admin rights.

adduser userbackup
passwd userbackup
mkdir backups
cd backup
ls -la
pwd

Now log out and log in again with the new user to check later in the folder "backups" with ls -la if the backups arrive there.

Preparation on the source (the VPS with the data)

install sshpass for automatic SSH login

sudo apt install sshpass

Check existing backups and query path

sudo -i -u postgres
cd backups
ls -la
pwd
exit

Create a Secure Copy (scp) command and test

format: scp <source> <destination>

Example:

scp /var/lib/postgresql/backups/lnbits.bak userbackup@222.222.222.222:/home/userbackup/backups/lnbits_$(date +\%Y\%m\%d_\%H\%M).bak 
  • Now please test the copy command once and confirm it with the password of the user userbackup. The first time you run the command you will have to confirm that the SSH key is a trusted key. Without it, the automatic system will not work later.
  • The backup file lnbits.bak will be copied once to the remote target, here another VM with the IP: 222.222.222.222. On the target the file is renamed and gets the current date and time added.

Add the Secure Copy (scp) with sshpass

format: sshpass -p "password" scp <source> <destination>

Example:

sshpass -v -p 'yourPassw0rd' scp /var/lib/postgresql/backups/lnbits.bak userbackup@222.222.222.222:/home/userbackup/backups/lnbits_$(date +\%Y\%m\%d_\%H\%M).bak 
  • This is the command you could use for the CroneJob. From now on you should not be asked for the password of the userbackup (here "yourPassw0rd"). The command extension -v shows you some more information about the operation. This is quite useful for debugging, but not necessary.

Set up a CronJob for the automatic transfer

Sets up the daily database backup for the user postgres for the first time.

sudo -i -u postgres crontab -e

Adds the following line:

0 0 * * * pg_dump -U postgres lnbits > ~/backups/lnbits.bak

This will recursively backup the database to the file lnbits.bak every day at 00:00.

Next it is important to set up the cron job for copying with the user synonym. The command does not work with the user postgres. So open CronTab with the user synonym.

crontab -e

Adds the following line:

5 0 * * * sshpass -p 'yourPassw0rd' scp /var/lib/postgresql/backups/lnbits.bak userbackup@222.222.222.222:/home/userbackup/backups/lnbits_$(date +\%Y\%m\%d_\%H\%M).bak 

At 00:05 this copies the lnbits.bak to the VPS and adds the current date and time. Finished is the backup to an external drive.

You can check the logs of the CronJobs with this command:

sudo grep CRON /var/log/syslog

9.4.7 Maintaining the backup archive / Deleting old files

Show backup files

sudo -i -u postgres
cd backups
ls -la
pwd

List all backup files starting with lnbits* and older than 3 days

find /var/lib/postgresql/backups/lnbits* -type f -mtime +3

Note: The * is a wildcard and stands for "any".

You can also delete the files by appending -delete to the command

find /var/lib/postgresql/backups/lnbits* -type f -mtime +3 -delete

With a CronJob you can automate the deletion process. Open CronTab with the user postgres:

sudo -i -u postgres crontab -e

And add the following line:

0 1 * * * find /var/lib/postgresql/backups/lnbits* -type f -mtime +14 -delete

Every day at 01:00 the folder backups is searched for lnbits* files and all older than 14 days are deleted.

9.5 Useful shortcut examples

# Generally
ls -la
pwd
du -sh file.bak
sudo systemctl poweroff
sudo systemctl reboot
sudo find /mnt/hdd/ -iname "RTL-Config.json"

# Firewall
sudo ufw allow 9735 comment 'Node1' 
sudo ufw enable
sudo ufw status 

# Docker
sudo systemctl status docker
sudo docker ps -a 
sudo docker start 8c5c4bf6c634
sudo docker stop 8c5c4bf6c634
sudo docker exec -it 8c5c4bf6c634 sh

# Check communication from the VPS to the node
curl https://172.17.0.2:8080 -v --cacert /home/synonym/tls.cert  

# LND 
sudo nano /mnt/hdd/lnd/lnd.conf
sudo systemctl restart lnd.service
sudo systemctl status lnd.service 
lncli getinfo
sudo tail -n 30 /mnt/hdd/lnd/logs/bitcoin/mainnet/lnd.log
sudo journalctl -u lnd.service -f --since "1 hour ago"

# OpenVPN
sudo systemctl status openvpn@CERT
sudo journalctl -u openvpn@CERT -f --since "1 hour ago"

# Transfer
scp synonym@111.111.111.111:/home/synonym/lnbits/lnbits.bak ./
scp lnbits.bak synonym@111.111.111.111:/home/synonym/lnbits/
scp root@111.111.111.111:/home/synonym/node1.ovpn /home/admin/VPNcert/
scp /mnt/hdd/lnd/tls.cert synonym@111.111.111.111:/home/synonym

# PostgreSQL & Cronjob
sudo -i -u postgres
sudo -i -u postgres ls -la backups
sudo -i -u postgres crontab -e
sudo systemctl status postgresql.service
sudo grep CRON /var/log/syslog

# LNbits
cd ~/lnbits
sudo nano ~/lnbits/.env
sudo systemctl restart lnbits.service
sudo systemctl status lnbits.service
sudo systemctl stop lnbits.service
sudo systemctl start lnbits.service
poetry run lnbits
sudo journalctl -u lnbits -f --since "2 hour ago"

# Connection test and network diagnosis/info
ping -c 3 google.com
ip add show tun0
ifconfig
nslookup google.com
dig google.com
sudo netstat -tulnp
sudo lsof -i :8081
curl https://api.ipify.org 

9.6 Reference table for Umbrel paths and commands

Raspiblitz v1.8.x Umbrel v0.5.x
ssh admin@192.168.x.x ssh umbrel@192.168.x.x
/home/admin/ /home/umbrel/
/mnt/hdd/lnd/ /home/umbrel/umbrel/app-data/lightning/data/lnd/
sudo nano /mnt/hdd/lnd/lnd.conf sudo nano /home/umbrel/umbrel/app-data/lightning/data/lnd/lnd.conf
sudo systemctl restart lnd.service sudo ~/umbrel/scripts/app restart lightning
lncli getinfo ~/umbrel/scripts/app compose lightning exec lnd lncli getinfo
tail -f ~/umbrel/app-data/lightning/data/lnd/logs/bitcoin/mainnet/lnd.log
/home/admin/VPNcert/ /home/umbrel/VPNcert/
scp synonym@111.111.111.111:/home/synonym/node1.ovpn /home/admin/VPNcert/ scp synonym@111.111.111.111:/home/synonym/node1.ovpn /home/umbrel/VPNcert/
sudo chmod 600 /home/admin/VPNcert/node1.ovpn sudo chmod 600 /home/umbrel/VPNcert/node1.ovpn
sudo cp -p /home/admin/VPNcert/node1.ovpn /etc/openvpn/CERT.conf sudo cp -p /home/umbrel/VPNcert/node1.ovpn /etc/openvpn/CERT.conf
scp /mnt/hdd/lnd/tls.cert synonym@111.111.111.111:/home/synonym scp /home/umbrel/umbrel/app-data/lightning/data/lnd/tls.cert synonym@111.111.111.111:/home/synonym
xxd -ps -u -C ~/.lnd/data/chain/bitcoin/mainnet/admin.macaroon xxd -ps -u -C /home/umbrel/umbrel/app-data/lightning/data/lnd/data/chain/bitcoin/mainnet/admin.macaroon
scp ~/.lnd/data/chain/bitcoin/mainnet/admin.macaroon synonym@111.111.111.111:/home/synonym scp /home/umbrel/umbrel/app-data/lightning/data/lnd/data/chain/bitcoin/mainnet/admin.macaroon synonym@111.111.111.111:/home/synonym

9.7 Uninstallations / Deconstruction

I find instructions for uninstalling software almost as important as those for installations. If you decide not to use the software or a problem arises, there must be a way to restore the device to its original state, especially if it is a Lightning Node. So here are a few hints.

Uninstall OpenVPN from the Node

sudo apt-get remove --purge openvpn
sudo rm -r /etc/openvpn
sudo rm -r /home/admin/VPNcert

restore the backup of lnd.conf

cd /mnt/hdd/lnd/
sudo cp lnd.conf.backup lnd.conf 

Alternative, manually restore the settings

sudo nano /mnt/hdd/lnd/lnd.conf

Change the corresponding line (true -> false) or comment it out with "#".

[Application Options]
..
nat=true # true = dynamic IP (NAT) 

# externalip=111.111.111:9735 # for OpenVPN
# tlsextraip=111.11.0.2 # for Wireguard

[tor]
..
# tor.streamisolation=false
# tor.skip-proxy-for-clearnet-targets=true

Special feature, ONLY on the Raspiblitz

Call the lnd_check.sh script at line 184

sudo nano +184 /home/admin/config.scripts/lnd.check.sh

And comment out the following line

  # enforce PublicIP if (if not running Tor)
  if [ "${runBehindTor}" != "on" ]; then
    setting ${lndConfFile} ${insertLine} "externalip" "${publicIP}:${lndPort}"
  else
    # when running Tor a public ip can make startup problems - so remove
    sed -i '/^externalip=*/d' ${lndConfFile}
  fi

Note: A bit further up it also says # enforce LND port is set correctly. If you also commented out the lines because you used a port other than 9735.

Restart the whole node once

sudo systemctl reboot

Now everything should work as before. To check, have a look at chapter "7.7 – General – Checking the connection" again

Removal Droplet

You can simply "destroy" (delete) the droplet (the VPS) on DigitalOcean.

9.8 Sources and additional documentation

Guide VPS-LNbits from TrezorHannes: https://github.com/TrezorHannes/vps-lnbits
Guide Docker-OpenVPN from Kyle Manna: https://github.com/kylemanna/docker-openvpn
Guide How-to from OpenVPN: https://openvpn.net/community-resources/how-to/
Guide Turn your self hostet.. from MobyCrypt: https://www.mobycrypt.com/turn-your-self-hosted-lightning..
LNbits – GitHub: https://github.com/lnbits/lnbits
LNbits – Wiki / Doc.: https://github.com/lnbits/lnbits/wiki
LNbits – Telegram Group: https://t.me/lnbits
LNbits – Option PostgreSQL database: https://github.com/lnbits/lnbits/blob/main/docs/guide/..
LNbits – SQLite to PostgreSQL migration: https://github.com/lnbits/lnbits/blob/main/docs/guide/..
LNbits – Video – Installation PostgreSQL: https://www.youtube.com/watch?v=hKFWhBKcwlo
Caddy.Service GitHub: https://github.com/caddyserver/dist/blob/master/init/caddy.service

9.9 Miscellaneous

This is where everything that is not primarily important, but can extend the tutorial, goes.

9.9.1 Node Alias Name

In the lnd.conf you can give your node a name (alias), if it doesn’t have one yet. It will then appear for certain services. Just add it to "Application Options". If you want you can even add an emoji to the node alias. Here you can find a good overview of emojis. But the emojis are not supported by all services and that can make it look a bit strange.

Example for an alias name:

[Application Options]
..
alias=FunnyName⚡
9.9.2 Personalize LNbits

-> Settings to be made in the .env file:

# Change theme
LNBITS_SITE_TITLE="LNbits🐣" # Icon see appendix "Alias name for the node".

You can find possible emojis here.

Note: If you change the LNBITS_SITE_TITLE, LNbits will not show you the last Commit version on the start page anymore.

9.9.3 "Telegram Ping Bot" to test the connection

Search for the Tunnel⚡️Bot:

https://t.me/TunnelSatsBot

Start the bot and then type the command /ping followed by the node ID, an "@", the IP and the port for the LND

/ping <node-ID>@<your-node-ip>:port

E.G.:

/ping 292f947f27220d327817f0dd3931898661a33a527ecd6242e34af2c4839956bf0@38.242.135.150:24438

It also works for the Tor connection:

/ping <Node-ID>@<tor-node.onion>:port

Note:Sometimes it can take a while until the bot reacts, especially with Tor requests it can take up to 1 or 2 minutes, so be patient.

9.9.4 A private VPN tunnel

The tunnel technology you have learned now, you can of course use for other functions. For example, you can create your own VPN connection. Either to surf the internet from your desktop PC via a VPS, so that your internet provider doesn’t know who you are connecting to and nobody can see your real location from the outside. If you are on the road with your cell phone or in a public WiFi, it can also make sense to use VPN. No one has to know where you are or what pages you are visiting. In principle, you can also use the VPS to securely access your home network via a second VPN tunnel to your mobile phone/computer. The application possibilities are manifold and there are now many clients for desktop and mobile devices. See openvpn.net.

9.9.5 Connecting a Wallet App like Zeus

If you enable port 8080 in the UFW (uncomplicated firewall) of the VPS, you can connect a Lightning wallet app like Zeus to your node. You only need the data Host = the IP of the VPS / LND Port = 8080 / Macaroon = which you have read out from your node in this tutorial. During the setup you will be asked for a certificate. This is the certificate for the encryption of the connection. While you can ignore it when connecting to your node in your home WLAN / LAN network, you should avoid an unencrypted communication in the open internet. So I should either use the certificate or build a VPN tunnel.I have not yet gone deeper into this myself, but will do so in due course and then add to it here.

9.9.6 Admin UI & Super User

Enable Admin UI and get Super User Account

The Admin UI is practical and necessary, because you can make many settings via the Web UI and activate extensions via it in the first place. You get a Super User Account for it, at the first start with the new settings in the .env, if you activate it. You have to save the account like a wallet account. Here are the instructions how to activate the account.

sudo systemctl stop lnbits.service
cd ~/lnbits
sudo nano .env

-> Set: LNBITS_ADMIN_UI=true

Now LNbits starts again

sudo systemctl start lnbits.service

The Super User has now been activated in the background and you can see its ID with the following command

cat ~/lnbits/.super_user

Alternative:

cd lnbits
poetry run lnbits-cli superuser

You will now see a string of 32 characters, this is the ID.

You can append it behind the link to your LNbits page, e.g.

https://lnbits.meineseite.org/wallet?usr=5216fc241448acb2344f32245

Now the page of the Super User should open. You will also see this displayed in the upper left corner and you have also received the Manage Server menu in addition to the Extensions menu. Keep this link safe. Open the page also best only if you have previously opened an incognito window in the browser. If you have this link, you have full control over your LNbits instance, including access data to the funding wallets.

Otherwise, you can design the interface here, it has TOPUP to fill wallets and you can now also share extensions with users here or restrict access rights to extensions. You can make users Admins or set Allowed Users if you want to restrict access. And of course also the classic settings that you would have done otherwise under the .env file, e.g. change the funding source wallet or set a charge fee.

Important note: Once you have set LNBITS_ADMIN_UI=true, you will not be able to get back to using the .env file. The values are stored in the database and cannot be overwritten by the .env file. If you need to go back, see the following expert tip.

Further hint: If you set ‘RESET TO DEFAULTS’, a new Super User account will be created. The old one is then no longer valid.

Expert tip, only for emergency: Delete PostgreSQL database entry for Admin UI

A once set Admin_UI=true writes the values of the .env file once into the database. Afterwards you can always use Admin_UI=false to go back to the .env settings, but the next time Admin_UI=true is used, they will not be transferred again from the .env to the database. If you copy now e.g. a database from one device / VPS to another, it can be that the funding source does not fit on the new system and LNbits does not start with the Admin_UI. Unfortunately you can’t change this afterwards. So you can only start LNbits with the data in the .env. To be able to work with the Admin_UI again, you have to edit the database directly. Exactly said delete the content of the table "settings". Here is a description how you can do that. You can leave the parameter Admin_UI=true in the .env and then execute the following commands.

# STOP LNBITS
sudo systemctl stop lnbits.service
# LOGIN AS USER POSTGRES
sudo -i -u postgres
# LOGIN POSTGRES FRONTEND
psql
# SHOW LIST OF DATABASES
\l
# CONNECT TO LNBITS
\c lnbits
# LIST TABLES FROM LNBITS DATABASE
\dt
# REMOVE ALL ROWS FROM TABLE "SETTINGS"
TRUNCATE TABLE settings;
# QUIT POSTGRES FRONTEND
\q
# EXIT USER POSTGRES
exit
# LNBITS TEST START TO VERIFY WALLET SPECIFIED IN THE .ENV
cd ~/lnbits
poetry run lnbits
# -> IT SHOULD SEE THE ADMIN SUPER USER ACCOUNT AND NEW FUNDING SOURCE
# FINALLY START LNBITS SERVICE
sudo systemctl start lnbits.service
9.9.7 Multiple Nodes on a Virtual Private Server

You can also manage multiple Node Clearnet Internet accesses with one VPS. Either for the families or friends, or if one has a second or even third Node. If one node fails, you can easily point LNbits to another node to use the new funding source. To not overstretch the frame of this tutorial, I created an extra page for this. You can find it here: Multi Node VPS (en)

9.9.8 VPS Ubuntu Update

When you login to your VPS you can see in the terminal window if new updates for Ubuntu are available. Unfortunately, an update cannot be done directly with the user synonym, not even with the command sudo. So you have to log in either with the root user or switch to the root user. Here is a possible sequence for the login of the user synonym.

sudo systemctl stop lnbits.service
sudo su -
apt update && apt upgrade -y
reboot
9.9.9 Attention, path change from "lnbits-legend" to "lnbits"

With LNbits version 0.10, the Github path has also moved from "lnbits-legend" to "lnbits". To make this quite consistent, I have also adapted this tutorial. All commands have been changed to the new path. Only the images are still after the old path. Who has created a LNbits server still after the old tutorial, I show here how he can also move the path for his instance. For me, this worked well, but still prefer to make a snapshot before, just to be sure.

# STOP LNBITS
sudo systemctl stop lnbits.service
# CHANGE LNBITS PATH
cd
mv -v lnbits-legend/ lnbits/
# REINSTALL / CREATE NEW ENV
cd lnbits
poetry install --only main
# OPTION: CHECK ENV
poetry env list
# CHECK LNBITS FUNCTION
poetry run lnbits
# EDIT PATH IN FOR WorkingDirectory
sudo nano /etc/systemd/system/lnbits.service
# RELOAD LNBITS.SERVICE
sudo systemctl daemon-reload
# START SERVICE AGAIN
sudo systemctl start lnbits.service
# CHECK SERVICE
sudo journalctl -u lnbits -f --since "2 hour ago"
# OPTION: EDIT URL FOR GIT PULL
vi .git/config
# -> :q! (leave without changes)
# -> a (edit modus)
# -> edit: "url = https://github.com/lnbits/lnbits.git"
# -> ESC (escape edit modus)
# -> :wq (save and exit)
9.9.10 Securing the server with SSH keys

SSH keys consist of a private and public key pair. This key pair is generated on the client computer and is valid only for this computer. You cannot simply copy it to another computer and use it. The private key can be additionally encrypted with a passphrase. So that, when calling the SSH connection, the private key must be decrypted first. This gives an additional security, but it is not absolutely necessary. The security is ensured by the fact that only the computer/client has access to the server for which the public key has been stored on the server. Several public keys can be stored on the server. Then also more computers have access to the server. The key pair for the client and the file for managing the public keys on the server can be found in the home directory in the folder .ssh. e.g. /home/user/.ssh or C:\Users\User\.ssh. The file with the private key is usually called "id_rsa", with the public key "id_rsa.pub". The file where the public keys are managed on the server is called "authorized_keys".

To transfer the public key of the client to the server, there are different options. The easiest one is to transfer the public key with the help of the clipboard. To do this you have to open a terminal window with access to the server, that is before you have deactivated the password login. The public key is only a text string and must be copied into the file "authorized_keys". From then on you can log in with the public key. You have to keep in mind that for every SSH connection there has to be a public key on the server. If you want to request a file from the server to copy it to the node, e.g. a Raspi flash, then the node must also have a key pair and the public key of the client must be stored on the server.

Here is a possible way to set up the SSH key function afterwards:

# Generate key pair on the client
ssh-keygen
# -> ENTER to accept the default path and filename
# -> enter a passphrase to encrypt the private key if desired
# -> Generated files private key / public key (.pub)
/Users/User/.ssh/id_rsa     
/Users/User/.ssh/id_rsa.pub 

# You can also change the passphrase afterwards
ssh-keygen -p   

# call the directory .ssh
cd \Users/User\.ssh
# read the content of the public key
notepad id_rsa.pub
# Copy the content to the clipboard

# Log in to the server (still without SSH key request)
ssh synonym@111.111.111.111
# call directory .ssh in the user's root directory
cd .ssh
# open file "authorized_keys"
nano authorized_keys
# -> copy the content of the private key to the end of the file
# save and close
# Log out and log in again to test the function
# Now only the passphrase should be asked but not the login anymore
# If you just press ENTER without entering the passphrase, you will be prompted to login

# Disable the password authentication and the root access
sudo nano /etc/ssh/sshd_config
# Comment out:
PasswordAuthentication no
# Optional if root login is not desired:
PermitRootLogin no
# Restart server
sudo service ssh restart

# If PasswordAuthentication is already set to "no" and you can still log in via User Login,
# then you have to edit a parent ".conf" file. The path to the file can be found in the "sshd_config" again.
# It can look like this: "Include /etc/ssh/sshd_config.d/*.conf". So more settings will be taken from the .conf.
# To view the file, we first go to the folder
cd /etc/ssh/sshd_config.d/
# The files lists
ls -la
# Open the file
sudo nano 50-cloud-init.conf
# set PasswordAuthentication from "yes" to "no"
# Then restart the server once
sudo service ssh restart
# Now you should not be asked for a password anymore and you can only log in with the SSH key

# Hint, if the directory .ssh doesn't exist for a new user you can create it with this command
mkdir -p ~/.ssh
# And herewith the file "authorized_keys
nano ~/.ssh/authorized_keys

Note: You can also find a good tutorial here.

Another tip. If you create a new user and have already deactivated the login password, you must first give the new user your public SSH key via the root user, otherwise you will be denied access. To do this, log in as root user. Runs the $ su synonym and $ cd /home/synonym commands. You are then on the user level and can fill the “authorized_keys” file with your public SSH key as described above. The login should then also work with the new user.

9.9.11 Cronjob to restart the LNbits server automatically

For some time there was a bug that caused LNbits to hang. The bug could only be fixed by a restart. To ensure that this bug was fixed proactively, I had the server restart every 30 minutes. Attached is the corresponding cronjob. This function is now no longer necessary, but I’ll just leave it in for the sake of completeness.

# Create cronjob with root privileges
sudo crontab -e
# add the following entry to the end
*/30 * * * systemctl restart lnbits.service
# save and close with CTRL+x -> y -> ENTER
# check logs
sudo grep CRON /var/log/syslog

-> every full hour at minute 0 and 30 the lnbits.service is restarted once

For more info about Cron see here.


If you liked the article, I’m happy about a message. 📨
My⚡️My Lightning address: axelhamburch@ereignishorizont.xyz

Tip: By the way, this also works with the LightningTipBot .
Syntax: /send <Amount> <LightningAddress> <Message>


Created with love 🧡 Since 775773 / 825674

– Lightning ⚡ (er)leben –