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

Plug.Conn also has get_peer_data, which returns the original ip #32

Closed
dvic opened this issue Nov 15, 2022 · 3 comments
Closed

Plug.Conn also has get_peer_data, which returns the original ip #32

dvic opened this issue Nov 15, 2022 · 3 comments

Comments

@dvic
Copy link

dvic commented Nov 15, 2022

I realised with a LiveView project that overwriting the remote_ip is not enough because Plug.Conn has a get_peer_data function and that's what's being called by LiveView. This value is

@type peer_data :: %{
          address: :inet.ip_address(),
          port: :inet.port_number(),
          ssl_cert: binary | nil
        }

What is the way forward here? Wrap the adapter implementation and wrap the get_peer_data to override the ip?

@dvic
Copy link
Author

dvic commented Nov 15, 2022

@ajvondrak
Copy link
Owner

Taking plug_cowboy as our canonical implementation, the way it works:

So ultimately, with a given Plug.Conn, the way we'd override the info returned by Plug.Conn.get_peer_data/1 would have to be adapter-specific. For Cowboy, this would involve manipulating the :peer key of the underlying conn.adapter payload (the Cowboy Req).

I believe clobbering this value would be a bad idea. My impression is that this data is used by Cowboy to actually orchestrate the HTTP response, which is why Plug.Conn exposes the :remote_ip as a separate entity that's meant to be overwritten.

I'm also under the impression that Phoenix LiveView relies on this "raw" data because of the low-level manipulation of sockets that it has to do. I'm unsure about those details.

The general workaround for this is to pass the forwarding headers to RemoteIp.from/2 in your Phoenix sockets, as sketched in the docs: https://hexdocs.pm/remote_ip/RemoteIp.html#module-usage I don't know enough about Phoenix to provide any more in-depth guidance than that. 😅

One of the main issues people have bumped into with this is that Phoenix sockets only expose the x- headers, which won't work so well if you're using a header like Forwarded or Fly-Client-IP. There has been some amount of discussion within Phoenix about exposing more data, but I take it there are security concerns:

Given all that, I'm inclined to close this issue, since (a) I don't think we should be clobbering the raw peer data and (b) getting the right information for RemoteIp.from/2 to work (e.g., non-x- headers) would need to be solved on the Phoenix end. Let me know if you think differently, though.

@dvic
Copy link
Author

dvic commented Nov 15, 2022

Thanks for the elaborate response!

RemoteIp.from/2 will work for us because we're dealing with the x-forwarded-for header (Google Cloud k8s ingress).

I believe clobbering this value would be a bad idea. My impression is that this data is used by Cowboy to actually orchestrate the HTTP response, which is why Plug.Conn exposes the :remote_ip as a separate entity that's meant to be overwritten.

I did not think of this, then indeed it's a bad idea. We can go ahead and close this issue. Once again, thanks for the explanation 👍

@dvic dvic closed this as completed Nov 15, 2022
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

No branches or pull requests

2 participants