monero in Whonix with torsocks for better stream isolation

I use

DNS_PUBLIC=tcp TORSOCKS_ALLOW_INBOUND=1 torsocks ./monero-wallet-cli --daemon-host [onionurl:port] --restore-height -1

like the above and get a similar error:

libunbound[6560:0] error: outgoing tcp: connect: Connection refused for

shown repeatedly when trying to transfer.

Is it anything to do with whonix firewall and ports blocking? can’t make any transactions, and it takes forever even to receive the errors.

Anyone successfuly using monero-wallet-cli 0.13.0.4 on Whonix 14?

the monero program is (and always been) terrible at handling connection issues. Not only it takes ages (minutes and more) to get an error, it doesn’t respond to CTRL-C as well. One has to close the terminal window to kill the program, then worry about process possibly still running in memory.

Update: I now tried

./monero-wallet-cli --daemon-host [onionurl:port] --restore-height -1

meaning not using torsocks, no stream isolation, and everything works well!

Still something to look into!

I don’t have any problem running monero-cli against a remote node (as suggested in the wiki). However, my connection to remote nodes keep dropping. I sometimes have to refresh several times before the remote node responds. Has anyone experienced this?

I got monerod working like this: DNS_PUBLIC=tcp://8.8.8.8 TORSOCKS_ALLOW_INBOUND=1 torsocks ./monerod --p2p-bind-ip 127.0.0.1 --no-igd --hide-my-port --data-dir /mnt/blockchain/monero/. I admit that I don’t understand some of these options. I got it from a tutorial on running monero behind tosocks.

Btw this will be the default in Whonix 15 (perhaps even already is in Whonix 14).

see

./monerod -h
./monero-cli -h

Monero v0.17.3.0 added a --proxy flag, e.g. monerod --proxy 127.0.0.1:9050. I haven’t audited for proxy leaks, but it does work fine in a Whonix VM that has transproxying disabled. Maybe consider updating the wiki instructions to use this flag instead of torsocks. I would recommend using a SOCKS port that isolates by both destination IP and destination port, to minimize the risk of eclipse attacks (Bitcoin Core does approximately this by default).

2 Likes

As @JeremyRand points out monerod now has the --proxy flag.

I’ve read through the pull request a few times now and my conclusion is that for Whonix users the optimal monerod command is:

monerod --proxy 10.137.0.8:9180 --p2p-bind-ip 127.0.0.1 --no-igd --hide-my-port --tx-proxy tor,10.137.0.8:9152,10

The reason for the tx-proxy argument is that, according to the information in the pull request discussion, monerod will use it to establish hidden service connections to broadcast txs. Unless one is transacting frequently this will typically mean each transaction gets its own circuit, as opposed to relying on just the proxy setting which would result in multiple transactions sharing the same circuit.

I could have something wrong, but this is my best understanding of the available information. How can I go about getting this put into the Whonix Monero documentation because the current torsocks commands are dated and barely usable?

At this complexity, perhaps best to create a config file

/etc/monerod.conf

and then start monerod with

–config-file=/etc/monerod.conf

?

This config could even be added to GitHub - Whonix/anon-apps-config.

The confusing thing would be that monerod by default does not use any config file unless using --config-file. Not sure that’s worth an upstream feature request.

I am also wondering how Whonix once that config file exists could add --config-file=/etc/monerod.conf to monerod and/or monero-wallet-cli / monero-wallet-gui by default.

Resources:

https://monerodocs.org/interacting/monero-config-file/

The daemon by default on Whonix checks /home/user/.bitmonero/bitmonero.conf: monero/src/daemon/command_line_args.h at c5d10a4ac43941fe7f234d487f6dd54996a9aa33 · monero-project/monero · GitHub

Transforming the tutorials (http://www.dds6qkxpwdeubwucdiaord2xgbbeyds25rbsgr73tbfpqpt4a6vjwsyd.onion/wiki/Monero_Wallet_Isolation) command line parameters into a config file:

data-dir=/home/user/.bitmonero
log-file=/home/user/.bitmonero/bitmonero.log

no-igd=1
hide-my-port=1

p2p-bind-ip=127.0.0.1

and adding @moneroconfig’s proxy settings:

proxy=10.137.0.8:9180
tx-proxy=tor,10.137.0.8:9152

--pidfile=/home/user/.bitmonero/monerod.pid and --non-interactive would still be required to be passed as command line parameters in the tutorial systemd setup.

Some questions regarding all of this:

  • port 9180 is a with IsolateDestAddr / with IsolateDestPort port: this creates a circuit per peer for communication right? That seems like a lot - so wouldn’t a without IsolateDestAddr / without IsolateDestPort port in that case be better?

  • port 9152 is a without IsolateDestAddr / without IsolateDestPort port: wouldn’t here then a with IsolateDestAddr / with IsolateDestPort port be better to create a new circuit for every local transaction?

  • in Qubes OS: should/could I use 127.0.0.1 instead of sys-whonix’s IP (10.137.0.8)

  • hide-my-port: if I understand this parameter this disables “self-propagation” → my nodes’ peers don’t announce my node to their peers - does that create a “Do Not Track” situation (as it is not a default parameter) and increases a fingerprinting possibility?

  • should I consider the parameters
    pad-transactions=1 (protocol: option to pad transaction relay to the next kB by moneromooo-monero · Pull Request #4787 · monero-project/monero · GitHub)

    and

    no-zmq=1

    Disable ZMQ RPC server. You should use this option to limit attack surface and number of unnecessarily open ports (the ZMQ server is unfinished thing and you are unlikely to ever use it).

    for my node?

Sorry for the missing hyperlinks, apparently cannot use them yet.

You can post links now.
(Kicksecure ™ Forums Usage Instructions, Best Practices and FAQ chapter Posting Links for New Users in Kicksecure wiki)
(Whonix is based on Kicksecure.)

1 Like

Thank you, populated my post with the missing hyperlinks.

Hi! I have a question similar to those discussed in this thread. I would appreciate it if you would check out my other post. However, I will copy the relevant questions to this chat as well. You can check it out here: Monero Anonymity: QubesOS/Whonix Split Monero Wallet vs. Self-hosted Onion Remote Node

Half of my question is also about the optimal monerod configuration in the QubesOS/Whonix Monero split wallet setup, which is also described in the Whonix documentation.

  1. How can I separate p2p traffic from transaction broadcasting traffic to avoid correlation attacks? In other words, I don’t want the p2p nodes I’m connected to also receiving my Monero transactions from the same Tor exit nodes.

My current work-in-progress idea is to use TransPort for p2p traffic and add another TorSocks port for the “new” –tx-proxy flag. However, I am unsure whether this is what the proxy flag is actually intended to do.

Currently, my best guess is to use the following configuration for QubesOS: --tx-proxy tor,127.0.0.1:9180,10. Is that the right approach? Note the IP address, port number, and 10. Is this the correct setup? What does the 10 actually do? From my understanding, it will rotate through ten different peers for broadcasting. Is that correct? Is 127.0.0.1 correct in the QubesOS context? What do you think about the specific port 9180?

  1. I am also trying to determine whether stream isolation is ideal for the two types of traffic (p2p and transaction broadcast).

My understanding is that, for long-lived p2p connections, stream isolation isn’t ideal, but it is for transaction broadcasts. Therefore, I would use the TransPort for p2p traffic and a SocksPort in the range of 9180–9189 for transaction broadcast traffic. These ports are documented in the Whonix documentation and come with IsolateDestAddr and IsolateDestPort. More information can be found here: Stream Isolation .

As a follow-up, I have a question about the specific port. Is it a good idea to choose any available port in sys-whonix? Wouldn’t doing so increase the risk of another application (perhaps from a different VM) using the same port, which could lead to identity correlation? Would it be better to define a unique monerod --tx-proxy SocksPort to ensure that it is not used by anything else? Is that even an issue, or is traffic using the same SocksPort (e.g. 9180) from two different VMs isolated anyway?

  1. I also believe that P2P connections running over Tor exit nodes allow for more timing correlation as if they never left the Tor network (e.g., by using Onion Services). In other words, I see potential for improvement in moving all p2p traffic from the current TransPort IP obfuscation method to Tor Onion Services exclusively.

My idea is to use the exclusive relay feature to add only Onion Services as peers. This should result in only P2P connections to Onion Services. I haven’t tested this yet, so I’m looking for feedback and discussion about it.

  1. Given the shift to Onion Services for p2p traffic, I would like to determine the optimal number of peers to mitigate the risk of an eclipse attack. Additionally, I would like to explore the potential benefits of implementing stream isolation for p2p traffic. In other words, I am requesting a reevaluation of previous p2p traffic considerations in light of the use of Tor Onion Services.

  2. I would also like to start a discussion about whether the Flatpak or the direct Monero binary is the better option.

Flatpak could be updated more easily. Depending on the option chosen, I recommend checking the hardening options, as these should differ between the systemd service file with the Monero daemon (monerod) binary and the Flatpak version.

This is just a rough draft and not a complete setup. It has not been fully tested either. I would appreciate some feedback before moving forward. Please note that I have already spent quite a bit of time testing and consulting the Whonix documentation.

I accidentally posted in the other thread and cannot double post due to the “similar post” error. Please check this: (Mod edit: Post moved from original location to this thread, it now appears below this post)

Next time, I will post here. Sorry!

1 Like

I am still working on an updated systemd service file for monerod that includes all the important flags. Today, I checked the reference documents again, and it seems they have changed. Is this correct, and where can I see the changes? I am referencing: How-to: Use Monero with Wallet Isolation in Qubes-Whonix

Also, I think the --db-sync-mode=safe argument is redundant because it is the default in monerod, as far as I know. I will publish some other modifications here after testing them.

In my opinion, the most important missing flag in the Whonix documentation is --tx-proxy=tor,127.0.0.1:9101,disable_noise or a variation of it. I’m not sure if it works yet, but I hope we can start a discussion about it. In theory, this flag should route p2p gossip traffic over a different Tor circuit than transaction broadcasts, which could help protect against correlation attacks.

I also don’t see torsocks anymore. Is it no longer needed in Whonix, even though it was in the past? Or, was using torsocks always a configuration mistake? I get Tor over Tor errors when using torsocks in the nyx sys-whonix logs. Is that expected? Could you explain why this behavior occurs and why the Whonix docs no longer require torsocks?

Thanks!

Noticed this, I took the liberty of moving your post here so that everything would be contiguous. Hope this is helpful :slight_smile:

1 Like
  • torsocks = socksifier → intends comprehensive socksification
  • --tx-proxy== proxy settings

These methods are typically technically incompatible, mutually exclusive.

Proxy settings - for applications that are Tor aware/friendly - may potentially allow for finer control of Stream Isolation. Specifically if these support IsolateSOCKSAuth.

Log required.

1 Like

I can confirm that the Tor over Tor warnings are no longer present in Nyx with my new monerod configuration in Whonix-Workstation.

I still have a question about the ideal SocksPort: Which one should I choose, and why? I have some thoughts on that, but first, let me explain what I did for the monerod configuration.

I checked 65_gateway.conf in sys-whonix to see all the configured socksports (e.g., grep -R socksport /etc/torrc.d/).

Then, I chose one that offered IsolateDestAddr and IsolateDestPort. I selected 9105 because my 65_gateway.conf includes this line: /etc/torrc.d/65_gateway.conf:SocksPort 127.0.0.1:9105 IPv6Traffic IsolateDestAddr IsolateDestPort.

I also used the command ss -ntp | grep 9105 to check if the port is in use. Since it was available (no output), I chose it.

This resulted in the configuration of my monerod file like this:

--proxy=10.152.152.10:9105
--tx-proxy=tor,10.152.152.10:9105,16

In the context of Whonix, how can I determine the best port for monerod? From what I understand, it’s best to assign different ports to different applications to avoid correlation risks, though stream isolation makes this less necessary. The only risk occurs when two applications reach out to the same destination and port, causing stream isolation to fail. This is possible but unlikely. For applications that reach different destinations and ports, it would be fine to always use the same stream-isolated port. This is my current understanding.

Ideally, each application, such as Tor Browser, monerod, and messaging, would have its own dedicated port. However, I am concerned that choosing any free port might lead to its use by Whonix developers in the future. I could not find a clear, declarative table in the documentation showing which ports are in use and for which application. For strong data locality, this information should be documented directly in the 65_gateway configuration file. Perhaps first-class Tor applications, such as monerod, should be given a reserved port (as a recommendation in the configuration file). Please let me know if my concern is valid and if I understand the matter correctly. Also, please let me know what you think about my proposal for improvement.

My tested monerod.service file is:

[Unit]
Description=Monero Full Node (Tor-only, restricted RPC) - Flatpak
After=network.target

[Service]
Type=simple

ExecStartPre=/bin/sh -c 'until nc -z 10.152.152.10 9105; do sleep 2; done'

ExecStart=/usr/bin/flatpak run \
  --command=monerod \
  --share=network \
  --filesystem=%h/.bitmonero:rw \
  org.getmonero.Monero \
  --data-dir=%h/.bitmonero \
  --non-interactive \
  --prune-blockchain \
  --sync-pruned-blocks \
  --proxy=10.152.152.10:9105 \
  --tx-proxy=tor,10.152.152.10:9105,16 \
  --out-peers=8 \
  --in-peers=0 \
  --hide-my-port \
  --pad-transactions \
  --enable-dns-blocklist \
  --no-igd \
  --rpc-bind-ip=127.0.0.1 \
  --rpc-bind-port=18081 \
  --restricted-rpc \
  --no-zmq \
  --check-updates=disabled \
  --log-file=%h/.bitmonero/bitmonero.log \
  --log-level=0,stacktrace:FATAL \
  --max-log-file-size=10485760 \
  --max-log-files=3

Restart=on-failure
RestartSec=30

ExecStop=/usr/bin/flatpak kill org.getmonero.Monero

StandardOutput=journal
StandardError=journal

PrivateTmp=true
ProtectSystem=full

[Install]
WantedBy=default.target

The goal of this file is to strike the optimal balance between connectivity and minimizing exposure. Monerod is locked down and all unnecessary features have been removed for the Qubes/Whonix split wallet architecture. No incoming connections are established.

The best feature is that separate circuits are used for monerod p2p connections and transaction broadcasting. This ensures that each connection has a different Monero p2p circuit, as well as additional circuits for Monero transactions, since the nodes used for p2p traffic aren’t used for transactions. This reduces the risk of correlation attacks. Broadcasting to a maximum of 16 nodes in the network leads to fast transaction diffusion, which protects against analysis by having some nodes receive the transaction much earlier than others in the network.

Monerod will primarily use Onion Services, but not exclusively, to reduce eclipse attacks. The pool of Onion Services for p2p Monero nodes is simply more limited than it would be if IP addresses were also used. Additionally, an attacker could create multiple Onion Services addresses for the same node, which could lead to the same node. Therefore, a mix is ideal.

I have always been annoyed by the stack traces in the logs that lead to a GitHub issue stating they are neither critical nor important. Therefore, I disabled logging for all but fatal stack traces. I also reduced the size of the logs because I don’t need 10 logs, each 100 MB. This should be the default behavior.

I consider padding transactions an improvement against traffic analysis.

To make updates easier, I used Flatpak. This allowed me to improve the Whonix documentation without completely breaking it. Since Flatpaks can be updated easily, I disabled the update check to reduce exposure and eliminate one unnecessary connection.

Terminating the Flatpak process isn’t the cleanest method, but I could not find a proper stop command for the monerod process. I tried for hours. The issue is that the graceful shutdown command needs to be passed from systemd through two child processes of Flatpak’s sandbox to reach monerod, but this often fails, leading to orphaned processes that still hold the lock on the LMDB database. This causes the database to break when monerod is restarted because the old service is still running and holding the lock. Therefore, I used the working Flatpak kill command that is also in the Whonix documentation. This shouldn’t be a problem, as LMDB is atomic and should not become corrupted upon abrupt shutdown.

I also added the pruned flag because running a pruned blockchain does not pose a privacy issue. The only real downside is that the node cannot provide others with full blockchain data. However, this limitation is irrelevant since the node only runs outbound connections anyway.

I consider this a significant improvement to the official documentation, and I would like to see it added. However, I don’t know how to edit the documentation or contribute to it.

My approach was to determine all flags of the latest moenrod version (‘Fluorine Fermi’ v0.18.4.6), while matching the QubesOS/Whonix split architecture in the best possible way. I omitted the unnecessary ones and set some redundant options to ensure added safety against future changes.

Please ask if you have any additional questions.

I have another question about Qubes/Whonix and stream isolation networking. Does Whonix support Qubes VM-wide stream isolation? For example, do AppVM_A and AppVM_B have guaranteed different Tor circuits, even if they use the same application? The same question applies to dispVMs for Tor Browser.

Required reading:

1 Like

Thanks for the tip to check out the documentation! I was stupid for not reading it before. Thanks! I carefully read the entire chapter.

Anyway, I have some questions:

  1. According to the documentation, IsolateDestAddrand IsolateDestPortare not typically necessary for configuration. I think it’s a good idea to separate different p2p monerod peers so the node can fully integrate into the network instead of connecting only over one exit node, which could interfere with monerod’s view of the network. I would like to hear rational arguments for or against using the flags.

  2. I was absolutely wrong about the docs not including a list of Socks ports in use. I apologize for that; as I said, I should have read the page beforehand. In any case, this isn’t a nitpick, but an honest effort to move forward. The table lists Monero, but doesn’t have a port noted. That field is empty. I hope that this thread (and my improved systemd unit file) will lead to full documentation. I propose full standardization of a dedicated monerod SocksPort.

  3. I read that the gateway address in Qubes/Whonix is determined by the qubesdb-read /qubes-gateway command. Therefore, I assume that my hard-coded Whonix-Gateway address of 10.152.152.10 is incorrect. This is likely due to the different networking styles of QubesOS and Whonix. However, my setup works. What are the real differences, disadvantages, and risks? I would appreciate a quick explanation and recommend adding a short rationale to the documentation. Also, does this mean that I should run the command manually and set the correct IP for the Qubes internal gateway every time I set up a new monerod VM?

After reading the documentation, I was able to answer my own question. Since every QubesOS VM has its own local IP address, and since Tor’s default behavior is to use IsolateClientAddr, every VM is stream isolated by default. Therefore, timing attacks are a real concern when using multiple identities in different VMs simultaneously. I also understood that templates aren’t isolated because they don’t reach out via networking to update. As far as I know, this is only a template issue and not an AppVM issue. Please correct me if I am wrong.

  1. Finally, what are your thoughts on the updated systemd unit file for monerod? Will you include it? I think it has much better properties than the current version. I hope to see some discussion and feedback.

@Patrick, please review my four questions and recommendations.

Additionally, I updated the systemd unit file to resolve the dynamic QubesOS gateway IP address instead of the incorrect hardcoded Whonix Gateway IP. Is this the correct approach now? Here is the updated file:

[Unit]
Description=Monero Full Node (Tor-only, restricted RPC) - Flatpak
After=network.target

[Service]
Type=simple

# Wait for qubesdb and Tor SOCKS
ExecStartPre=/bin/sh -c '\
  until GW=$(qubesdb-read /qubes-gateway 2>/dev/null) && [ -n "$GW" ]; do sleep 1; done; \
  until nc -z "$GW" 9105; do sleep 2; done'

ExecStart=/bin/sh -c '\
  GW=$(qubesdb-read /qubes-gateway); \
  exec /usr/bin/flatpak run \
    --command=monerod \
    --share=network \
    --filesystem=%h/.bitmonero:rw \
    org.getmonero.Monero \
    --data-dir=%h/.bitmonero \
    --non-interactive \
    --prune-blockchain \
    --sync-pruned-blocks \
    --proxy=$GW:9105 \
    --tx-proxy=tor,$GW:9105,16 \
    --out-peers=8 \
    --in-peers=0 \
    --hide-my-port \
    --pad-transactions \
    --enable-dns-blocklist \
    --no-igd \
    --rpc-bind-ip=127.0.0.1 \
    --rpc-bind-port=18081 \
    --restricted-rpc \
    --no-zmq \
    --check-updates=disabled \
    --log-file=%h/.bitmonero/bitmonero.log \
    --log-level=0,stacktrace:FATAL \
    --max-log-file-size=10485760 \
    --max-log-files=3'

Restart=on-failure
RestartSec=30

ExecStop=/usr/bin/flatpak kill org.getmonero.Monero

StandardOutput=journal
StandardError=journal

PrivateTmp=true
ProtectSystem=full

[Install]
WantedBy=default.target

Whonix is the wrong recipient for such support requests.

Quote How to mitigate identity correlation: