[PATCH v2 0/3] Probe host's ephemeral ports, rather than using RFC values
As discussed on our recent call, this implements basing which ports we consider "ephemeral" on probing the host's settings, rather than just assuming the RFC 6335 recommended values, which are not what Linux uses by default. I think this is more correct, but additionally using the Linux values means we consider more ports ephemeral, reducing kernel memory consumption for -t all -u all. Changes in v2: * Add missing close() for the sysctl file David Gibson (3): conf, fwd: Make ephemeral port logic more flexible conf, fwd: Don't attempt to forward port 0 fwd, conf: Probe host's ephemeral ports conf.c | 19 +++++++++++---- fwd.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ fwd.h | 3 +++ util.h | 3 --- 4 files changed, 92 insertions(+), 7 deletions(-) -- 2.46.0
"Ephemeral" ports are those which the kernel may allocate as local
port numbers for outgoing connections or datagrams. Because of that,
they're generally not good choices for listening servers to bind to.
Thefore when using -t all, -u all or exclude-only ranges, we map only
non-ephemeral ports. Our logic for this is a bit rigid though: we
assume the ephemeral ports are always a fixed range at the top of the
port number space. We also assume PORT_EPHEMERAL_MIN is a multiple of
8, or we won't set the forward bitmap correctly.
Make the logic in conf.c more flexible, using a helper moved into
fwd.[ch], although we don't change which ports we consider ephemeral
(yet).
The new handling is undoubtedly more computationally expensive, but
since it's a once-off operation at start off, I don't think it really
matters.
Signed-off-by: David Gibson
Nit:
On Thu, 29 Aug 2024 11:32:40 +1000
David Gibson
+/* Empheral port range: values from RFC 6335 */ +static const uint16_t fwd_ephemeral_min = (1 << 15) + (1 << 14); +static const uint16_t fwd_ephemeral_max = NUM_PORTS - 1;
Maybe you could use in_port_t instead, just for consistency with (almost) everything else, no advantages otherwise. -- Stefano
On Thu, Aug 29, 2024 at 06:59:05AM +0200, Stefano Brivio wrote:
Nit:
On Thu, 29 Aug 2024 11:32:40 +1000 David Gibson
wrote: +/* Empheral port range: values from RFC 6335 */ +static const uint16_t fwd_ephemeral_min = (1 << 15) + (1 << 14); +static const uint16_t fwd_ephemeral_max = NUM_PORTS - 1;
Maybe you could use in_port_t instead, just for consistency with (almost) everything else, no advantages otherwise.
Duh, of course. -- David Gibson (he or they) | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you, not the other way | around. http://www.ozlabs.org/~dgibson
When using -t all, -u all or exclude-only ranges, we'll attempt to forward
all non-ephemeral port numbers, including port 0. However, this won't work
as intended: bind() treats a zero port not as literal port 0, but as
"pick a port for me". Because of the special meaning of port 0, we mostly
outright exclude it in our handling.
Do the same for setting up forwards, not attempting to forward for port 0.
Signed-off-by: David Gibson
When we forward "all" ports (-t all or -u all), or use an exclude-only
range, we don't actually forward *all* ports - that wouln't leave local
ports to use for outgoing connections. Rather we forward all non-ephemeral
ports - those that won't be used for outgoing connections or datagrams.
Currently we assume the range of ephemeral ports is that recommended by
RFC 6335, 49152-65535. However, that's not the range used by default on
Linux, 32768-60999 but configurable with the net.ipv4.ip_local_port_range
sysctl.
We can't really know what range the guest will consider ephemeral, but if
it differs too much from the host it's likely to cause problems we can't
avoid anyway. So, using the host's ephemeral range is a better guess than
using the RFC 6335 range.
Therefore, add logic to probe the host's ephemeral range, falling back to
the RFC 6335 range if that fails. This has the bonus advantage of
reducing the number of ports bound by -t all -u all on most Linux machines
thereby reducing kernel memory usage. Specifically this reduces kernel
memory usage with -t all -u all from ~380MiB to ~289MiB.
Signed-off-by: David Gibson
participants (2)
-
David Gibson
-
Stefano Brivio