Skip to content

Add TPROXY inbound (TCP and UDP) - #493

Open
SafaSafari wants to merge 1 commit into
eycorsican:masterfrom
SafaSafari:feature/tproxy-inbound
Open

Add TPROXY inbound (TCP and UDP)#493
SafaSafari wants to merge 1 commit into
eycorsican:masterfrom
SafaSafari:feature/tproxy-inbound

Conversation

@SafaSafari

Copy link
Copy Markdown

Adds a Linux TPROXY inbound listener so leaf can be used as a transparent proxy via the iptables TPROXY target. The README lists TPROXY as "Coming soon"; this implements it for both TCP and UDP.

How it works

TCP — a listening socket with IP_TRANSPARENT accepts connections redirected by the TPROXY target. The original destination is simply the accepted socket's local address.

UDP — a socket with IP_TRANSPARENT + IP_RECVORIGDSTADDR receives redirected datagrams. The original destination is read from the IP_ORIGDSTADDR control message via recvmsg(2). Replies are sent from a transparent socket bound to the original destination, so the client sees the reply coming from the address it originally talked to.

Usage

Enabled by the inbound-tproxy feature (Linux only; added to all-endpoints). Configured as a JSON inbound:

{ "tag": "tproxy-in", "protocol": "tproxy", "address": "0.0.0.0", "port": 12345 }

leaf needs CAP_NET_ADMIN to open transparent sockets. The usual ip rule / ip route local / iptables TPROXY setup is required.

Testing

Verified in an isolated network-namespace setup (client ns → router ns running leaf+TPROXY → upstream): TCP transfers (256 KiB, md5-verified) and UDP datagrams were both proxied correctly, with the UDP reply source matching the original destination.

Notes

  • Linux only; the module is cfg-gated on target_os = "linux".
  • Wired into the JSON config format; the conf format is not covered.

Add a Linux TPROXY inbound listener for transparent proxying, enabled
by the `inbound-tproxy` feature and configured as an inbound with
protocol "tproxy".

TCP: a listening socket with IP_TRANSPARENT accepts connections
redirected by the iptables TPROXY target; the original destination is
the accepted socket's local address.

UDP: a socket with IP_TRANSPARENT and IP_RECVORIGDSTADDR receives
redirected datagrams; the original destination is read from the
IP_ORIGDSTADDR control message via recvmsg(2). Replies are sent from a
transparent socket bound to the original destination, so the client
sees the reply coming from the address it originally talked to.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant