Skip to content

tor Setup & Usage

shermand100 edited this page Apr 14, 2021 · 6 revisions

How PiNode-XMR implements tor usage.

This Wiki will show PiNode-XMR's (Debian based system) configuration and implementation of

  • tor installation
  • tor hidden service & SOCKS tunnel setup
  • tor service start/stop
  • Monerod commands
  • Systemd config

tor installation

tor and related services are installed with sudo apt install tor torsocks nyx -y

This installation generates the keys and address for your hidden service. Your address is held at, and can be viewed with sudo cat /var/lib/tor/hidden_service/hostname.

tor hidden service & SOCKS setup

During install from the PiNode-XMR menu the hidden service config /etc/tor/torrc file is downloaded from the appropriate repository (Devolopent,Raspbian or Armbian - user selected) and moved into location for you.

The key elements of this config file are:


SOCKSPort 9050 # Default: Bind to localhost:9050 for local connections.

ControlPort 9051

HashedControlPassword 16:AC98E29BEB12067860AB94CC2C5262F6AA3153863BCB03B8B6FE8A82B4

HiddenServiceDir /var/lib/tor/hidden_service/

HiddenServicePort 18080 127.0.0.1:18080

HiddenServicePort 18081 <DEVICE_IP>:18081


The SOCKSPort will be used for our outgoing transactions

ControlPort is for the NYX (previously known as ARM) tor monitoring service. This can be used to view errors, logs and bandwidth usage among other tools. The HashedControlPassword is the hash of PiNodeXMR used to access NYX.

HiddenServiceDir is where keys and hostname/addresses are kept

HiddenServicePort is telling the hidden service that connections to your .onion at port 18080 should be re-directed to 127.0.0.1:18080 (and respectively 18081 to you local RPC bound port of 18081). This will later be configured as our RPC addr:port allowing external RPC connections via our .onion hostname. During the tor install script and the PiNodeXMR update script the command sudo sed -i "73s/.*/HiddenServicePort 18081 $(hostname -I | awk '{print }'):18081/" /etc/tor/torrc is run to insert your local device IP into the /etc/tor/torrc file. Each time it is run it replaces line 73 to overwrite with a the latest IP if required.

*Note: Ideally your PiNodeXMR should be set a static local IP from your router, (not subject to DHCP lease times). This will prevent your PiNodeXMR from changing IPs and inadvertently preventing hidden service routing.

Monerod

That first bit is simple with very few deviations from what tor ships as default.

Monerod is a little more complex, I will share below a simplified (all non-tor flags removed, --in-peers, --max-log-files etc) command used to start the 'tor-ified' node, then I'll simplify and explain each component:

DNS_PUBLIC=tcp TORSOCKS_ALLOW_INBOUND=1 ./monero/build/release/bin/monerod --p2p-bind-ip 127.0.0.1 --no-igd --rpc-bind-ip=<device-ip> --rpc-bind-port=18081 --tx-proxy tor,127.0.0.1:9050 --anonymous-inbound <my-hidden-service.onion>,127.0.0.1:18080 --confirm-external-bind --rpc-login=<username>:<password> --rpc-ssl disabled --non-interactive --add-peer <addr>.onion:<port>

With reference to monerodocs.org/interacting/monerod-reference and github.com/monero-project/.../ANONYMITY_NETWORKS.md

  • DNS_PUBLIC=tcp - Here left blank so by default monerod will populate with it's own list of DNS providers. You can specify your preferred ones in the format of DNS_PUBLIC=tcp://1.1.1.1.

  • TORSOCKS_ALLOW_INBOUND=1 - Tell torsocks to allow inbound connections.

  • ./monero/build/release/bin/monerod - The path to monerod. In this case monerod has been compiled from source using USE_SINGLE_BUILDDIR=1 make

  • --p2p-bind-ip 127.0.0.1 - Network interface to bind to for p2p network protocol. Default value 0.0.0.0 binds to all network interfaces. For clearnet this is what you want, however you must change this if you want to constrain binding, in our case to configure connection through Tor via torsocks.

  • --no-igd - Disable UPnP port mapping on the router ("Internet Gateway Device"). Add this option to improve security if you are not behind a NAT (you can bind directly to public IP or you run through Tor).

  • --rpc-bind-ip=<device-ip> - IP for RPC to listen on. This will allow local (LAN) wallet connections to broadcast transactions via tor, without the need for the wallet to be torified.

  • --rpc-bind-port=18081 - TCP port to listen on. By default 18081 (mainnet). Elsewhere in the PiNode-XMR system I let users set their own RPC port. For now, running as a tor node this is fixed to 18081 as our hiddenservice config (torrc) is also pointing to here. A custom point would break this link.

  • --tx-proxy tor,127.0.0.1:9050 - Outgoing transactions are sent through tor via SOCKS at this address:port. You may specify a maximum number of outgoing connections (for example 10) with --tx-proxy tor,127.0.0.1:9050,10

  • --anonymous-inbound - my-hostname.onion,127.0.0.1:18080 - Inbound Monerod settings for p2p network synchronisation (not RPC)

    • my-hostname.onion - Allow inbound monerod connections to your hidden service via hostname (as produced by sudo cat /var/lib/tor/hidden_service/hostname) and the hidden service port specified in /etc/tor/torrc
    • , - Then send connections to local monero-daemon found at...
    • 127.0.0.1:18080 - The localhost of the running monerod P2P with port 18080.
  • --confirm-external-bind - Confirm you consciously set --rpc-bind-ip to non-localhost IP and you understand the consequences.

  • --rpc-login=<username>:<password> - Restricts access to RPC port by username:password authentication.

  • --rpc-ssl disabled - ssl certificates aren't used for node -> wallet authentication yet.

  • --non-interactive - Do not require tty in a foreground mode. Helpful when running in a container. By default monerod runs in a foreground and opens stdin for reading. This breaks containerization because no tty gets assigned and monerod process crashes. PiNode-XMR runs monerod in a container to use tor via a systemd service in the background. Systemd config mentioned later.

  • --add-peer Monerod doesn't by default come with knowledge of any other tor nodes in the network and cannot find them itself. --add-peer informs monerod that another tor node exists and that it should contact it on it's addr.onion:port. If connection is successful the added peer will share it's list of tor nodes it is aware of with your node, building an ever growing list of peers. In theory. Peers are stored in /.bitmonero/p2pstate.bin. You can specify many peers as once your specified "app seed peer" has been loaded into p2pstate.bin you may change it to another, on next node start this new seed peer will be added to p2psate.bin.

Systemd


[Unit]

Description=Monero Tor Node

After=network.target

[Service]

User=pinodexmr

WorkingDirectory=/home/pinodexmr/

SuccessExitStatus=143

Type=simple

Restart=on-failure

ExecStart=/bin/bash /home/pinodexmr/monerod-start-tor.sh

RestartSec=30

[Install]

WantedBy=multi-user.target


PiNode-XMR uses systemd to initiate a monerod start script. This differs from how systemd is used in other examples.

I have simply removed the enviroment variables from the systemd.service file and put them in the monerod start script instead, with the addition of SuccessExitStatus=143 to prevent the service exiting in a 'failed' state.

Restart=always changed to Restart=on-failure

I hope that adds some context to how tor and monerod can be used together. However as always examination, testing and feedback on these settings is greatly appreciated.

Wallet connection

You can connect to your PiNode-XMR via it's unique .onion service address using a torrified wallet ( an example on Android would be using "Orbot" to wrap "Monerujo" wallet traffic ).

Connection can be made on port .onion:18081 using RPCusername and RPCpassword as normal.

This connection is very simple and didn't cause much issue on testing. However once the tx sits in PiNode-XMR mempool it requires good tor peer connections in order to broadcast. I took me a while to get a good seed peer for the tx to be broadcast and get included in a block. If this happens to you, stop the node, add a new seed peer and restart the node. Leave for 20 minutes, if it still fails to get included repeat this process.

Seed peers you specify that fail connections are still held in p2pstate.bin and will be periodically checked by the node for connectivity. The key to success may be to get several seed nodes into this list by the method specified above.