Multi Node VPS

Multi Node VPS

Multi Node VPS

In this small addition to the LNbits server tutorial I want to show what you need to set up multiple tunnels on one VPS, so you can get multiple nodes into the clearnet via one VPS. Additionally I have also included the LNbits REST API for each tunnel to the node. So the owner of the VPS can easily switch the funding source of his LNbits. I will show this here only in excerpts. So you also need the original tutorial.


  • Node 1 – LND Port 9735 / REST API Port 8080
  • Node 2 – LND Port 9736 / REST API Port 8081
  • Node 3 – LND Port 9737 / REST API Port 8082

Addition to 7.2 – VPS – Basic settings of the Virtual Private Server

UncomplicatedFirewall (UFW) installieren und einrichten

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 allow 9736 comment 'Node2' 
ufw allow 9737 comment 'Node3' 
ufw enable   # -> y
ufw status   # -> Check if OpenSSH or 22/tcp is inside!

Addition to 7.3 – VPS – Installing and setting up Docker

Here you need to add the ports in Docker for the additional nodes and generate the additional nodes certificates. What is also added here, if you have multiple nodes it makes sense to assign a fixed tunnel IP to each node. Otherwise the IP is assigned freely by the server. Whoever requests first after a restart of the VPS gets the first IP. This is a bit inconvenient if you want to set the routings in the iptables firewall.

Starting the OpenVPN server process

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

generate a client certificate without a passphrase for the nodes

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

get client configuration with embedded certificates for the nodes

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

NEW – Assign a fixed IP to the VPN tunnel for each node

To process the data for the Docker volume, you must first switch to the superuser/root account

sudo su
cd /var/lib/docker/volumes/ovpn-data/_data/ccd/
nano node1
  • fill with: ifconfig-push
  • CTRL-x -> y -> ENTER

Repeat for the second node e.g.

nano node2
  • fill with: ifconfig-push
  • CTRL-x -> y -> ENTER

The third node gets the IP ending .14 / .13 and the fourth node gets .18 / .17. The node side of the tunnel, is always assigned the higher number, e.g. .6 and the server gets the ".5".

Info: Example IP assignment for full compatibility with multiple nodes:

[ 1, 2] [ 5, 6] [ 9, 10] [ 13, 14] [ 17, 18] [ 21, 22] [ 25, 26] [ 29, 30] [ 33, 34] ..

To activate the settings, reboot the VPS once $ reboot. Alternatively, you can just restart the Docker container $ docker restart <Docker-ID> and then exit the superuser/root with $ exit.

Note: After you have installed and set up OpenVPN on the node, you can check there with the command $ ip add show tun0 if you got the assigned IP.

Display the container ID

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

Display the path to the nodex.ovpn files

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

Addition to 7.4 – Node – Set up OpenVPN

Now you have to download and set up the individual certificate for each node. Here is an example for Node2.

Download the certificate from the VPS

Attention: Adjust IP and if necessary the paths

scp synonym@ /home/admin/VPNcert/

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

Assign read and write permissions only for the user

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

Install and set up OpenVPN

Attention: Also here adjust the path or name if necessary

sudo apt-get install openvpn -y
sudo cp -p /home/admin/VPNcert/node2.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: peer dev tun0

Now the IPs should be displayed automatically.

Addition to 7.5 – VPS – Specifying package rules for Docker

Call Docker Shell

sudo docker ps # -> display the ID again
sudo docker exec -it b7a78bb8b394 sh # -> start shell

Info: With the slightly extended command $ sudo docker ps -a you can also see 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
iptables -A PREROUTING -t nat -i eth0 -p tcp -m tcp --dport 8080 -j DNAT --to
iptables -A PREROUTING -t nat -i eth0 -p tcp -m tcp --dport 9736 -j DNAT --to
iptables -A PREROUTING -t nat -i eth0 -p tcp -m tcp --dport 8081 -j DNAT --to
iptables -A PREROUTING -t nat -i eth0 -p tcp -m tcp --dport 9737 -j DNAT --to
iptables -A PREROUTING -t nat -i eth0 -p tcp -m tcp --dport 8082 -j DNAT --to
iptables -t nat -A POSTROUTING -d -o tun0 -j MASQUERADE

Note 1: You can check the IPs on the node with the command: $ sudo systemctl status openvpn@CERT.

Note 2: Remember also that the ports you assign here for the LND nodes and for the REST API are also released on the node side in the ufw (uncomplicated firewall), otherwise it won’t work.

Save the rule permanently

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

cd /etc/openvpn
vi # -> editor opens

It became now the vi editor. The handling is a bit unusual, but if you follow the steps exactly, you should reach your goal. You can also find a command overview here.

For practice leave the editor now:

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

Now open the editor again:

  • vi
  • 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 "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:


Addition to 7.6 – Node – Adjusting lnd.conf

On the Node you have to release the firewall port. For example I do this for the Node2 with the LND port 9736 and REST API port 8081. For the Raspiblitz you also have to adjust the script. Otherwise the ports in the lnd.conf will be overwritten at the next reboot.

NEW Edit Firewall

sudo ufw allow 9736 comment 'VPS Tunnel LND Node2'  
sudo ufw allow 8081 comment 'VPS Tunnel REST Node2' 
sudo ufw status

Here you can check if the ports (9735, 9736,..) are open for the LND Node. This only works when the LND is running and working normally. You can’t check the REST ports (8080, 8081,..) with this, because the ufw of the VPS didn’t release the ports and doesn’t have to, because LNbits accesses the LND from the VPS over the tunnel and not over the internet.

LND.conf edit

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

-> Check the following line and adjust if necessary:

[Application Options]
nat=false # -> check and set to false
listen= # -> check it
restlisten= # -> check it

Special feature: ONLY on the Raspiblitz

The script checks the lnd.conf and might overwrite your settings. Therefore you have to comment out some lines.

Call in the script the lines from 184:

sudo nano +184 /home/admin/config.scripts/

Comments out the following line with #:

# setting ${lndConfFile} ${insertLine} "restlisten" "0\.0\.0\.0\:${portprefix}8080"

# # enforce LND port is set correctly (if set in raspiblitz.conf)
# if [ "${lndPort}" != "" ]; then
# setting ${lndConfFile} ${insertLine} "listen" "0\.0\.0\.0\:${portprefix}${lndPort}"
# else
# lndPort=9735
# fi

# # 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: 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 

-> Both commands may take some time, be patient

Check if the certificate and the key has changed

ls -l 

-> Date and time (GTM) of the tls.cert and tls.key files must have updated, if you made one for the certificates change!

Connection test

Test if you can reach the Google server from your node:

ip route get

-> You should get back via dev tun0 src

Note about Ride The Lightning (RTL)

By default RTL uses the REST port 8080 to access LND. Therefore you will get the error message Error 503 - Unable to Connect to LND Server when accessing the website if you change the REST port 8080 to LND. So you have to inform RTL about the port change. The port is defined in the file /mnt/hdd/app-data/rtl/RTL/RTL-Config.json, but the JSON is always overwritten by the startup script /home/admin/config.scripts/ on the Raspiblitz. Therefore you have to edit this.

sudo nano /home/admin/config.scripts/
  • Now search for "lnServerUrl" with: CTRL+w -> lnServerUrl -> ENTER
  • Change the port for lnServerUrl from 8080 to e.g. 8081 for the second node
  • Then restart the RTL.service once
sudo systemctl restart RTL.service

Note: For Thunderhub you don’t need this, because TH uses the RPC port 10009 instead of the REST port.


Everything else is basically the same as the original tutorial.

-> back to LNbits Server

Created with love 🧡 Block 775775 / 825673

– Lightning ⚡ (er)leben –