How is the QubesOS firewall implemented?

I have successfully created firewall rules by the two methods in QubesOS:

  1. qvm-firewall - the python script in the host OS (dom0) which writes to /var/lib/qubes/appvms/<vm-name>/firewall.xml and outputs my rules with:
    qvm-firewall <vm-name> list
  2. The GUI: Qubes Settings > Firewall Rules

But I cant find information in the docs on how and where my rules are then implemented. Iv been looking in iptables -L -v on the relevant netVM and even in the appVM and I dont see the implementation of the rules I defined anywhere. Please can someone provide more information or a link to more information on how and where my rules are implemented?

I donā€™t know too much about this but my guess would be that they are applied on sys-firewall. Have you run iptables -vL there?

The qubes-firewall uses nftables instead of iptables so you can see the rules by using the nft command in netVM:

sudo nft list table qubes-firewall

But I donā€™t know enough about it either, and if I remember correctly, there is no document that explains it in detail, so you may need to read the source code to understand it.

3 Likes

Yeah running iptables -L -v on sys-firewall doesnt show any implementations of the rules I wrote

1 Like

Aha, thats the trick!

Running sudo nft list table qubes-firewall in sys-firewall displayed all the firewall rules for appVMs which are connected directly to sys-firewall (it is their netVM).
I had thought it might be nft but I didnt know that there was a qubes-firewall table. In retrospect, I should have run:
nft list tables

However, Im not sure where my whonix workstation templatesā€™ rules are implemented because theyre not listed by iptables in sys-whonix and nft commands return:
Command 'nft' not found, but can be installed with: apt install nftables

1 Like

Actually, on closer inspection, my firewall rules for my whonix-ws template appVMs are not actually implemented at all! But I remember in one of the QubesOS documentations the following recommendation about using proxyVMs (I assume such as sys-whonix):
INTERNET <-> netVM <-> firewallVM(0) <-> proxyVM <-> firewallVM(1) <-> appVM

i.e. having an extra firewallVM if you use a proxyVM

2 Likes

I just tried it and this worked :slight_smile:

And in the new firewallVM(1) I just created (firewallVM only for sys-whonix traffic), I ran nft list table qubes-firewall and I found the implementation of my rules. Nice.

Thanks for digging through this. I was actually looking for this answer for a long time. How do you go about creating said firewallVM(1)? Is there anything in particular you need to tweak for it to be considered a firewall?

I donā€™t have my Qubes running right now but manually configuring a firewallVM for the whonixVM chain is non-standard, isnā€™t it?

I canā€™t imagine that the default whonix VMs (e.g., anon-whonix, whonix disposable VMs, ā€¦) come preconfigured in an insecure way without the possibility to enforce firewall rules. Clearly this must be configured somewhere else?

The Whonix gateway doesnā€™t (didnt?) provide the capability
to enforce firewall rules. One reason why I donā€™t use Whonix.

If you adopt the proposed solution of putting in an extra firewallVM,
you should be aware that traffic will then arrive at the WhonixGW
after NAT, so traffic from all connected qubes will arrive at the GW
showing the same originating IP - this will impact how Tor circuits are
built and used, and is almost certainly not what you want.

1 Like

Thatā€™s an interesting point. Do you mean to say that that same originating IP would be of the internal QubesOS private network subnet, eg. 10.137.0.42?

If so, that wouldnt give away the userā€™s location but it would form part of a fingerprint which could be used to track the user across accessing different websites etc on the internet.

Any idea in what way that would be?

Nope

To create the firewallVM(1) I mentioned go to:
Qube Manager > Qube > Create New Qube > Type: AppVM | Networking: proxyVMname | Advanced: provides network (yes) > OK

Then open the ā€˜Qubes Settingsā€™ of any appVMs you want to connect to this firewallVM(1) and set their ā€˜Networking:ā€™ to your newly created VM

2 Likes

Though it seems the original question was answered, here are some bullet points from what I have learned over time regarding implementation details:

  1. The qubes firewall service is enabled by default in NetVMs and ProxyVMs. It can be disabled by adding the qubes-firewall service to the Services, but leaving the box unchecked.
  • As mentioned previously, this service is explicitly disabled in sys-whonix, and replaced by the Whonix Firewall.
  • The Whonix Firewall does not have the ability to apply host-based blocking rules, without manual configuration on the gateway qube itself.
  1. The qubes-firewall application is a service that is run at boot of the Net/ProxyVM (ā€œFirewallVMā€). info: systemctl status qubes-firewall

  2. qubes-firewall sets up initial rules using nftables (if available) or iptables.

    • On Debian, iptables uses an nftables backend, so using the iptables or nft commands do the same thing.
    • On Fedora, there is divergence - see Issue #5031. qubes-firewall ends up using nft to setup its rules, but those rules will not be seen when running iptables commands. Therefore, usage of nft is required to inspect the rules.
  3. When a qube is attached to the FirewallVM, qubes-firewall within the FirewallVM is notified, and it sets up the appropriate rules for the attached qube using nft or iptables which at minimum enables IP forwarding. If there are Firewall rules for the qube in question, additional rulesets are added to the appropriate netfilter forwarding chain within the FirewallVM.

  4. If hostnames are used for an attached qubeā€™s firewall rules, the FirewallVM must succeed in resolving the hostname, otherwise, ALL traffic to the attached qube will be blocked and appear to not have internet access. I hear this issue commonly when people have involved ā€œVPNā€ qubes and have extra firewall rules.

@anon, I believe what @unman is referring to is that any attached qube to the FirewallVM which is then attached to sys-whonix will appear to have the same IP address as the FirewallVM. This could result in Tor building a single circuit that will be shared by the attached qubes. This would then give both qubes the same exit IP, which may be undesired if isolation between activities in the attached qubes is sought.

7 Likes

Excellent summary - I should add that there is currently an issue with Debian
minimal template used as basis for FirewallVM.

On the Whonix issue, @icequbes1 is spot on. All traffic arriving at
sys-whonix will appear to come from a single IP address, that of the
firewall. So stream isolation between qubes may be compromised, if the
streams are based on IsolateClientAddress.
Example - I have 2 qubes representing different identities, which I use
to access separate accounts on the same mail server - if I put them behind
a firewall then they will share a common circuit, allowing identity
correlation.

1 Like

Thanks for this nice summary @icequbes1. Since there is no ā€œsolutionsā€ making in #general-discussion topics, Iā€™ve added some highlight color to your post :slight_smile:

A post was split to a new topic: Sys-whonix ā† sys-firewall2 leads to identity correlation

(Moved this into a new topic. Feel free to propose a title change)

Iā€™m readed this topic, and few more. Also dig a little about qubes-mirage-firewall that was recommended to me by a friend who also recommend me qubes. Iā€™m still not fully understand few things. As I assume both sys-firewall and qubes-mirage-firewall came with, a default set of predefined rules. Which we can edit either by using console and nft, or by adding rules in rules.ml and rebuilding qubes-mirage-firewall. Both also support additional rules which we can add for VM via qvm-firewall command or via GUI. Am I getting this right? Since Iā€™m little bit confused because Iā€™m read that mirage not supporting changes from GUI. But As I understand GUI only providing simpler way for same mechanisms as qvm-firewall so what will be the reason that mirage support one way, and not support the other?

Good questions.

There is no need to change and rebuild the mirage firewall - for some
time it has been able to respond to standard Qubes firewall, as set in
the GUI, or qvm-firewall.

Every qube has its own implementation of iptables/nftables.
Each qube that offers network access, like sys-firewall or
mirage-firewall, also implements iptables/nftables.
When you set firewall rules in the GUI or at the command line, they
are implemented in the tables of the qubeā€™s netvm.
Each qube comes by default with a set of iptables/nftables rules, and
a set is implemented on the netvm. Usually you use the GUI or qvm-firewall
to change the ruleset upstream on the netvm, but you can also change the
internal ruleset.

I never presume to speak for the Qubes team.
When I comment in the Forum or in the mailing lists I speak for myself.
2 Likes
sudo systemctl status qubes-iptables
sudo systemctl status qubes-firewall
  • /lib/systemd/system/qubes-firewall.service runs /usr/bin/qubes-firewall
  • /usr/lib/python3/dist-packages/qubesagent/firewall.py
  • /lib/systemd/system/qubes-iptables.service ā†’ /usr/lib/qubes/init/qubes-iptables

Would be most useful if this information was in a wiki or at least website so it can be collaboratively edited to expand, improve, complete, etc.

1 Like