Closed xbc5 closed 1 year ago
I should note that I could write a daemon (in Go) for the external approach. I am just not sure how it would interface with the firewall exactly.
Hi, thanks for that suggestion.
The Qubes security model is to have a white list rules and a default drop policy (and I see black list strategy lowering the security model as you can miss that your list is out of date).
I think you can achieve your goal with qvm-firewall
calls in dom0: you can create a script from an appvm, and upload it to dom0 to filter access of the firewall to appropriate IPs.
I think you can achieve your goal with qvm-firewall calls in dom0: you can create a script from an appvm, and upload it to dom0 to filter access of the firewall to appropriate IPs.
@palainp that is possible (and I do that myself) but it's very slow. It also requires pulling large lists into dom0, which is frowned upon by the Qubes team. It is probably possible to use a dedicated management VM and a disposable VM for that specific task alone, it's something I need to look into.
The Qubes security model is to have a white list rules and a default drop policy (and I see black list strategy lowering the security model as you can miss that your list is out of date).
That's my approach right now for domains that I want to lock down to a single service (e.g. IRC; although I am unaware of how to get a TLS resolver working). However, on more general systems (like untrusted) it doesn't make sense to do that.
I will likely research how to load large lists via management VM and QubesDB.
I'm not on my computer right now for testing so I may be wrong. In order to reduce the rules list, it may be possible to register your banned IPs with a drop action and at the end add a wildcard accept action? The online manpage seems to permit that.
Yeah that works, it won't reduce the size of the rule set thought.
The only issue I take with the Qubes firewall as it is, is performance and convenience. The current implementation is clunky, slow, and only useful for basic firewalling. I just thought some extra features in the firewall would be nice.
Perhaps this is a Qubes issue in fact. I should raise a ticket there instead.
The current implementation for filtering packets is O(n) with n the rules list size. With a really long list it's certainly slow :( I'm not sure how to improve that here, as the rules set is read only on startup or on updates, so the list is in memory when a packet arrives.
I see. I should ask these question on the Qubes dev forums/mailing list to be honest.
Would 1 million entries (~16MB) badly affect (runtime) filtering performance? (I am trying to gauge whether my effort will be worth it)
Closing this issue then.
I got my laptop back and now I guess I can imagine what you called slowiness :) I tried to create a list of drop rules and adding a wildcard accept at the end with the following script:
#!/bin/env sh
printf "#!/bin/env sh\n"
for b2 in `seq 16 31` ; do
for b3 in `seq 0 255` ; do
for b4 in `seq 0 4 255` ; do
printf "qvm-firewall perso add drop 172.%d.%d.%d/30\n" $b2 $b3 $b4
done
done
done
printf "qvm-firewall perso add accept\n"
This should produce less than a million: 2^18 rules (it doesn't matter if the networks are in RFC 1918 as the firewall will check if a packet belong to any of those anyway), but I first tried with 500 rules and 2400 rules:
$ wc -l rules_list.sh
578 rules_list.sh
$ time ./rules_list.sh
real 1m15.999s
user 0m30.876s
sys 0m10.164s
The 2400 rules listing failed after 7 minutes before adding 2000 rules (I may have missed something here but haven't time for investigations :/) with Got empty response from qubesd. See journalctl in dom0 for details.
and journalctl saying dom0 qubesd[2304]: request too long
.
So now I still think the correct setup for that use case is using Qubes firewall ruleset but I wonder if Qubes support large rulesets. The other approach could be to create a separate specialised unikernel that takes a network list / file as argument and nat everything (not) included in that list (this can be independent from Qubes and take its roots from https://github.com/mirage/mirage-nat/tree/main/example).
The other approach could be to create a separate specialised unikernel that takes a network list / file as argument and nat everything (not) included in that list (this can be independent from Qubes and take its roots from https://github.com/mirage/mirage-nat/tree/main/example).
I'd love to, but I don't know OCaml or Mirage (yet; but it's on my TODO list). I will raise an issue with Qubes because it seems like the right place for such a feature request. I will come back to this thread one day with an answer.
Thanks for your help.
Is it feasible to to implement a self-updating IP/domain whitelist/blacklist?
Context: A self-updating blocklist manager.
Use case: Prevent/allow egress/ingress connections to single IPs and IP blocks. For example a country block, or blocks assigned to corporations. Additionally, resolve domain names to IPs (at time of use) to support domain blacklisting/whitelisting.
Requirements:
There are two possible approaches:
Drawbacks:
Questions: