When the average person hears the term "cryptocurrency," they may assume that every aspect of the protocol is encrypted and thus completely private, allowing users to safely remain anonymous. This is most certainly not the case, and privacy-conscious users will need to take additional steps to protect themselves. One particular threat vector that Bitcoin and Lightning users should consider is that of the network observer. By sending data in the clear via default IPV4 and IPV6 networks, sophisticated entities can look for patterns to correlate your financial activity and they can use the IP address of your machine to probe it for weaknesses and attempt to learn your location and identity.
How are we to protect ourselves?
- By sharing as little data with third parties as possible.
- By ensuring that all of the data our nodes send and receive is routed over a privacy preserving network.
Full nodes offer the best privacy model when it comes to preventing data leaks. With a full node, you download all the blockchain data and only query for addresses / transactions locally — network observers can’t see what you’re interested in.
But if we run our own nodes, we still have to share data (such as for sending transactions) with peers on the network - how do we protect ourselves from them? Enter Tor. Tor Project maintainers say that you can think of what Tor does as "using a twisty, hard-to-follow route in order to throw off somebody who is tailing you — and then periodically erasing your footprints." Your traffic gets intermingled with the traffic of other Tor users. As the global Tor userbase grows, the path gets twistier.
In order for you to make networked services (anything from a web server to a peer to peer node) work on Tor, you need to create a hidden service that acts as a bridge from the Tor network to the specific software running on your machine.
NOTE: after running a tor-only Lightning node for a year, I have come to believe that doing so results in significantly decreased routing performance and available inbound liquidity. Be aware that if your goal is to be a highly trafficked routing node, going tor-only makes it far more challenging.
As of Bitcoin Core 0.12, a node will automatically run a hidden service if it is able to connect to a local Tor daemon. However, we have to make sure that a few things are configured correctly so that the node and daemon can talk to each other. As such, back in 2016 I first looked into how to get my Bitcoin nodes operating on the Tor network and I wrote this guide:
The above guide will get you most of the way there, though additional configuration needs to be made in order to disable communication via IPV4 and IPV6. When you set up Bitcoin Core to power a Lightning node you'll want to have the following lines in your bitcoin.conf file:
# [core] # Maintain a full transaction index (improves lnd performance) txindex=1 daemon=1 disablewallet=1 maxuploadtarget=1000 # [rpc] # Accept command line and JSON-RPC commands. server=1 rpcauth=[redacted]:[redacted] # [zeromq] # Enable publishing of transactions to [address] zmqpubrawtx=tcp://127.0.0.1:28333 # Enable publishing of raw block hex to [address]. zmqpubrawblock=tcp://127.0.0.1:28332 # Privacy bind=127.0.0.1:8333 # Allow DNS lookups for -addnode, -seednode and -connect values. dns=0 # Query for peer addresses via DNS lookup, if low on addresses. dnsseed=0 # Specify your own public IP address. externalip=[redacted].onion # Use separate SOCKS5 proxy to reach peers via Tor onion=127.0.0.1:9050 proxy=127.0.0.1:9050 proxyrandomize=1 # Only connect to peers via Tor. onlynet=onion listenonion=1 listen=0 # helps bootstrap peers for initial sync addnode=6u2hzskqwebn4ldjhobi73kch5us4cc6cssm7pnatnyumvci7btdmhqd.onion addnode=jnuehir3ownmhnrceltatxz6vvznwgw5hlz3dgk6kjlrop5rq7tykeqd.onion addnode=6nwabl7vks2jieb74akgjmariirzchzeionxdwthsgjsenbfr3qgqzad.onion addnode=2hz64d5zd7f3vznpbnfpicbzsotp5bjr742qeyqkcgghxah4dck543qd.onion addnode=fpmxqxvjhexojvyeqrr7oles6r6bztt2e2i5ltwtdorpwqw2zoeqi2qd.onion addnode=e5l6pazznjdfozuen3763bkde4njorniffxq7xg35znm3344oitjwfad.onion addnode=m4gtrhkde7abevhmt2cbdxw5eqcqnpoekjseaunq45p6ithquonl54qd.onion addnode=mrlyeqavp5ufbsnk37tr6pmbnlr74e4v3xtlx4elmhrb3hfrfpuiz4yd.onion addnode=t2ui2nl7hm63qqmwot5rwzegh42mhuzpmodxmxzb6dc7ckovkyiejiad.onion addnode=52cawcafaswleiedcprfs4y7bp3vn4qaknjl3j64bcjunixryjxpozyd.onion addnode=567ckf7gxoxoun5ympwwphcvzxtc2usqlvu2zggi3b5neznub77gwaid.onion addnode=uwxxxv3alapmwijos7vtgv7ueuoffyu6ev62ttbpt5cvtkq7p56725ad.onion
Note that the two lines with [redacted] info need to be set dynamically by you.
The rpcauth value should be set by running this python script.
You can find your Bitcoin hidden service address that you should set as the externalip by running this command while your node is running: bitcoin-cli getnetworkinfo | grep \"address
Now you'll just have to wait for bitcoind to finish syncing. This will take at least a few days, depending upon a variety of factors.
LND is similarly smart like Bitcoin Core in that it can talk to the Tor daemon; you just need to tell it to do so. I suggest the following lnd.conf parameters:
[Application Options] minchansize=100000 listen=localhost accept-keysend=1 allow-circular-route=1 watchtower.active=1 # Mark unpayable, unpaid invoices as deleted gc-canceled-invoices-on-startup=1 gc-canceled-invoices-on-the-fly=1 # Avoid historical graph data sync ignore-historical-gossip-filters=1 # gRPC socket binding rpclisten=0.0.0.0:10009 restlisten=0.0.0.0:8080 # Avoid slow startup time sync-freelist=1 # Avoid high startup overhead stagger-initial-reconnect=1 # Auto regenerate RPC TLS certificate tlsautorefresh=1 # Do not include IPs in the RPC TLS certificate tlsdisableautofill=1 [Bitcoin] bitcoin.active=true bitcoin.mainnet=true bitcoin.node=bitcoind bitcoin.minhtlc=1000 bitcoin.basefee=1000 bitcoin.feerate=100 [Bitcoind] bitcoind.rpcuser=[redacted] bitcoind.rpcpass=[redacted] bitcoind.zmqpubrawblock=tcp://127.0.0.1:28332 bitcoind.zmqpubrawtx=tcp://127.0.0.1:28333 bitcoind.estimatemode=ECONOMICAL [routerrpc] # Set default chance of a hop success routerrpc.apriorihopprob=0.5 # Start to ignore nodes if they return many failures routerrpc.aprioriweight=0.75 # Set minimum desired savings of trying a cheaper path routerrpc.attemptcost=10 routerrpc.attemptcostppm=10 # Set the number of historical routing records routerrpc.maxmchistory=10000 # Set the min confidence in a path worth trying routerrpc.minrtprob=0.005 # Set the time to forget past routing failures routerrpc.penaltyhalflife=6h0m0s [tor] tor.active=true tor.v3=true tor.streamisolation=true
Note that bitcoind.rpcuser and bitcoind.rpcpass should be the values that you fed into the rpcauth python script when configuring Bitcoin Core, not the output value of the script.
LND has a ton of config options; you may wish to browse the sample lnd.conf here. Alex Bosworth also has some fairly in-depth recommendations for configuring your machine.
Be sure to set automatic off-site channel backups for disaster recovery! Believe me, you'll want to avoid having to perform a wallet recovery on corrupted data. I've written extensively about some of the edge cases I've run into.
Here's a simple utility script that you can tweak to send channel backups to another machine via any bash command you can conjure up (such as scp.) Alternatively you can use this script that I found and modified to automatically back up your channels to Dropbox.
Mobile Node Control via Zeus
Getting your nodes set up is great, but what if you want to actually use them to make a payment when you're out on the town and not lugging a laptop around?
At time of writing it appears that Zeus is the only mobile app available on both iOS and Android that supports talking directly to remote LND, Eclair, and c-lightning nodes.
While it's possible for Zeus to talk to your node via IPV6, we might as well stick to Tor! You'll first want to create a separate Tor hidden service for lnd's REST interface.
sudo vim /etc/tor/torrc
Add these two lines:
HiddenServiceDir /var/lib/tor/lnd_rest/ HiddenServicePort 8080 127.0.0.1:8080
Restart tor and find your new onion service hostname that you'll paste into Zeus.
sudo service tor restart sudo cat /var/lib/tor/lnd_rest/hostname
Create a macaroon for authentication.
/path/to/lncli bakemacaroon address:read address:write info:read info:write invoices:read invoices:write message:read message:write offchain:read offchain:write onchain:read onchain:write peers:read peers:write signer:generate signer:read
This command will output a bunch of hex that you'll need to paste into Zeus. You'll also want to make sure you have the "use Tor" option checked in the Zeus config.
Now you should be all set!
But one more thing...
We are still in the early days of understanding best practices for managing Lightning Network liquidity; I expect that entire books will be written on the subject. You should learn the basics, however. I'd suggest joining some of the discussion forums to stay up to date on best practices.
There are several tools available to help manage liquidity across your channels.
There are plenty of liquidity management functions in the Balance of Satoshis tool; if you read through the documentation you'll find some automation examples under the "Linux Fu" section.
Just remember: a balanced channel is a useful channel!