Local networking between qubes?

What is the preferred way to communicate locally between qubes using the virtual network interfaces? Someone has certainly solved this before so I’m mostly looking for confirmation of whether I’m on the right track.

My best idea rn is to add commands to sys-firewall’s rc.local that add forwarding rules between my desired qubes. It would look something like:

set my-lan {
    type ipv4_addr
    elements = {,, }
chain custom-forward {
    oifgroup 2 ip daddr my-lan ip saddr my-lan accept

(I haven’t tried this or checked for errors so hopefully you get the idea)

My next idea is to insert another qube between the app qubes and sys-firewall, to act as a network switch, installing a virtual switch in it. I like that this keeps the configuration neatly self-contained. But I think this wouldn’t work because sys-firewall has anti-spoof nft rules that would prevent the switch forwarding packets from other qubes.

My situation right now is that I have 3 VMs that need to communicate with each other, with two of them running Windows-dependent apps. I’m not using windows-qubes-tools because of recent security issues I’ve heard about, so I don’t see qrexec services as a solution.

If the 3 VMs are connected to sys-firewall, you would just have to allow the 3 VMs to reach each other on sys-firewall

the qubes (non Windows) have all incoming ports blocked by default, so you may need to open what you need. On Windows, you will have to deal with its firewall for your needs.

Thank you! The section you linked is exactly what I was looking for, but somehow the firewall page didn’t stand out to me as the place I would find it :sweat_smile: .

It suggests to install the custom-forward rule from /rw/config/qubes-firewall-user-script. Do you know what kind of problem could be caused if it is installed from rc.local instead? Just trying to have a better understanding. This section clarifies but doesn’t provide justification Firewall | Qubes OS

It will work in rc.local too. qubes-firewall-user-script has a comment in it explaining its purpose, it requires the service qubes-firewall to be enabled in that qube for the file to be executed, while rc.local is always started.