Monero Wallet/Daemon Isolation with Qubes + Whonix

Just a heads-up for anyone who is new to setting this up … Just don’t even bother going to the Official Monero Guide. Don’t worry, you’re not going mad, it’s just hopelessly out of date.

I eventually came across this github guide that took all the pain away. Highly recommended.

A few pointers I found as I went:

1.2. Create daemon’s AppVM: monerod-ws
Increased size to 100G

2.2. Create systemd unit
sudo kwrite /lib/systemd/system/monerod-mainnet.service
Replaced kwrite with nano

3.1.1 Install command-line only tools
sudo install -g staff -m 0755 -o root ~/monero-<VERSION NUMBER>/monero-blockchain-* ~/monero-<VERSION NUMBER>/monerod -t /usr/local/bin/
For the correct VERSION NUMBER look at /home/user for name of the directory (monero-x86_64-linux-gnu.v0.17.1.0). That’ll save you a few guesses lol.

4.2 Create communication channel with daemon on boot
Replace kwrite with nano

There. Now there’s my good deed for the day.


Been trying to make this work, I indeed went along with the official monero guide.
Looking trough this guide, it seems to be the same thing, just different user or am I missing something else?
I always end up with socat failing:

2020/10/19 13:18:30 socat[4188] E waitpid(): child 4189 exited with status 127
2020/10/19 13:18:31 socat[4144] E waitpid(): child 4191 exited with status 127
2020/10/19 13:18:31 socat[4190] E write(5, 0x5da184961ec0, 1023): Broken pipe

@MrA you running 4.0.3 or 4.1? I’m at 4.1, so could potentially be something there that makes me unable to do this.

I’m on 4.0.3.

To update:
I had no problems with the daemon or the whonix gateway. No issue that you describe either.

However, there’s still an obstacle to overcome with the the wallet vm communicating with the daemon. It’s on my to-do, but still not to-done. I’ll be sure to update this thread when I get there.

Yeah, the daemon is all synced and good. It’s once I fire up wallet-cli the socat messages pops and wallet reports no connectivity with the daemon.

Now I’ve been able to get back to my Qubes lappy, it turns out my issue was a simple brain-fart on my part.

The edit to /rw/config/rc.local in 4.2 had not been saved (duh!). Once I’d sorted that, everything fires up.

Thankfully, I can now stand by my original post that the github guide is a valid method.

I very much hope you’ve been able to get through the obstacle you experienced, @helge

@MrA I wish I could say yes to that. Was kinda hoping you would come with some revelation :slight_smile:
Still at the same point, once I start CLI the socat process on the wallet vm is killed.
If I start it manually I get to the see the errors, which are as the ones stated above.

I don’t know if this is an issue with 4.1 or whats going on here, but I have created and deleted the setup several times to make 100% sure I’m doing each step, but as mentioned, once I try to reach the local socat process it dies.


Thanks for the Git process, really nice!

I face 2 issues on my side:

  1. how to change the path of the lmdb Monero Database?
  2. when I start GUI in my ws-wallet how do I configure the database to be the monerod because it shows syncing with no block while my lmdb has already few GB (not 100% yet)

Thank you

@jKER24qP since you even got to this part I’m curious, what version of QubesOS are you on?

To answer your questions:

  1. you can use the --data-dir /path/to/blockchain in your systemd file (check monerod --help for all options)
  2. You mean it creates a local blockchain on the ws-wallet? If so it haven’t caught the setup and started a local daemon, try with the cli wallet and make sure it are able to connect to the daemon from the monerod-ws.
    Which might in turn mean you have the same issue as me.

It seems to be either me thats completly missing something or simply these steps doesn’t work with 4.1 code.
I tried to get my Trezor T working which also rely on the same method of using socat.
Method shown here:
Same thing happens here, socat dies once the port is accessed.

Thanks for the update @helge. Must be like you said - something in 4.1

Mine using the github guide on 4.0.3 is working well.

I have no Trezor to test your thought, unfortunately. I do have a Ledger S, and I came across the ‘How-to: Ledger Hardware Wallet in Qubes’, but I’ve not had the chance to mess with it so far. Plus it looks to be a completely different trip to the Trezor method you point to.

Well, got it working, but I don’t understand why this was needed.
I decided to start the daemon with --rpc-bind-ip= --confirm-external-bind
Then I was able from the wallet-ws to utilize socat and reach the daemon-srv via localhost:18081.

Since no incoming requests to the daemon is allowed anyhow it’s not a biggie, but still…
Having it listen on all IPs rather than just localhost is a bit meh, and not what I expected.

Did you do this as well @MrA or does it work with the daemon listening on localhost only (as per default) work for you on 4.0.3?


Cool. Definitely something for me to note whenever I move to 4.1.

I’ve not had incoming with the github guide and, like you mention, no biggie. I made no changes to the steps in the guide.

I’ve also upgraded monero to this evening too. Released yesterday, I beleive.

I moved the reply on another thread here for cleanness:

For easyness of testing (if someone wanna have a go at it) I’d like to throw in some details.
The issue seem to be that if you have a qube hosting a TCP service on a qube called srv-qube.
Then we got another qube, with no netvm, called client-qube.
The TCP service on srv-qube listens on localhost:18081.

On 4.0.3 it seems to no problem at all using socat (or the new “wrapper” ConnectTCP) and reaching that TCP service calling localhost:18081 on client-qube.
On 4.1 however I was unable to replicate this, what I instead had to do was on srv-qube make the TCP service listen on then use socat or qvm-connect-tcp (same settings/method as 4.0.3) to call localhost:18081 from the client-qube, now I’m reaching the service on srv-qube.

Sorry to hijack the thread @MrA just wanted to throw in some extra info as I had the exact same problem with another service that wasn’t monero (the trezor daemon).
Hopefully if someone else struggle with monero separation or any other networking service in non-netvm enviornment this thread can shed some light.

Very curious myself to know if its just my end or if there is a networking change in the background here =)

Not at all :slightly_smiling_face: I think it’s great we can put this all together, and I very much appreciate your input. I’m sure I’m not the only one who will find all this extremely useful when I make a move to 4.1

Maybe you should open an issue against Qubes OS 4.1? But then again, maybe not?

It certainly looks like a change in functionality in the 4.1 implementation… but that change may actually be done intentionally, since services that only listen on localhost should only be reachable from the local host or VM???

I agree, normally networking wise, anything listening on localhost is meant to be only reached from localhost.
Though in this a bit special case with Qubes it does work to share such a resource between Qubes trouch socat, if your allowing it via dom0.
All guides for cryptocurrency and trezor T hardware wallet setup in qubes rely on exactly this.

So security wise, to me, it sounds very good to have the daemon simply listening on localhost, but trough socat/ConnectTCP we manage to reach it even though.
This can of course be achived by other means, like blocking incoming packets destined for the daemon, but the whole idea behind making the daemon listen on localhost is to avoid any chance of remote RPC calls (which in turn COULD potentially lead to tampering).

So these guides shows how to still keep that security aspect, but at the same time give access to the daemon from the qube, with no netvm, that holds your private keys.

At this stage I’m ok with that as a solution, this whole thing has turned in to a more curiousity case to what actually has changed.
I’ve been at it on 4.1 for a while now to try to use these various cryptocurrency/hardware wallet guides with no success, until I discovered this solution.

Does that mean you need to adopt the [file] in the /rw/usrlocal/etc/qubes-rpc/user.monerod in the Monero VM-Doemon to:
socat STDIO TCP:localhost:18081 --rpc-bind-ip= --confirm-external-bind or where do you need to add “–rpc-bind-ip= --confirm-external-bind”?

I am running Qubes 4.1 and without “–rpc-bind-ip= --confirm-external-bind” i get “Error: Couldn’t connect to daemon:” in the wallet VM

Thank you going to try this now.

Is there anything needed to do when template vms are updated? The time I got it working it stopped after I updated.

I haven’t found any issues so far. That includes after updates.