-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Hi all,
We want to somehow rework firewall ~~VM~~ qube interface in Qubes 4.0,
because the current implementation have some limitations. Some of us
already talked about it on 32c3, but I think it would be good to have
also input from others not present there. But first, some background
info:
Firewall purpose, goals
=======================
- prevent user mistakes, like opening links directly in mail ~~VM~~ qube
- mitigate software errors, like using http instead of https somewhere
Non-goals:
- ----------
- prevent compromised ~~VM~~ qube from leaking the data
- filter incoming traffic (technically it is also firewall task, but
not part of the interface discussed here, at least not directly)
Current features
================
- generally all that is available in VM firewall tab, so:
- default policy: accept / deny
- list of exceptions from that policy, for each entry it is possible to
specify:
- host or IP (optionally with netmask)
- protocol tcp, udp or "any"
- in case of tcp/udp - also port number
- separate option for allowing DNS traffic
- separate option for ICMP traffic
- "Allow connections to Updates Proxy"
- "Allow full acccess for X min"
Current implementation
======================
- firewall rules are converted to iptables script in dom0
- iptables scripts is saved to QubesDB of directly connected ProxyVM,
one entry for every VM (but all the rules as a single entry)
- there is /qubes-iptables-header - with some common header
- and /qubes-iptables-domainrules/<ID> - entry for rules for a given
VM
- qubes-firewall service in ProxyVM monitor QubesDB and apply the rules
when new are available
- all the special rules (ICMP/DNS/Updates Proxy) are embedded in that
iptables script, using addresses known to dom0 (for example Updates
Proxy has predefined address
10.137.255.254:8082)
- if there are any temporary rules ("Allow full access for ..."),
firewall reload is scheduled after that time, using systemd timer
(this part currently doesn't work reliable: #1173
- firewall rules in dom0 are saved in separate file firewall.xml, in VM
directory (this isn't part of the discussion here, just for
reference)
Limitations of current implementation
=====================================
- it is highly Linux/iptables specific, from VM point of view, hard to
use other implementations (*BSD, unikernels like MirageOS)
- hard to customize - if user want add non-standard rule, there is
/rw/config/qubes-firewall-user-script, but adding some rules in the
middle of FORWARD chain is hard (you can add at the beginning, but
it isn't always enough - #1183)
- finally, QubesDB has limit of 3kb for one entry - it means about 35
rules per VM (#1570)
Current proposal
================
- use a simple for rules in QubesDB
- convert the rules to iptables/whatever in ProxyVM
- integrate ICMP and DNS rules as standard rules, not a special case
- rule format proposal:
"allow/deny <target> <proto> [<port>]"
- allow/deny - should the connection to the target be allowed or
denied (somehow redundant to the default action)
- <target> - target IP address (possibly with netmask like "/22") or
name, or "*"
- <proto> - one of: tcp, udp, icmp, any
- in case of tcp/udp, there would be also <port> - a port number, or
"*"
- in QubesDB, save the rules as:
/qubes-firewall/<domain-ID>/default-action - "allow" or "deny"
/qubes-firewall/<domain-ID>/rules/XXX - actual rules, each as a
separate entry, where XXX is 3-digit rule number (so a maximum of
1000 rules)
- Linux specific: place rules for each VM into separate iptables chain,
to ease customizations (#974)
- convert updates proxy connection to qrexec service - see below
Questions
- ---------
- do we want to support port ranges?
- do we want any special treatment for DNS? The problem here is target
IP - dom0 may not know it (for example in case of custom VPN-provided
DNS - #1183). So I see two practical options:
- translate "Allow DNS" to a rule "allow * udp 53" + "allow * tcp 53"
- add a virtual protocol "DNS", which would be translated to
appropriate rule(s) by the ProxyVM (base on its /etc/resolv.conf,
or so)
* I think in the discussion on 32c3 we were for the first option
- anything else missing/wrong in the above proposal?
Details of qrexec-based updates proxy
- -------------------------------------
It would be socat/systemd.socket listening in TemplateVM on loopback
interface and package manager configured to connect to this address. As
a "backend" it would call qrexec-client-vm to initiate connection to
UpdateVM and connect to HTTP proxy there. UpdateVM still would have
tinyproxy to handle that traffic, the only changed part is underlying
connection transport - qrexec instead of TCP. But with such a small
change we get a lot of benefits:
- TemplateVM now may have no direct access to the network, which
eliminate the whole TCP/IP stack from attack vector (but still
leaving package manager - so some HTTP(S), which is admittedly more
concerning...)
- we can use any VM as a target here, using UpdateVM (the VM for dom0
updates) would be logical choice, but it may be different; this VM no
longer needs to on "network path between TemplateVM and the internet"
- no more problems with chaining proxies - like putting VPN VM, or
TorVM in between (which in the current implementation breaks the
connection in most cases)
- TemplateVM may even not know the name of target VM, thanks to ability
to redirect qrexec connection in policy (not sure if worth using it
in practice here)
- --
Best Regards,
Marek Marczykowski-Górecki
Invisible Things Lab
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2
iQEcBAEBCAAGBQJWl87xAAoJENuP0xzK19csijkH/jVjldwvPNFveWlAMULFlYgi
lBT/HESuDqBzXzm3pBDcKnwzDhhXHlVp6L6igJqEUpBe88hZp2hwvNeMntjvpqFa
c3XKUoFr66+1NYCl6+XpQmaFwmw6CX5LvhoxeEkDtcAKCRzwHaW3XytkkjZRHYus
mAAE5oI/zKPYplBeh9Si9NSnsyfIt/wOrjNjXsvUm9LhNkWRjKjuYApPLhbuECS3
ntWE3Sgs9fVvfJK9766Tm5KtiH35dR7m+vMd3X1cGV6CiXhLmOFwN46oRwMFpqgs
F/eOc/LJo+HGIjPAsnZXCb16N+doXF465Xc4L1ZDZbrTjhh0CjsOurV5Ipb+KMg=
=3QXO
-----END PGP SIGNATURE-----