Monero Node (Qubes-Whonix)

Bu sayfanin TURKCE cevirisi var!

Objective

In this guide I will show you how to install and setup a Monero node (aka, "a Monero daemon", or, "monerod") in a Qubes-Whonix AppVM.

An AppVM (also known as a "qube") is single virtual machine that you run inside QubesOS. In QubesOS, you use virtual machines to confine and isolate your digital activities. For example, you can have an email qube in which you run the Thunderbird program and check your emails. You can have another qube in which you run your office programs. And yet another qube that you run a Monero node. This last use case is the topic of this guide.

Specially, Whonix qubes in QubesOS route all the network connections through Tor network. That way, you don't leak your geographic IP address to the websites you visit or the online services you use. For more info, check out whonix's website, it is a great OS.

At the end of you following this guide, you will have:

  • a running monero node
  • a monero node that's completely behind the Tor network, preventing your local internet providers from discerning whether you are running Monero or not

In this guide QubesOS 4.2 (which runs Whonix 17) is used for demonstration.

Note: throughout the guide I use the terms "hidden server" and "hidden service" interchangeably.

Setup

Get the software

Create a whonix qube

On QubesOS, open the Qube Manager window. Click on New Qube button upper left corner.

Create new qube
Create new qube

On the "Create new qube" window, fill the details as follows:

1. Name and label: anon-monerod-who17. Naming convention: "anon" is for hinting at the fact that this qube will be completely behind Tor network. "monerod" is for reminding us that this qube will be used for running the monero daemon (aka, "monerod"). "who17" is for signaling to us that this is a whonix-17 qube.

2. Color: Pick red for color coding your anonymous qubes.

3. Type: Keep it as AppVM (persistent home, volatile root) option.

4. Template: Select whonix-workstation-17 option.

5. Networking: Select sys-whonix option.

6. Launch settings after creation: Check this option.

Click OK.

You will see the specs window for your newly created anon-monerod-who17 qube as shown below:

New qube settings
New qube
settings

Here, bump up the Private storage max size to 250 GB. Currently the Monero blockchain size is at 200 GB, so you definitely need more than 200 GB of storage space for your monerod qube.

Click Apply and then OK.

Open your Qube Manager window again. On the search bar, enter monerod, and locate your newly created qube. Select that qube, and click on Start/Resume button.

Download monerod software

Start torbrowser inside your monerod qube. Go to https://getmonero.org/downloads/#cli OR its onion address http://monerotoruzizulg5ttgat2emf4d6fbmiea25detrmmy7erypseyteyd.onion/downloads/#cli

There, click on the Linux 64-bit link to start the download. After the download completes, make sure you move the downloaded files to your home directory.

In this guide, we will use the command line to download the monerod, its hashes and the cryptographic key files. Open a terminal window in monerod qube, and enter the following command:

$ scurl-download 'http://dlmonerotqz47bjuthtko2k7ik2ths4w2rmboddyxw4tz4adebsmijid.onion/cli/monero-linux-x64-v0.18.3.3.tar.bz2' 'http://monerotoruzizulg5ttgat2emf4d6fbmiea25detrmmy7erypseyteyd.onion/downloads/hashes.txt' 'https://raw.githubusercontent.com/monero-project/monero/master/utils/gpg_keys/binaryfate.asc'

We are using the download links for the monero release v0.18.3.3. Make sure to adjust the download links according to the newest release versions of the day; or, simply visit the monero's official website links which are mentioned above, and download the files inside the tor browser.

Verify the downloaded monerod software

Import the software signing key:

$ gpg --import binaryfate.asc

On your terminal, you should see the following output. Here, the key fingerprint is 0xF0AF4D462A0BDF92. Verify that you have the same output on your terminal.

gpg: key 0xF0AF4D462A0BDF92: 2 signatures not checked due to missing keys
gpg: /home/user/.gnupg/trustdb.gpg: trustdb created
gpg: key 0xF0AF4D462A0BDF92: public key "binaryFate <binaryfate@getmonero.org>" imported
gpg: Total number processed: 1
gpg:               imported: 1
gpg: no ultimately trusted keys found

After importing the signing key, we can verify the signature:

$ gpg --verify hashes.txt

You should see the following output:

gpg: Signature made Sun 31 Mar 2024 01:49:15 PM UTC
gpg:                using RSA key 81AC591FE9C4B65C5806AFC3F0AF4D462A0BDF92
gpg: Good signature from "binaryFate <binaryfate@getmonero.org>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 81AC 591F E9C4 B65C 5806  AFC3 F0AF 4D46 2A0B DF92

Depending on your gnupg config, you might see more or less information on your terminal. The only thing you must see on your terminal output is the following line:

gpg: Good signature from "binaryFate <binaryfate@getmonero.org>" [unknown]

The warning in the output is just informing you that you do not know whether the key you just imported indeed belongs to the "binaryFate" person. In an ideal world, you would meet binaryFate in one of the MoneroKons (or MoneroTopias), pull out your computer, show him the key fingerprint and get him to tell you, "Yes, I am binaryFate, and that fingerprint belongs to my signing key." In a lesser ideal world, you can ask whether other monerobros have the same key fingerprint for this binaryFate person on monero.town, /r/Monero, or monero matrix rooms. For the purposes of this guide, we will trust this key fingerprint and its verification results.

Now verify the compressed archive file containing the monero program:

$ sha256sum -c hashes.txt --ignore-missing

You should see something similar:

monero-linux-x64-v0.18.3.3.tar.bz2: OK
sha256sum: WARNING: 17 lines are improperly formatted

The first line with the OK output is the important one, informing us that the downloaded file has a valid hash value.

Extract the compressed archive file

Now, extract the compressed monero binaries:

$ tar xvf monero-linux-x64-v0.18.3.3.tar.bz2

You should see the following output in your terminal:

monero-x86_64-linux-gnu-v0.18.3.3/
monero-x86_64-linux-gnu-v0.18.3.3/ANONYMITY_NETWORKS.md
monero-x86_64-linux-gnu-v0.18.3.3/LICENSE
monero-x86_64-linux-gnu-v0.18.3.3/monero-blockchain-ancestry
monero-x86_64-linux-gnu-v0.18.3.3/monero-blockchain-depth
monero-x86_64-linux-gnu-v0.18.3.3/monero-blockchain-export
monero-x86_64-linux-gnu-v0.18.3.3/monero-blockchain-import
monero-x86_64-linux-gnu-v0.18.3.3/monero-blockchain-mark-spent-outputs
monero-x86_64-linux-gnu-v0.18.3.3/monero-blockchain-prune
monero-x86_64-linux-gnu-v0.18.3.3/monero-blockchain-prune-known-spent-data
monero-x86_64-linux-gnu-v0.18.3.3/monero-blockchain-stats
monero-x86_64-linux-gnu-v0.18.3.3/monero-blockchain-usage
monero-x86_64-linux-gnu-v0.18.3.3/monerod
monero-x86_64-linux-gnu-v0.18.3.3/monero-gen-ssl-cert
monero-x86_64-linux-gnu-v0.18.3.3/monero-gen-trusted-multisig
monero-x86_64-linux-gnu-v0.18.3.3/monero-wallet-cli
monero-x86_64-linux-gnu-v0.18.3.3/monero-wallet-rpc
monero-x86_64-linux-gnu-v0.18.3.3/README.md

You can now remove the downloaded files from the previous step:

$ rm monero-linux-x64-v0.18.3.3.tar.bz2 hashes.txt binaryfate.asc

Which should leave you with the extracted monero directory:

$ ls -lah monero-x86_64-linux-gnu-v0.18.3.3
.rw-r--r--  10k user 12 Mar 16:46 ANONYMITY_NETWORKS.md
.rw-r--r-- 2.7k user 12 Mar 16:46 LICENSE
.rwxr-xr-x  16M user 12 Mar 16:46 monero-blockchain-ancestry
.rwxr-xr-x  14M user 12 Mar 16:46 monero-blockchain-depth
.rwxr-xr-x  15M user 12 Mar 16:46 monero-blockchain-export
.rwxr-xr-x  15M user 12 Mar 16:46 monero-blockchain-import
.rwxr-xr-x  11M user 12 Mar 16:46 monero-blockchain-mark-spent-outputs
.rwxr-xr-x  14M user 12 Mar 16:46 monero-blockchain-prune
.rwxr-xr-x  14M user 12 Mar 16:46 monero-blockchain-prune-known-spent-data
.rwxr-xr-x  14M user 12 Mar 16:46 monero-blockchain-stats
.rwxr-xr-x  14M user 12 Mar 16:46 monero-blockchain-usage
.rwxr-xr-x  10M user 12 Mar 16:46 monero-gen-ssl-cert
.rwxr-xr-x  28M user 12 Mar 16:46 monero-gen-trusted-multisig
.rwxr-xr-x  29M user 12 Mar 16:46 monero-wallet-cli
.rwxr-xr-x  30M user 12 Mar 16:46 monero-wallet-rpc
.rwxr-xr-x  25M user 12 Mar 16:46 monerod
.rw-r--r--  46k user 12 Mar 16:46 README.md

Install the software

Create monerod config file

Create a new file in /home/user/.config/monerod/monerod.conf and insert the following in it:

max-log-file-size=0
log-file=/dev/null
no-igd=1
disable-dns-checkpoints=1
p2p-bind-ip=0.0.0.0
p2p-bind-port=18080
out-peers=32
in-peers=32
tx-proxy=tor,${YOUR-SYS-WHONIX-IP}:9153,16,disable_noise
pad-transactions=1
proxy=${YOUR-SYS-WHONIX-IP}:9153
public-node=1
confirm-external-bind=1
rpc-bind-ip=127.0.0.1
rpc-bind-port=18081
rpc-restricted-bind-ip=0.0.0.0
rpc-restricted-bind-port=18089
rpc-ssl=disabled
disable-rpc-ban=1
db-sync-mode=fastest:async:250000000bytes
max-concurrency=2
fast-block-sync=0
block-sync-size=0

A few important points:

  1. We will use systemd journalctl for keeping logs of monerod. Therefore, you are using:
   max-log-file-size=0
   log-file=/dev/null
  1. We are syncing a FULL node, and we are doing that without relying on hardcoded block hash values. Monero developers offer you some checkpoints along the blockchain's history in the form of hardcoded block hashes. You can choose to trust that, and that will increase the speed of your initial block download. However, we choose not to rely on that, and instead, calculate the proof-of-work of all the past Monero blocks and verify them ourselves:
   fast-block-sync=0
  1. Whonix offers stream isolation for its tor proxy'ing. That improves the privacy of your monerod operation. Here, you must replace ${YOUR-SYS-WHONIX-IP} with actual IP of your sys-whonix qube. To see that value, open your Qube Manager, search for sys-whonix, and see the IP column. Enter the IP value you see there in place of ${YOUR-SYS-WHONIX-IP}. If you simply copy-pase the above config contents without doing this, your monerod will fail to operate.
   tx-proxy=tor,${YOUR-SYS-WHONIX-IP}:9153,16,disable_noise
   proxy=${YOUR-SYS-WHONIX-IP}:9153

Create monerod service file

We will use systemd to automate the running of monero daemon and also keep track of its logs. Create a systemd file:

$ systemctl --user edit --full --force monerod.service

Insert the following in the new file:

[Unit]
Description=Monero Full Node (Mainnet)
After=network.target

[Service]
Type=simple
ExecStart=/home/user/monero-x86_64-linux-gnu-v0.18.3.3/monerod --non-interactive --config-file=/home/user/.config/monerod/monerod.conf
Restart=on-failure
RestartSec=30

# Hardening measures
PrivateTmp=true
ProtectSystem=full
NoNewPrivileges=true

[Install]
WantedBy=default.target

A few important points:

  1. When running the service files under systemctl --user command, the systemd automatically assigns your user's User and Group to the running service. Therefore, adding User and Group directives to the service file is not needed. Indeed, adding them causes the systemd service to fail.

  2. The ExecStart= line points at /home/user/monero-x86_64-linux-gnu-v0.18.3.3/ directory. The name of this directory will change with as Monero gets new versions, like, [...]-v0.18.3.4[...] or [...]-v0.19.0.0[...]. As you update your monerod installation in the future, you must change the ExecStart= line in the service file above. You can edit your service file with the same command you used creating it.

Run the software

Start monerod

Reload the systemd daemon:

$ systemctl --user daemon-reload

Enable and start the monerod.service. Enabling it makes the service start by itself whenever the monerod qube boots up.

systemctl --user enable --now monerod.service

Checkout the service's status:

systemctl --user status monerod.service

You should see some output beginning with the following:

● monerod.service - Monero Full Node (Mainnet)
     Loaded: loaded (/home/user/.config/systemd/user/monerod.service; enabled; preset: enabled)
     Active: active (running) since Sat 2024-06-22 13:25:12 UTC; 42s ago

Congratulations. You have a running monero daemon. Now, all you need to do is wait for the full node to finish its sync. You can follow the syncing process of your monerod with the following command:

journalctl --user -fu monerod

Typical output will be like following:

