aboutgitcodebugslistschat
path: root/fwd.c
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2024-10-18 12:35:56 +1100
committerStefano Brivio <sbrivio@redhat.com>2024-10-18 20:28:03 +0200
commitb4dace8f462b346ae2135af1f8d681a99a849a5f (patch)
tree2c15016a302582cad72c37ec1bfe5f541b5c555d /fwd.c
parent58e6d685995f7b1068357a00e2618627d17fa8f5 (diff)
downloadpasst-b4dace8f462b346ae2135af1f8d681a99a849a5f.tar
passt-b4dace8f462b346ae2135af1f8d681a99a849a5f.tar.gz
passt-b4dace8f462b346ae2135af1f8d681a99a849a5f.tar.bz2
passt-b4dace8f462b346ae2135af1f8d681a99a849a5f.tar.lz
passt-b4dace8f462b346ae2135af1f8d681a99a849a5f.tar.xz
passt-b4dace8f462b346ae2135af1f8d681a99a849a5f.tar.zst
passt-b4dace8f462b346ae2135af1f8d681a99a849a5f.zip
fwd: Direct inbound spliced forwards to the guest's external address
In pasta mode, where addressing permits we "splice" connections, forwarding directly from host socket to guest/container socket without any L2 or L3 processing. This gives us a very large performance improvement when it's possible. Since the traffic is from a local socket within the guest, it will go over the guest's 'lo' interface, and accordingly we set the guest side address to be the loopback address. However this has a surprising side effect: sometimes guests will run services that are only supposed to be used within the guest and are therefore bound to only 127.0.0.1 and/or ::1. pasta's forwarding exposes those services to the host, which isn't generally what we want. Correct this by instead forwarding inbound "splice" flows to the guest's external address. Link: https://github.com/containers/podman/issues/24045 Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'fwd.c')
-rw-r--r--fwd.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/fwd.c b/fwd.c
index a505098..c71f5e1 100644
--- a/fwd.c
+++ b/fwd.c
@@ -447,20 +447,35 @@ uint8_t fwd_nat_from_host(const struct ctx *c, uint8_t proto,
(proto == IPPROTO_TCP || proto == IPPROTO_UDP)) {
/* spliceable */
- /* Preserve the specific loopback adddress used, but let the
- * kernel pick a source port on the target side
+ /* The traffic will go over the guest's 'lo' interface, but by
+ * default use its external address, so we don't inadvertently
+ * expose services that listen only on the guest's loopback
+ * address. That can be overridden by --host-lo-to-ns-lo which
+ * will instead forward to the loopback address in the guest.
+ *
+ * In either case, let the kernel pick the source address to
+ * match.
*/
- tgt->oaddr = ini->eaddr;
+ if (inany_v4(&ini->eaddr)) {
+ if (c->host_lo_to_ns_lo)
+ tgt->eaddr = inany_loopback4;
+ else
+ tgt->eaddr = inany_from_v4(c->ip4.addr_seen);
+ tgt->oaddr = inany_any4;
+ } else {
+ if (c->host_lo_to_ns_lo)
+ tgt->eaddr = inany_loopback6;
+ else
+ tgt->eaddr.a6 = c->ip6.addr_seen;
+ tgt->oaddr = inany_any6;
+ }
+
+ /* Let the kernel pick source port */
tgt->oport = 0;
if (proto == IPPROTO_UDP)
/* But for UDP preserve the source port */
tgt->oport = ini->eport;
- if (inany_v4(&ini->eaddr))
- tgt->eaddr = inany_loopback4;
- else
- tgt->eaddr = inany_loopback6;
-
return PIF_SPLICE;
}