Skip to content

[WIP] Rootless bridge: preserve source IPs via pesto/pasta#28478

Draft
Honny1 wants to merge 3 commits intocontainers:mainfrom
Honny1:pesto-support
Draft

[WIP] Rootless bridge: preserve source IPs via pesto/pasta#28478
Honny1 wants to merge 3 commits intocontainers:mainfrom
Honny1:pesto-support

Conversation

@Honny1
Copy link
Copy Markdown
Member

@Honny1 Honny1 commented Apr 9, 2026

Require passta version: tbd

Local Passt Setup

# Build pasta with pesto support
git clone git://passt.top/passt && cd passt
git checkout bc872d91765d
b4 shazam https://archives.passt.top/passt-dev/20260323073732.3158468-1-david@gibson.dropbear.id.au/
make && sudo make install

TODO:

Replace rootlessport with pesto for rootless bridge network port forwarding, preserving source IPs.

I did the replacement since the target is 6.0, and I didn't bother providing both ways. But probably it should be part of dissuasion.

Problem

When running rootless containers on a bridge network (podman run -p 8080:80 --network mynet), the old rootlessport userspace TCP/UDP proxy destroyed source IP information. Every connection appeared to come from 127.0.0.1 inside the container, regardless of the actual client IP.

Solution

Pesto is a client tool for passta that dynamically updates port forwarding rules via a UNIX domain socket. Instead of proxying traffic in userspace (which loses source IPs), pesto configures pasta to forward at the kernel level using splice (localhost) or TAP (external traffic), preserving the original source IP.

How it works

Host -> pasta (splice/TAP) -> rootless netns -> netavark bridge DNAT -> container
  1. A shared pasta instance runs in the rootless network namespace with a control socket (-c pasta.sock)
  2. On container start: netavark sets up the bridge + nftables DNAT rules, then pesto replaces pasta's entire forwarding table with the aggregate ports of all running bridge containers
  3. On container stop: pesto updates the table without the stopped container's ports, then netavark tears down bridge/DNAT
  4. On network connect/disconnect/reload: pesto replaces the table to reflect the new state

Key implementation details:

  • portMappingsForNetavark() strips HostIP from port mappings before passing them to netavark in rootless mode. Pesto handles host-side address binding via pasta; netavark's DNAT rules inside the rootless netns must not restrict on destination address since pasta's splice delivers traffic with a different address than the user-specified HostIP
  • ensureLoopbackSetmark() inserts an nftables rule so localhost-originated traffic (src 127.0.0.0/8) is properly masqueraded through the bridge, required because pasta's splice path delivers packets with loopback source addresses
  • route_localnet=1 sysctl is set once per rootless netns lifetime so the kernel allows routing of 127.x.x.x-sourced packets to non-loopback interfaces

Current limitations

  • IPv4 only (netavark DNAT is IPv4; pesto binds 0.0.0.0 by default)
  • Full table replacement per change (brief forwarding gap, possible races with many containers)
  • Loopback SETMARK rule directly manipulates netavark's nftables chains
  • gatherAllRootlessBridgePorts reads all containers from DB without locks

Fixes: https://redhat.atlassian.net/browse/RUN-2214
Fixes: #8193
Fixes: https://redhat.atlassian.net/browse/RUN-3587

Depends on: passta version tbd
Depends on: containers/container-libs#755
Depends on: #27828
Depends on: #28451

Checklist

Ensure you have completed the following checklist for your pull request to be reviewed:

  • Certify you wrote the patch or otherwise have the right to pass it on as an open-source patch by signing all
    commits. (git commit -s). (If needed, use git commit -s --amend). The author email must match
    the sign-off email address. See CONTRIBUTING.md
    for more information.
  • Referenced issues using Fixes: #00000 in commit message (if applicable)
  • Tests have been added/updated (or no tests are needed)
  • Documentation has been updated (or no documentation changes are needed)
  • All commits pass make validatepr (format/lint checks)
  • Release note entered in the section below (or None if no user-facing changes)

Does this PR introduce a user-facing change?

Rootless bridge network port forwarding now preserves source IPs. Previously, all connections appeared from 127.0.0.1 inside the container due to rootlessport's userspace proxy. Podman now uses pesto to configure pasta's kernel-level forwarding, so containers see the real client IP address.

Honny1 added 3 commits April 9, 2026 18:46
TODO: vendor container-libs

Signed-off-by: Jan Rodák <hony.com@seznam.cz>
Pesto dynamically updates pasta's forwarding table via UNIX socket,
preserving source IPs that rootlessport's userspace proxy destroyed.

Strip HostIP from port mappings passed to netavark in rootless mode
(portMappingsForNetavark) because pesto handles host-side address
binding via pasta. Netavark's DNAT rules inside the rootless netns
must not restrict on destination address since pasta's splice delivers
traffic with a different address than the user-specified HostIP.
Pesto receives the original HostIP so pasta binds correctly on the
host.

Fixes: https://redhat.atlassian.net/browse/RUN-2214
Fixes: containers#8193
Fixes: https://redhat.atlassian.net/browse/RUN-3587

Signed-off-by: Jan Rodák <hony.com@seznam.cz>
Delete networking_rootlessport.go, rootlessPortSync pipes, and the
reloadRootlessRLKPortMapping stub.

Signed-off-by: Jan Rodák <hony.com@seznam.cz>
@Honny1 Honny1 changed the title Rootless bridge: preserve source IPs via pesto/pasta [WIP] Rootless bridge: preserve source IPs via pesto/pasta Apr 9, 2026
@packit-as-a-service
Copy link
Copy Markdown

[NON-BLOCKING] Packit jobs failed. @containers/packit-build please check. Everyone else, feel free to ignore.

1 similar comment
@packit-as-a-service
Copy link
Copy Markdown

[NON-BLOCKING] Packit jobs failed. @containers/packit-build please check. Everyone else, feel free to ignore.

@Honny1 Honny1 added rootless pasta pasta(1) bugs or features 6.0 Breaking changes for Podman 6.0 labels Apr 10, 2026
@Honny1
Copy link
Copy Markdown
Member Author

Honny1 commented Apr 10, 2026

Question for reviewers: Should the option for rootlessport exist, or can it be dropped fully?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

6.0 Breaking changes for Podman 6.0 pasta pasta(1) bugs or features rootless

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Alternate port_handler that keeps the source ip for user-defined rootless networks

1 participant