Jun 22 13:41:35 host monerod[891]: 2024-06-22 13:41:35.254        I Synced 118020/3176974 (3%, 3058954 left)
Jun 22 13:41:35 host monerod[891]: 2024-06-22 13:41:35.532        I Synced 118120/3176974 (3%, 3058854 left)
Jun 22 13:41:35 host monerod[891]: 2024-06-22 13:41:35.939        I Synced 118220/3176974 (3%, 3058754 left)
Jun 22 13:41:36 host monerod[891]: 2024-06-22 13:41:36.214        I Synced 118320/3176974 (3%, 3058654 left)
Jun 22 13:41:37 host monerod[891]: 2024-06-22 13:41:37.412        I Synced 118420/3176974 (3%, 3058554 left)
Jun 22 13:41:38 host monerod[891]: 2024-06-22 13:41:38.132        I Synced 118520/3176974 (3%, 3058454 left)
Jun 22 13:41:44 host monerod[891]: 2024-06-22 13:41:44.817        I Synced 118620/3176974 (3%, 3058354 left)
Jun 22 13:41:45 host monerod[891]: 2024-06-22 13:41:45.045        I Synced 118720/3176974 (3%, 3058254 left)
Jun 22 13:41:46 host monerod[891]: 2024-06-22 13:41:46.863        I Synced 118820/3176974 (3%, 3058154 left)
Jun 22 13:41:47 host monerod[891]: 2024-06-22 13:41:47.054        I Synced 118920/3176974 (3%, 3058054 left)
Jun 22 13:41:47 host monerod[891]: 2024-06-22 13:41:47.237        I Synced 119020/3176974 (3%, 3057954 left)
Jun 22 13:41:47 host monerod[891]: 2024-06-22 13:41:47.429        I Synced 119120/3176974 (3%, 3057854 left)
Jun 22 13:41:47 host monerod[891]: 2024-06-22 13:41:47.608        I Synced 119220/3176974 (3%, 3057754 left)
Jun 22 13:41:47 host monerod[891]: 2024-06-22 13:41:47.790        I Synced 119320/3176974 (3%, 3057654 left)
Jun 22 13:41:47 host monerod[891]: 2024-06-22 13:41:47.983        I Synced 119420/3176974 (3%, 3057554 left)
Jun 22 13:41:49 host monerod[891]: 2024-06-22 13:41:49.848        I Synced 119520/3176974 (3%, 3057454 left)
Jun 22 13:41:50 host monerod[891]: 2024-06-22 13:41:50.061        I Synced 119620/3176974 (3%, 3057354 left)
Jun 22 13:41:58 host monerod[891]: 2024-06-22 13:41:58.027        I Synced 119720/3176974 (3%, 3057254 left)
Jun 22 13:41:58 host monerod[891]: 2024-06-22 13:41:58.224        I Synced 119820/3176974 (3%, 3057154 left)
Jun 22 13:41:58 host monerod[891]: 2024-06-22 13:41:58.370        I Synced 119920/3176974 (3%, 3057054 left)
Jun 22 13:41:58 host monerod[891]: 2024-06-22 13:41:58.604        I Synced 120020/3176974 (3%, 3056954 left)
Jun 22 13:41:58 host monerod[891]: 2024-06-22 13:41:58.759        I Synced 120120/3176974 (3%, 3056854 left)
Jun 22 13:41:58 host monerod[891]: 2024-06-22 13:41:58.903        I Synced 120220/3176974 (3%, 3056754 left)
Jun 22 13:41:59 host monerod[891]: 2024-06-22 13:41:59.063        I Synced 120320/3176974 (3%, 3056654 left)
Jun 22 13:41:59 host monerod[891]: 2024-06-22 13:41:59.228        I Synced 120420/3176974 (3%, 3056554 left)
Jun 22 13:41:59 host monerod[891]: 2024-06-22 13:41:59.387        I Synced 120520/3176974 (3%, 3056454 left)
Jun 22 13:41:59 host monerod[891]: 2024-06-22 13:41:59.545        I Synced 120620/3176974 (3%, 3056354 left)

Stop monerod

If you want to stop monerod, simply use the following command:

systemctl --user stop monerod.service

This will stop your monerod from syncing the blockchain. If you want to completely disable the monerod.service from starting up automatically as the monerod qube boot-up, use the following command:

systemctl --user disable monerod.service

This will prevent monerod.service from starting up after a monerod qube reboot.

Conclusion

In this guide I showed you how to setup a monero node in Qubes-Whonix. For this, we created a new whonix-17 qube. Then we downloaded and verified the monerod software. After that we have prepared the monerod config file and service file. Lastly, we started the monerod service, which started syncing the Monero blockchain to your local disk. As we are running the monerod inside a whonix-17 qube, all the network operations are behind Tor network. That way, you are hiding the fact that you are running a monero node from your local internet service provider.


If you find this guide useful you can send some Monero (XMR) to this address:

88wcWTiopkUQQDXeC9R3xxJrgj5MDf8cpNtULQPteqVYQ2kpw2g9bSJD1Cfjpmra5hgsBX19L9wVWEZ8YHGxWtcHTYU2cZW
Donate XMR!
Donate XMR!