Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature Request] Make client IP accessible to upstream by spoofing source IP #4184

Open
1 of 11 tasks
dong-zeyu opened this issue Apr 27, 2024 · 2 comments
Open
1 of 11 tasks
Labels

Comments

@dong-zeyu
Copy link
Contributor

Describe the feature request

As a reverse proxy, FRP currently supports two ways for the upstream server to obtain the client's real IP: HTTP X-Forwarded-For and Proxy Protocol. The former only supports HTTP protocol and the latter supports generic TCP connection but would require support for uptream. My current solution for upstreams that do not support proxy protocol is to use mmproxy or go-mmproxy to wrap the bare TCP with the proxy protocol. However, this requires configuring additional programs and upstream ports and also introduces overhead to copy data between the processes.

Describe alternatives you've considered

The underlying technology that mmproxy uses is TPROXY supported by the Linux kernel. This can be easily implemented in Go by a few lines of code (I referred to go-mmproxy)

dialer := net.Dialer{LocalAddr: saddr}
dialer.Control = func(network, address string, c syscall.RawConn) error {
    return c.Control(func(fd uintptr) {
        syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_TRANSPARENT, 1)
    })
}

saddr is the remote client address obtained from the FRP server. Then the upstream will be connected as if it is directly connected from the IP address of the remote client.

By doing so, the FRP client would support spoofing the client IP to the upstream out-of-box, without further configuration to the upstream or running additional programs.

However, this functionality still has certain limitations: first, this would only work on the Linux system as far as I know; second, configurations to the Linux firewall/routing is still needed (these configurations are global and do not need to be set separately for each service); third, CAP_NET_ADMIN capability is required to set IP_TRANSPARENT socket opt.

I have a simple PoC for this feature in my fork, but maybe more work is needed to make it into the FRP.

Affected area

  • Docs
  • Installation
  • Performance and Scalability
  • Security
  • User Experience
  • Test and Release
  • Developer Infrastructure
  • Client Plugin
  • Server Plugin
  • Extensions
  • Others
@dong-zeyu dong-zeyu changed the title [Feature Request] Transparent proxy support to inform client real IP to upstream server [Feature Request] Transparent proxy support to inform upstream client real IP Apr 27, 2024
@dong-zeyu dong-zeyu changed the title [Feature Request] Transparent proxy support to inform upstream client real IP [Feature Request] Make client IP accessible to upstream by spoofing source IP Apr 27, 2024
@fatedier
Copy link
Owner

However, this functionality still has certain limitations: first, this would only work on the Linux system as far as I know; second, configurations to the Linux firewall/routing is still needed (these configurations are global and do not need to be set separately for each service); third, CAP_NET_ADMIN capability is required to set IP_TRANSPARENT socket opt.

This is one of the reasons we were not too keen on introducing related features before.

Currently, it may be a wiser choice to combine more professional tools.

I hope to see more practical demand scenarios. Changes in this area will only be considered after we have made progress in the refactoring and optimization of our core architecture.

@crabdancing
Copy link

One reason this feature is potentially important is that the company I work for is interested in localizing the TLS encryption to the backend server, with the less trusted proxy essentially functioning as a dumb pipe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants