How to restrict traffic through firewall, on a single cube, only to few particular sites?

The rules for my sys-firewall are:
all 443 TCP
all 80 TCP
all 53 UDP

I wanted to filter that further for a cube. So I tried:
site1 443 TCP
site2 443 TCP
all 53 UDP

I’ve used the firewall settings window for those cubes.

Does not work. Although some sites load (slower, unsure if anything within is broken), some does not.

What is the simplest solution for that?

You can use the firewall tab in the qubes settings, and you can use the qvm-firewall command in dom0

$ qvm-firewall VMNAME reset
$ qvm-firewall VMNAME del --rule-no 0
$ qvm-firewall VMNAME add accept dsthost="SITE1" dstports=443 proto=tcp
$ qvm-firewall VMNAME add accept dsthost="SITE2" dstports=443 proto=tcp
$ qvm-firewall VMNAME add accept specialtarget=dns
$ qvm-firewall VMNAME add drop

Then verify everything with

$ qvm-firewall VMNAME 
1 Like

I’m assuming that you simplified things a little, otherwise
“some sites” does not make any sense.
Unfortunately, these days, connecting to one site usually involves
multiple connections to various other sites. It may well be that this is
your problem.
The only real solution for this is to examine the actual traffic that is
generated and to make sure that you are allowing all related traffic.
You might be surprised (and worried) by what you find.
This may be difficult for you. A simple approach might be to install
NoScript in your browser and set it to blocking mode. Then identify what
other sites are being targeted by your desired sites and allow them one
by one until you have a working site.

Another problem you likely face is that the Qubes firewall resolves
sites - if your chosen target has many potential IPs you will have to
allow them all.

I never presume to speak for the Qubes team. When I comment in the Forum or in the mailing lists I speak for myself.
1 Like

Apparently it needs to be proto=tcp instead of proto=TCP. The capital letters gave me an error.

1 Like

Another problem you likely face is that the Qubes firewall resolves
sites - if your chosen target has many potential IPs you will have to
allow them all.

Can you elaborate on this a little? Wouldn’t allowing sites (including the ones we figure out using noscript) based on domain as shown in @BEBF738VD’s post be enough? What IPs should we be authorizing?

Any domain name that you add to your qvm-firewall is resolved at once and stored as IP address. Check it out in qvm-firewall output.
When the site changes IP keeping domain - nobody will notice, but your setup will not work (because IP is outdated).

Also websites make a lot of requests to third-party domains (cloudflare and etc), you can check it in ublock origin addon in Firefox. And those third-party domains will often have a lot of IPs and change them from time to time.

Long story short: your plan is not possible to implement easily nor reliably.

1 Like

I disagree.

It’s quite an easy task to see which hosts a domain connects to and it’s fairly reliable once properly set up. I’ve had restricted VMs for a while now without issues.

Plus, one can always re-create the rules if the website is updated to make new requests, not an issue.

Long story short: this shouldn’t discourage users to harden their setups.

Thanks @fsflover, I was hoping for an alternative solution.

@BEBF738VD How did you achieve it? How to find which hosts a domain connects to?

@unman I checked generic websites like facebook, feedly, etc., so I can test. What I got is feedly connect without problems, facebook stop loading with fbcdn.net showing in the loading bar then just show plain non stylized text, other sites directly show me “Unable to connect”, like the ones not in the firewall settings.

This is due to what you mentioned, but I will quote a clearer explanation:

1 Like

I tested for few days. Will post “solution” for that case, as alternative to the tinyproxy method. One little thing is left.

Some parts of some sites (coming from different source) are changing IPs too frequently. As address is taken once, I need to reset.

Is there an easy way with a command like qvm-firewall to take new IP or basic deleting and adding it again is how it works?

I’m intending to create a small script with qvm-firewall rules, for those frequently changing ones, which will execute on each boot. (if that pose a security risk, let me know)

Do you mean something like:

qvm-firewall VMNAME del --rule-no RULE_NO

It’s easy enough to grep the rule number corresponding to the IP you want to remove.

Aside from the responses of @unman & @balko, I disagree with most posted. I could be wrong but, IMO you’re trying to use the wrong tool for the job which, more often than not leads to a poor job. Essentially you’re planning to fail.

I “think” what you are seeking is an application-layer aka L7 (Layer-7) firewall whereas ip/nfables are network-layer aka L3 (Layer-3).


There’s many L7 options these days but, I bet OpenSnitch will be your buddy.

2 Likes

@cayce
I wanted to restrict all the traffic of a particular cube to 1 or few websites. That is all, nothing more going in or out, ideally. By taking the most minimalistic approach possible. Which is using what I have at hand, the integrated cube firewall.

The only problem is that it resolves the domain to IP the first time, and if that changes does not work, as mentioned by few users.

@BEBF738VD
What I asked next was, if there is a something like:

qvm-run “refresh” rule no3 (which consists of allowing 443 to site1.com)

or the only way is to del and then add the rule again. Practically I was looking for 1 line of code instead of 2, per rule.

Example part of site1 and site2 does not work, so I automate with script at each boot:

del sub.site1.com
add sub.site1.com
del sub.site2.com
add sub.site2.com

Ideally:
refresh sub.site1.com rule
refresh sub.site2.com rule

According to man qvm-firewall the only available actions are {add,del,list,reset}.

There is however a --reload option (force reload of rules even when unchanged). Not sure if that’ll do.