Guide to Networking for LND

Getting networking correct for lnd can be daunting for a beginner. This guide is meant to help with that on a general level, but obviously there are too many different solutions out there that it can cover the specifics on different types of devics. I will start from the inside, at the lnd software.

This guide will assume you are running under Linux – or any other Unix-like system which usually have the same user structure. This guide is current as of lnd v0.5.1, and will be updated in the future.

I have used IP address 1.2.3.4 to signify IP addresses you are meant to replace with your own, and your.domain.name to signify domain names you are meant to replace.

 

Listening port for protocol traffic

It is most usual to have LND listen on port 9735, on all IP addresses. This is done with the configuration line

listen=0.0.0.0:9735

Common networking notation uses 0.0.0.0 to signify any IP addresses, and the port number after a colon.  For most people, there wouldn’t be much need for changing this.

There is a command you can run to check which ports you are listening on, which is pretty useful at times:

netstat -an | grep LISTEN

Listening ports for administrative traffic – and applications!

There are two ways to communicate with lnd for controlling it – rpc and rest. Rest is really just a proxy for the rpc service, whether you choose to use either for your application is a matter of taste. The syntax is as for the listen command

rpclisten=1.2.3.4:10009
restlisten=1.2.3.4:8080

The administrative command, lncli, uses RPC. This command doesn’t read the configuration file, so if you change the port – 10009 – or run lncli on any other host than the same machine LND runs – you are going to have to specify this on the command line of lncli, with the –rpcserver parameter. You are also going to have to worry about things like certificates and macaroons, which I will cover next, but not specifically for lncli.

If you specify 0.0.0.0 as IP address, this means all IP-adresses, of course.

Certificate

The certificate will automatically be valid for IP addresses you specify directly here, but if you are using 0.0.0.0 to signify “any IP adress” here, you are going to  have to specify in the configuration file (or on the command line) what extra things should be encoded in the certificate. My preference is to actually have a domain pointing to it, and use the tlsextradomain parameter to make it valid for the domain:

tlsextradomain=foo.bar.com

You can also add extra IP addresses with

tlsextraip=1.2.3.4

This is probably one of the hardest parts of the lnd configuration, but if you are only going to use it as a wallet or routing node, you don’t have to worry about this at the start, and can think about it later when you decide to start using it for something else.

The certificates will be found in ~/.lnd of the user that runs lnd.

If you change the contents of what the certificate should contain, you will have to force regeneration of it, by

  • Stopping the node
  • Removing ~/.lnd/tls.cert and ~/.lnd/tls.key
  • Starting the node again

Remember to update tls.cert if you had previously copied it for use somewhere else. tls.cert is not secret, tls.key is the secret part of it that you need to keep on the server and not reveal to anyone.

If you connect to lnd with rpc or rest, you will have to make the client trust this certificate specifically. lnd automatically looks for the certificate in ~/.lnd/tls.cert, so if you are,running lncli as the same user as runs lnd, you will not have to worry about this, but if you start connecting to lnd from somewhere else, you will.

Macaroons

Macaroons are tokens to connect to lnd with specific rights. You will have to use these when you connect to lnd with either rpc or lnd. You will find them in ~/.lnd/data/chain/bitcoin/network, where network is testnet if you on the test network and mainnet if you run it with real bitcoins.

There are three standard macaroons generated

  • admin.macaroon is for all administrative purposes and give you all rights.
  • readonly.macaroon gives rights to querying the node for information, but can’t do any changes.
  • invoice.macaroon is a macaroon that gives enough rights to generate invoices and to check whether or not they are paid. It’s specifically made for giving the access rights a store that receives payments needs.

As with the certificates, you can delete them and have them recreated when lnd is started again.

The administrative, lncli, will know where to find them if you run it under the same user lnd runs, and on mainnet, but if you run it on testnet you can specify –network=testnet on the command line, and it will find it. You can also specify it with –macaroonpath=value if you run lncli on a different machine or as a different user than lnd.

 

Accessing lnd from outside the lnd machine

It is a good idea to harden the lnd box a bit, by letting it have its own firewall running locally. Most Linux distributions have an abundance of firewall software, so I can not cover all of this in this guide. Many Linux distributions comes with this firewall already enabled.

Before you worry about accessing it from outside world, it’s a good idea to test everything both from the local machine itself, but also from a machine on the same network. The telnet command can be used to try to connect to a specific port with telnet 1.2.3.4 9735. Replace with the IP addresses and ports you want to test connectivity for, of course.

Accessing lnd from the Internet

There is an abundance of network setups. Most home users will not have real IP addresses on their local network, but if you can assign it a static IP address on your local network – real or not – things becomes easier.

If you don’t want anyone to be able to connect to you, i.e. you want to open all channels yourself, you probably don’t need to do anything special for lnd traffic. If you want your node to be reachable and people to create channels to you, you need to make sure the node is reachable and announced on a public ip address on the lnd protocol port (usually 9735).

If you already run public services on Internet, I assume you know a bit about this, so I will in this guide assume you run on home network behind a router with NAT (network address translation). If not, parts of this information is still good.

There is a setting in lnd that might simplify things for you greatly if it works:

nat=true

If you have a local firewall on your machine, you need to allow UDP port 1900 from your router for UPnP to work.

With this setting, your lnd will try to use two techniques, UPnP and NAT-PMP, to talk to your router and have it open the port for you incoming. It will also tell lnd to announce the outside address of the router on the network. Now, it depends on router support, and it will not work if you have two routers doing NAT, i.e. an ISP router doing NAT plus your own router doing NAT in addition. There’s no harm in trying it. If it does not work, either your router doesn’t support it, or it isn’t enabled in the router. Router specific configuration is a bit outside the scope of this guide, so you’ll have to consult documentation about your own router to get more information about this in your case.

If this setting doesn’t work, you’ll have to do it manually. You’ll need to go into the router configuration and enable traffic on port 9735 incoming, and forward it to the IP address of your node. This is the reason I recommended making sure your node has a static IP on the internal network at least. In this case, you additionally need to find out what IP address is on the outside of the router. The easiest is to run a command from the inside to a page that reports what IP address it saw. The site https://ipinfo.io/ip reports only this ip address and is easy to use from a script. If your external IP does not change, you might get away with specifying it in the configuration file directly:

externalip=1.2.3.4

If it is dynamic, that is likely to change, you might decide to use a script to find this information, and have lnd use this information when it starts.

This is the method Stadicus has used in his guide https://github.com/Stadicus/guides/blob/master/raspibolt/README.md

Here is the script he is using, that is meant to be run in the background. It will check each 10th minute and write the IP address to the file /run/publicip.

#!/bin/bash
# getpublicip.sh
echo 'getpublicip.sh started, writing public IP address every 10 minutes into /run/publicip'
while [ 0 ]; 
 do 
 printf "$(curl -vv ipinfo.io/ip 2> /run/publicip.log)\n" > /run/publicip;
 sleep 600;
done;

Once you have found this information, you need to make sure that lnd has the information when it starts, for examply by starting lnd with the –externalip argument. You can have it use this information directly from the file:

lnd --externalip=`cat /run/publicip`

Stadicus have  a bit more sophisticated setup that you might decide to follow.

Talking to lnd from the Internet

You might need to also talk to lnd with REST or RPC, for example if you want to accept LN payments on an external site. In this case, you need to forward the REST and/or RPC port, per default 8080 and 10009 to your internal node. I would recommend using a domain name for lnd. If you have a static ip, you might get away without it, but if your ip address changes, things will be easier with a domain name.

If you decide to connect to lnd with an ip-adress, you need to add a statement in the lnd configuration file to add this IP adress to the certificate:

tlsextraip=1.2.3.4

If you decide to go with connecting to a domain, you need to use another statement:

tlsextradomain=your.domain.name

Then, you need to delete and recreate the certificates as described earlier in the guide.

The reason I recommended a certificate if you are on a dynamic IP adress is that then you don’t have to recreate the certicificate if your ip address changes.  You can instead opt for using a free service to register a domain name you can update automatically if your ip address change, for example https://www.noip.com/free.

You can also connect to a domain/host name not registered in DNS, but then you will need to specify it in /etc/hosts of the machine that connects to your lnd, by adding a line which looks like this:

1.2.3.4   your.host.name

There is an abundance of ways to specify how to connect to your lnd, so it is not possible to cover them all in this guide. What you will generally have to do, though is:

  • Specify the ip address/domain and port (i.e. 8080 for REST and 10009 for RPC) to connect to.
  • Provide it with your tls.cert
  • Provide it with an appropriate macaroon.

The macaroon you generally want if you want to accept payments is the invoice macaroon. The admin macaroon gives the site all rights, and this might not be what you want. The readonly macaroon gives access to information only, and you will not be able to create invoices so you can accept payments. This is an area there is likely to be changes, and there is also work under way to make it possible to create your own macaroons, however most likely the above will be enough to get you started.

Conclusion/comments

Running services on the Internet is not an easy task. With this guide, I have intended to give enough information on how to configure lnd and the network to use lnd on Internet. I would love to have comments, either in the comment section or in a mail to vegard@engen.priv.no.

I would especially be interested in corrections, and there is no stupid questions. I have been trying to write a guide people who don’t know too much about networking can use, but I might have left out things that you feel need more description/clarification.

12 thoughts on “Guide to Networking for LND

  1. Thank you so much. I have been trying to figure this out for weeks. I will try your guide later. While I was trying to figure it out someone suggested I use an ssh tunnel to forward the ports. Would you recommend that? If so could it be added to your guide? I couldn’t figure it out.

    1. An ssh-tunnel to forward the port is a good idea. A couple of use-cases.

      1) You don’t expose the IP-adress of your home network. Presumably, a cloud provider has better anti-DDOS measures.
      2) You don’t need to worry if your IP-adress at home changes (though you would, in that case, have to restart the ssh-tunnel).

      You would have to add some mechanism to ping/monitor the SSH tunnel, and
      tear it town and set it up again if that should happen. Not sure it belongs in a beginners guide, but I’ll see about it.

  2. Are macroons required for Talking to lnd from the Internet? I have no-macaroons=true specified in my lnd.conf file.

    1. macaroons have nothing to do with the LN protocol, only the administrative commands through REST or RPC.

      In my opinion, it’s always a bad idea to run without macaroons.

  3. nice summary.
    I have a situation when something works fine, but I don’t understand why. I’m using ZAP and that’s using the cert and macaroon to connect to remote LND via gRPC. In lnd.conf I set:
    rpclisten=0.0.0.0:10009
    listen=0.0.0.0:9735
    externalip=1.2.3.4:9735
    But I didn’t set tlsextradomain or tlsextraip.
    Why does the certificate works regardless?

    1. It will automatically add all the IP addresses on all network interfaces.

      As long as you are calling it via one of those, you are good. If you needed to take for example NAT into account, you would have to use tlsextrip to have it add the NAT address too.

Leave a Reply

Your email address will not be published. Required fields are marked *