libp2p / go-libp2p

libp2p implementation in Go
MIT License
6.03k stars 1.06k forks source link

websocket: record X-Real-IP header #1437

Open magik6k opened 5 years ago

magik6k commented 5 years ago

We currently don't support TLS here, so a reverse proxy needs to be set up, which has the side effect of loosing real ip addresses in ipfs swarm peers.

We could check if the X-Real-IP header is set when accepting connections and change the ip address we report as the remote (and probably only do that when we proxy from localhost)

Jorropo commented 5 years ago

That also should come with a way to set trusted reverse proxy because else someone could do a real ws conn with a X-Real-IP and change his ip to someone else for you. (the reverse proxy would be an ip or ip range (/ip4/127.0.0.1 by default) and if the connection is made via here we can know X-Real-IP should be real)

MarcoPolo commented 1 year ago

Here's how I think we could implement this:

snichols commented 5 months ago

Another issue that comes from using a proxy is that the host thinks that remote websocket connections are coming from localhost which causes the identify protocol to share private addresses with websocket peers. When this happens, browser peers react poorly and refuse to connect to the proxied peer after identify is completed. I'm still narrowing down that piece and will report to the libp2p-js repo.

Relevant filtering code in identify: https://github.com/libp2p/go-libp2p/blob/be32b5ba0d7fc08135a27193d00f94808f0d828c/p2p/protocol/identify/id.go#L999

That being said, this issue is a thorn in the side of anyone that wants to easily provide browser-friendly websocket transports. I'm using ngrok -> nginx -> libp2p to wrangle my web traffic. This would be exacerbated if I were deploying to Kubernetes as web ingress relies on standard proxying to communicate details about the external connection. Accepting standard headers seems like a necessary feature to me and would help make adoption of libp2p easier in production environments, IMO.

@MarcoPolo has the right idea here. Trust the header when coming from a private network. Optionally add a config setting for fine-grained control over the behavior.