Title: Script NAT on Qubes OS
Author: Solène
Date: 06 March 2024
Tags: qubesos unix network
Description: In this article, I'm sharing a script I wrote to easily
expose a given network port of a qube to the local network

# Introduction

As a daily Qubes OS user, I often feel the need to expose a port of a
given qube to my local network.  However, the process is quite painful
because it requires doing the NAT rules on each layer (usually net-vm
=> sys-firewall => qube), it's a lost of wasted time.

I wrote a simple script that should be used from dom0 that does all the
job: opening the ports on the qube, and for each NetVM, open and
redirect the ports.
Qubes OS Nat git repository
# Usage

It's quite simple to use, the hardest part will be to remember how to
copy it to dom0 (download it in a qube and use `qvm-run --pass-io` from
dom0 to retrieve it).

Make the script executable with `chmod +x nat.sh`, now if you want to
redirect the port 443 of a qube, you can run `./nat.sh qube 443 tcp`.
That's all.

Be careful, the changes ARE NOT persistent. This is on purpose, if you
want to always expose ports of a qube to your network, you should
script its netvm accordingly.

# Limitations

The script is not altering the firewall rules handled by
`qvm-firewall`, it only opens the ports and redirect them (this happens
at a different level).  This can be cumbersome for some users, but I
decided to not touch rules that are hard-coded by users in order to not
break any expectations.

Running the script should not break anything.  It works for me, but it
was only slightly tested though.

# Some useful ports

## Avahi daemon port

The avahi daemon uses the UDP port 5353.  You need this port to
discover devices on a network.  This can be particularly useful to find
network printers or scanners and use them in a dedicated qube.

# Evolutions

It could be possible to use this script in qubes-rpc, this would allow
any qube to ask for a port forwarding.  I was going to write it this
way at first, but then I thought it may be a bad idea to allow a qube
to run a dom0 script as root that requires reading some untrusted
inputs, but your mileage may vary.