How To Sync an Ethereum Node via Tor

Push Ethereum further towards uncensorability!

Johannes Pfeffer
Dec 18, 2019 · 4 min read

Why?

Sycing an Ethereum node over the Tor network is not principally about privacy. It’s about censorship resistance.

We have recently seen that countries will block ethereum explorers and that dApp websites will block countries. Russia want’s to be able to decouple it’s internet from the rest of the world completely. I’m sure we will also see blocked Ethereum traffic in the near future, somewhere. For instance, using deep packet inspection, the UDP traffic that Ethereum nodes produce when discovering each other can be heavily impaired or even blocked.

When it’s possible to sync and run a node over the Tor network, a project to defend yourself against tracking and circumvent censorship, this problem is mitigated and abstracted to the problem of being able to access Tor itself. While that cannot be taken for granted — it is another layer for which many solutions are provided, discussed and will continue to emerge in future.

When you run your own Ethereum node you can point local instances of dApps (decentralized Ethereum apps) directly to it an reach a level of independence from central infrastructure unknown to the Web2.

You can also run your own block explorer and browse the Ethereum blockchain itself

How?

The biggest obstacle to overcome is peer discovery. When directly connected to the internet, Ethereum nodes use UDP packets to discover each other, starting from a set of boot nodes hardcoded into the client. Tor, however, does not support UDP, so when you start a sync, nothing happens, no peers are ever discovered.

Manually “discovering” nodes

Consequently we need another way of providing our node with peers. Luckily there is one.
I have done this with Geth, but there are similar approaches for the other Ethereum clients, as well. There is a standard of how Ethereum clients identify each other, it’s a type of URI, but instead of http:// it uses enode://:

enode://[signature]@[host]:[port]

First, you need to find sources for nodes that you feel you can trust.

  • You can call your friends and ask them to send you their enode-URL

It’s important to do this right — in this step you select nodes you trust. If you get tricked into adding mostly compromised nodes, your Ethereum client can be manipulated into following a fake chain.

When you have about 10-20 of these URLs together, put them in a file called static-nodes.json like so:

static-nodes.json

Place the file in ~/.ethereum/geth/ or wherever you store your chaindata.

Set up Geth, Tor and and routing

For the sake of simplicity this guide assumes Ubuntu. But for other distros the process should be similar.

Now that you have Geth and Tor, we need to make sure that the Geth traffic is routed through Tor. To be as sure as possible that nothing leaks through the normal internet, I recommend to pass ALL traffic through Tor. But you can also go a different route if your machine is not a dedicated node.

toriptables2 is a convenient tool that sets your iptables (a kind of firewall/router for linux) so that all traffic must go through the Tor network.

Make sure you have python and git installed for the next step.

git clone https://github.com/ruped24/toriptables2.git
cd toriptables2
sudo ./toriptables2.py -l
# use ‘-f’ to deactivate

Now you should check that really all traffic goes through Tor. Start by visiting the official Tor Check and continue with other checks, e.g. the ones listed here.

Start Geth

  • Make sure again that your ~/.ethereum/geth/static-nodes.json is correctly placed

Now you can finally start the sync over Tor:

geth --syncmode fast --nodiscover

You can choose another syncmode — but since you decided to trust a set of nodes anyways, it shouldn’t make much of a difference. --nodiscover switches off the built-in node discovery because it wouldn’t work.

Voilà! Your node should start sync now! Expect 2–5 days to fully sync, depending on the state of the Tor network, your internet connection and your hardware.

Adding more nodes

One remaining problem is that you’re now operating from a static set of nodes. Some of these nodes may be unreliable or go offline over time. You can always stop Geth, update your static-nodes.json file and restart Geth. However, there also is a way to add new nodes while Geth is running:

geth --exec "admin.addPeer('[here goes your enode-URL]')" attach

Run this command from another terminal and it will attach to the main Geth instance and execute the addPeer() command. Feel free to automate this if you have some script-foo. Please let me know any of any work in this direction!

DNS-based node discovery (EIP-1459)

“Manual peer discovery” is an important approach to running an uncensorable Ethereum client because it gives you full control over the set of peer nodes. But it is also very inconvenient and adds the additional risk of being tricked into adding compromised nodes.

Luckily there is an effort started by Felix Lange and Péter Szilágyi to add a UDP-less discovery mechanism to Ethereum nodes: EIP-1459. The mechanism is already implemented for Geth, all that’s left is testing and setting up the necessary DNS infrastructure. Péter says that it will likely go into a Geth release in early 2020. Parity also has done some some work towards it.

When DNS-based node discovery is supported by the clients it should be possible to just run Geth over Tor, with no additional work needed.


I’d appreciate it if you subscribe to me here on Medium and follow me on Twitter. Thanks!


Thanks to @tzapulica and @mysticryuujin for pointing me toward this solution.

Johannes Pfeffer

Written by

blockchain + life

More From Medium

Related reads

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade