Monero Wallet/Daemon Isolation with Qubes + Whonix

Create file in dom0 using terminal:

sudo nano /etc/qubes/policy.d/30-monerod.policy

Or using Qubes Policy Editor GUI tool.
Add this inside:

user.monerod * monero-wallet-ws monerod-ws allow

can you explain followings:

  • user.monerod : what is this?
  • * : what is this?

Other posters in this thread (a few posts above) have different directives in their policy files, including, qubes.ConnectTCP and @default directives. While your example doesn’t have those? Why? What’s the difference?

user.monerod - service name
* - argument
It’s described in the qrexec doc:

Policies are defined in lines with the following format:

service-name|* +argument|* source destination action  [options]

user.monerod is custom qrexec service that you define, qubes.ConnectTCP is already existing Qubes OS service that you can use like this:

You can read qrexec doc to know about specifics.

Isn’t using the existing qubes.ConnectTCP better (“more secure”) in this case? It seems like qubes.ConnectTCP limit the capability to sharing just a single tcp port, while defining user.monerod seems like allowing “everything” between the target and source qubes.

Not sure if it’s more secure, but it should be less error-prone during configuration.


1 Like

Okay so I am trying to understand this whole thing. I have been reading the qubes os documentation as well as whonix guide and the protonmail-bridge guide you’ve linked. It seems like main the cause for complexity is that I need to setup policy files, startup command files, in dom0 AND the AppVM’s.

  1. The policy file in the dom0 will be stored in /etc/qubes/policy.d/30-user.policy file and will contain, what? – I guess something about qubes.ConnectTCP?

  2. there will be another qubes-rpc stuff inside monerod-ws qube, which will be stored in /rw/usrlocal/etc/qubes-rpc/user.monerod file and will contain some socat command.

  3. there will be a command line command defined in monero-wallet-ws qube inside the /rw/config/rc.local/ file which will contain socat TCP-LISTEN[...] command

  4. another cause for confusion is, the terms “service name” and “policy”. What is “service name” in this context?

Policies are defined in lines with the following format:

service-name|* +argument|* source destination action  [options]

Is service-name a systemd service (is it a --user service, or a root account service)? Or do we name stuff like qubes.ConnectTCP as “services” ?

I’m assuming that you want to use qubes.ConnectTCP instead of custom service.
Then you need to follow the guide for Opening a single TCP port to other network-isolated qube in the firewall doc linked before. You need to follow 1. Simple port binding + 4. Permanent port binding.

In dom0, add the following to /etc/qubes/policy.d/30-user-monerod.policy:

qubes.ConnectTCP +18081 monero-wallet-ws @default allow target=monerod-ws

In monero-wallet-ws run these commands:

cat << 'EOF' | sudo tee /rw/config/monerod-service.socket >/dev/null


cat << 'EOF' | sudo tee /rw/config/monerod-service@.service >/dev/null

ExecStart=qrexec-client-vm '' qubes.ConnectTCP+18081
cat << 'EOF' | sudo tee -a /rw/config/rc.local >/dev/null
cp -r /rw/config/monerod-service.socket /rw/config/monerod-service@.service /lib/systemd/system/
systemctl daemon-reload
systemctl start monerod-service.socket

It’s referring to the Qubes RPC services and Qubes RPC policies, not systemd services:

1 Like

Thanks for the detailed responses.

However, I already have:

  1. a monerod-ws AppVM in which I run a user-level monerod.service file (using systemctl --user enable --now monerod.service).

  2. monero-wallet-ws AppVM in which I run Feather Wallet.

I want to (I guess) establish a TCP port connection from monero-wallet-ws to the monerod.service qube, so that the Feather Wallet can pull the monero blockchain data from the monerod running in the other qube.

So, I don’t understand why I should use the monerod-service files you just give me. Do I have to use the socket config file you give me? Can I not listen in on using the socat stuff that the previous people in previous guides seem to use?

These files are needed to configure the permanent port binding between qubes using qubes.ConnectTCP service as described here:

If you don’t want to use qubes.ConnectTCP service and you want to use the custom Qubes RPC user.monerod service instead then you can follow the guide from Whonix doc but using new policy format:

I want to use qubes.ConnectTCP because it sounds like it does what I want (and only what I want): just forward a port between two AppVMs.

So, in this vein, how about using this one?

This one seems to use qubes.ConnectTCP service from (dom0) /etc/qubes-rpc/qubes.ConnectTCP. Further, using this one, I won’t be needing to create (dom0) /etc/qubes-rpc/user.monerod file (saving me from cluttering, and possible mistakes).

1 Like

Then you can follow the steps in my previous post about qubes.ConnectTCP usage.
Just adding /etc/qubes/policy.d/30-user.policy file in dom0 with qubes.ConnectTCP policy is not enough, you need configure the use of qubes.ConnectTCP service in the monero-wallet-ws to bind the port between qubes.

1 Like

It is so fucking confusing because I am trying to juggle 4 different guides, and come up with a sane synthesis of them: 1 2 3 4

So, I start on dom0 creating a policy file:

sudoedit /etc/qubes/policy.d/30-user.policy

add the following line into the file:

qubes.ConnectTCP +18081 monero-wallet-ws monerod-ws allow

Now, are you telling me that I need to repeat this 30-user.policy file in the monerod-ws qube, inside /rw/usrlocal/etc/qubes-rpc/user.monerod file? Why the repeat? Isn’t this already saying “aight, establish the connection of the port 18081 between the two monero qubes” ?

My guess is @appartus wanted to say you will need to run the connectTCP command in the whonix qube to make the port binding effective (it’s what the rule allows), I’m doing it from /rw/config/rc.local in a qube and it’s working fine, dunno if there is a better place to run it.

Something like

qvm-connect-tcp 18081:@default:18081
1 Like

So yeah, you add this qvm-connect-* command to /rw/config/rc.local file on your monero-wallet-ws.

However, I guess I also need to instruct monerod-ws qube to expose its 18081 port to stdin/stdout using socat or something? Or is monerod-ws qube already ready for the qvm-connect-tcp command coming from the monero-wallet-ws qube?

this will bind the local port 18081 to the target port 18081, if it’s listening on localhost on that port on the remote, then you do not have anything else to do.

1 Like

That’s cool. Now that I have some cursory understanding of what I am doing, let me try these.

1 Like

When I try to create file 30-user.policy in dom0 I get the following error:

(dom0) $ sudoedit /etc/qubes/policy.d/30-user.policy
sudoedit: /etc/qubes/policy.d/30-user.policy: editing files in a writable directory is not permitted

How do people create the 30-user.policy file in dom0?

EDIT: oh, ${SUDOEDITOR} is undefined in dom0. My bad.

Amazing. It worked. And the only policy file I created is the one on dom0. I really don’t know why the previous guides all create mumbo-jumbo of policy files across dom0, monerod, qubes, etc.

Create the 30-user.policy file on dom0. Fill it with this:

qubes.ConnectTCP +18081 monero-wallet-ws monerod-ws allow

Then, go to your monero-wallet-ws qube. On the terminal enter the command:

qvm-connect-tcp 18081:monerod-ws:18081

From then on, your Feather Wallet will be able to connect to a monero node on That’s it. No need to add an rpc/policy/socat/etc/etc/ files in monerod-ws nor monero-wallet-ws qubes.

1 Like

Would it be possible for you to rewrite the guide (or write a new one) with your split monero setup? As you discovered, there are multiple guides that are complicated and not really up to date.

1 Like

I wrote a guide here:

tor: http://karaparawplotu233ux7adtiaqswdthdk6kiqqovgy4ldp2dseijwnad.onion/wiki/feather-wallet/feather_wallet_isolated_qubes_whonix_setup_en/

clearnet: feather wallet isolated qubes whonix setup en