I have mixed feelings about this.
On the one hand, this is indeed risky. On the other hand, P2P
applications are currently crippled except in sys-net. Some protocols
can fall back to TURN servers, but that doesn’t always work and is
at best a fallback behavior. I have personally hit this problem more
than once. NAT traversal and port forwarding aren’t something
everyone needs, but for those who *do* need it, it is extremely
difficult to work around the lack of it.
IMO, port forwarding and NAT traversal should be clearly separated,
as the use-cases are extremely different. Port forwarding is used
to expose a server to the outside world, whereas NAT traversal is
used for P2P communication. Furthermore, my understanding is that
port forwarding usually needs to be persistent, whereas NAT traversal
usually does not. And port forwarding often requires a specific port
to be forwarded, whereas for NAT traversal I would not be surprised
if the system can choose the port.
I agree that allowing a qube to set up its own port forwarding is a
Bad Idea in most cases. That said, it should be possible to set up
port forwarding via the Admin API, with fine-grained access controls.
So it should be possible to express, “Qube X can request port Y
to be forwarded to it,” as a qrexec policy. In practice, however,
I expect most users to manage port forwarding from the management qube.
NAT traversal is a different matter altogether. It is already
possible for a qube and a peer that are *trying* to establish a P2P
connection to do so, by means of a brute force attack. Nobody does
this in practice, because it requires (on average) somewhere around
65536 outgoing connections from each side, which is a good way to
overload firewalls. But it can be done, assuming that all outgoing
UDP traffic is allowed. And there are a large number of applications
that need it. These applications often need to set up and tear down
connections at will.
Overall, I consider allowing qubes to request NAT traversal a net win,
provided a few restrictions are enforced:
- Only UDP forwarding may be requested. TCP is not allowed.
- Only certain ports can be forwarded. Well-known ports (anything
in /etc/services) and ports below 1024 are blocked. Ideally,
the port number should be chosen by QubesOS, rather than by the
requesting qube.
- Only the qube that made the request can receive the traffic.
Intermediate qubes, such as sys-net and sys-firewall, pass through
the traffic, but attempts to listen on the relevant port fail with
EADDRINUSE or similar.
- NAT traversal is only allowed if a certain preference has been set
via the Admin API.
Sincerely,
Demi Obenour