How to get real client ip behind docker load balancer using plain tcp?

Viewed 585

What I want

I want to get client's IP in my TCP server and use it to whitelist/bind actions, detect regions (for language and currency), etc.

How I approached it

I'm using TornadoWeb framework for python to set up my tcp server.

It contains TCPServer.handler_stream(stream: IOStream, address: tuple[str, int]) from where i can get a hand on client's IP address. It's all good when running with host network (i.e. exposing my ports directly)

Problem

If launched multiple tasks (containers) in docker swarm, and therefore use docker's load balancer, client's IP address gets replaced with docker's inner one.

Question

How do i configure docker swarm or another load balancer to somehow send real client's ip to my server?

I'm not particularly bound to one piece of software or another, nor do i know which is better, the only thing I wouldn't consider - is using Kubernetes (not now at least), so any suggestion on software rather than configuration are also welcome!

Client and server can be altered, so other techniques I could use regardless of protocol itself will also be useful. However, something like using HTTPs requests to gather IP address via X-Forwarded-For or X-Real-IP headers is possible, but i'd like to refrain myself from it.

2 Answers

How do i configure docker swarm or another load balancer to somehow send real client's ip to my server?

Docker has already an open issue for that, see https://github.com/docker/roadmap/issues/157 . It is currently not possible to do any configuration to do that.

As you already mentioned earlier, you will have to use some custom way of handling that until the issue is closed.

The easiest solution would be replacing the load balancer with another one like nginx, here's a nifty guide for swarm Where in the nginx configuration file you just need to keep the original request headers to keep tabs on them, you can see how to that here but the gist is to add an nginx directive with the X-Forwarded-For variable to it for when you proxy the request to one of your load balanced instances

Depending on how many instances you've got using docker-compose maybe easier than hassling with swarm which is a bit less bare bone

Related