Qubes OS 4.2 nftables / nft firewall guide

Hi!

I started fiddling with NFT on Qubes OS 4.2 and the official documentation is quite bad in this area. Let’s gather material here so we could enhance the documentation once we have enough content.

Port forwarding from outside to a qube

I got port forwarding to work, that wasn’t easy as the default ruleset didn’t have a chain for the nat rules. I made a simple script where you just have to fill the port and the destination.

Typically, you would do:

  • run the snippet Forwarding in sys-net using sys-firewall IP as a destination
  • run the snippet Forwarding in sys-firewall using the qube IP as a destination
  • run the snippet Accept only in the destination qube

This is an example for a TCP redirection, for UDP you would have to replace tcp by udp.

Forwarding

#!/bin/sh

PORT=8000
DESTINATION=10.138.0.52

if ! nft -nn list table ip qubes | grep "chain nat {" ; then
    nft add chain qubes nat { type nat hook prerouting priority dstnat\; }
fi
nft add rule qubes custom-input tcp dport "${PORT}" accept
nft add rule qubes custom-forward tcp dport "${PORT}" accept
nft add rule qubes nat iifname != "vif*" tcp dport "${PORT}" dnat "${DESTINATION}"

Accept only

#!/bin/sh

PORT=8000

nft add rule qubes custom-input tcp dport "${PORT}" accept
5 Likes

I tried to run chiaki (Remote Play program for a Playstation 5 or 4) from a qube, works great :+1:

Lot of firewall required, that was a good real world problem to solve :smiley:

1 Like

What kind of firewall rules are missing in their nftables equivalent?

if I want to connect qube1 and qube2, will this work by running forwarding in qube1, and accept in qube2?

i don’t need port forwarding to outside, but between my qubes.

also, does it work for standalone qubes as well? thanks :smile:

I didn’t try yet, but from the current documentation, that the same steps except:

  • you would need to forward only for a source address (otherwise all the other qubes would be allowed to reach that qube) AND only forward for internal qubes interfaces, so the rule would be a bit different, maybe something like this
#!/bin/sh

# allows qube $SOURCE to reach $DESTINATION on port $PORT
PORT=8000
DESTINATION=10.137.0.16
SOURCE=10.137.0.15

if ! nft -nn list table ip qubes | grep "chain nat {" ; then
    nft add chain qubes nat { type nat hook prerouting priority dstnat\; }
fi
nft add rule qubes custom-input ip saddr "${SOURCE}" tcp dport "${PORT}" accept
nft add rule qubes custom-forward ip saddr "${SOURCE}" tcp dport "${PORT}" accept
nft add rule qubes nat iifname "vif*" tcp dport "${PORT}" dnat "${DESTINATION}"

  • you don’t need to do anything in sys-net

It’s working fine with the script above on sys-firewall :ok_hand:

In the destination qube, don’t forget to allow the port using nft add rule qubes custom-input tcp dport 8000 accept