How to use your Zcash full node with your mobile wallet using Tailscale

Zcash is great! Full nodes can't run on mobiles, and mobile wallets rely on a data source. There are public data sources, but if you already run your own full node, you can use it to get more privacy!

The next question is how to connect to your full node from your mobile phone. There are many ways to go about this, but the easiest and most reliable option is Tailscale.

(The post below has a bunch of TODOs, because I put this draft together in August last year and then ran out of time to finish it, but I want to get the information up somewhere. If you care about specific TODOs, ping me and I'll fill them in!)

Configure your full node

By default, the full node implementations do not build and maintain the extra indexes necessary for running a lightwalletd server. If you haven't done so already, you'll need to configure your full node.

If you already had a full node running without these extra indexes, you'll need to reindex before you can use them. This will take a while! For zcashd, restart it with the -reindex flag (only once; if you include this on every restart, it will reindex from scratch each time).

Set up a Tailscale network

Personal accounts are free, sign up with e.g. a Gmail account.

Once you have a Tailscale account:

  • Install Tailscale on the server you are running your full node on, and that you will run lightwalletd on. Technically you can run these on separate servers, but we'll assume they are on the same server here.
  • Install the Tailscale app on your phone, and log in. I tested this on an Android phone, but iOS should work very similarly.
  • Enable the Tailscale app on your phone, so it's running as your VPN.

Run lightwalletd

TODO something something Docker.

To run it directly, first install Go. Then:

$ git clone https://github.com/zcash/lightwalletd.git
$ cd lightwalletd
$ make
$ ./lightwalletd --no-tls-very-insecure --zcash-conf-path /path/to/zcash.conf --data-dir . --log-file /dev/stdout

This will run it in the foreground. TODO install screen and run the command in the background.

Something something need to ensure this stays up. If the server restarts, blah blah do whatever you're doing to restart zcashd to also rerun this command.

Expose lightwalletd via Tailscale

Tailscale Serve is a simple way to expose any service running on a machine in your Tailscale network, to any other machine in your network. In particular, it handles HTTPS for you. This is important as most Zcash mobile wallets (in particular, Zashi) require HTTPS.

Warning: this will record a URL containing the name of your server and your tailnet subdomain in a public ledger (due to how HTTPS certificates work).

By default lightwalletd listens on 127.0.0.1:9067. We can expose this by running tailscale serve --bg --https=9067 localhost:9067 on the server:

$ sudo tailscale serve --bg --https=9067 localhost:9067
Available within your tailnet:

https://server-name.tail12345.ts.net:9067/
|-- proxy http://localhost:9067

Serve started and running in the background.
To disable the proxy, run: tailscale serve --https=9067 off

The HTTPS URL that it printed out (https://server-name.tail12345.ts.net:9067 in the example above) is now ready to be used:

Configure your Zcash mobile wallet

Zashi makes this easy:

  • Go to "Advanced" in settings, then click "Choose a server".
  • Select "custom".
  • In the box that appears, type the domain name and port from the HTTPS URL that Tailscale printed out (server-name.tail12345.ts.net:9067 in the example above).
  • Click "Save".

If Tailscale is running correctly on your phone, Zashi will check that it is able to connect to your server.

Non-Tailscale connection options

TODO: Clean up the following.

The main central service you depend on with Tailscale is its control server, which manages ACLs, permissions etc. for devices in your Tailnet (the actual traffic between your devices is not visible to Tailscale due to its use of WireGuard). If you like this approach but don't want to depend on Tailscale's control server, try Headscale!

Some wallets support non-HTTPS connections (which would be insecure for any normal usage, but in this specific Tailscale case would be fine). You need to configure lightwalletd to listen to connections from its Tailscale IP instead of just localhost, but then you can use http://server-name:9067 (if you have Tailscale's MagicDNS enabled) or http://server-tailscale-ip:9067 instead.

Some wallets support connecting to lightwalletd servers over Tor (via exit nodes). If those wallets also support connecting to lightwalletd servers on onion addresses, then you can host your lightwalletd server above behind a Tor onion server to make it reachable. This has the downside that you're paying the cost of onion routing (higher latency, lower bandwidth and reliability) but not getting the benefit (you operate both ends of the pipe, and any targeted adversary that knows your devices could trivially run timing correlation attacks between them, so there's little point in hiding the fact that your devices are communicating amongst each other).