Prevent Qubes OS clearnet leaks

Thanks for the guide @solene. I have made some improvements. Notably, my version runs before network-pre.target, which prevents any traffic from leaking. I have also structured it such that if something goes wrong with the nftables rules, no uplink will be brought up. There was existing support for doing this with Qubes-managed (virtual) uplinks, but the support for doing this with NetworkManager-managed (physical) interfaces was missing. I’ve now added it. Finally, this allows loopback communication.

My implementation follows @rustybird suggestion from Preventing non-Tor connections - #31 by rustybird

These files should be created in a template VM that is specifically for sys-net/sys-firewall.

/lib/systemd/system/external-output-firewall.service

[Unit]
Description=External output firewall
Before=network-pre.target
# Arbitrary order, but keeps it consistent.
Before=qubes-antispoof.service

[Service]
Type=oneshot
ExecStart=/usr/sbin/nft -f /etc/qubes/external-output-firewall.nft
# So that it never runs more than once.
RemainAfterExit=yes

[Install]
# Qubes does not follow systemd.special man page, where network-pre.target is specified passive. Instead, network-pre
# pulls units in (qubes-antispoof, qubes-iptables) and fails if they fail. This failure is then used to stop 
# qubes-network-uplink@eth0.service from activating, which stops eth0 from being brought up (unless NetworkManager is
# managing the interface).
RequiredBy=network-pre.target

/etc/qubes/external-output-firewall.nft

#!/usr/sbin/nft -f
table inet external-output-firewall {
  chain output {
    type filter hook output priority filter; policy drop;
    oifname "lo" accept
  }
}

/lib/systemd/system/NetworkManager.service.d/50_user.conf

[Unit]
# Refer to /lib/systemd/system/external-output-firewall.service. NetworkManager will configure/up interfaces that it 
# manages, so only start it if network-pre succeeded.
Requires=network-pre.target

Run sudo systemctl enable external-output-firewall.service

2 Likes