I’m using Traefik 2.10 via rootless Docker, which acts as a reverse proxy for Apache. The hosting works but I can’t get it to give me the real IP address of clients.
Apache is set up properly to trust the local Docker address range and accept X-Forwarded-For.
Some posts say that you need to use “host” mode networking but that doesn’t work here.
For anyone else that runs into this problem, here is what I was able to figure out:
Host mode networking is severely limited in rootless Docker. This mode is only good if an application needs to “see” the host network interfaces. You’re still trapped in a user namespace and you don’t get the performance gain.
Docker’s port manager (using SNAT) is never going to give you the real IP address.
A proxy in rootless Docker can’t forward in “host” mode because everything is blocked by security.
So, slirp4netns (the network manager) is never going to see anything except the SNAT address that the Docker port driver gives it.
Solution:
Make slirp4netns the port driver. That way, slirp4netns sees the real IP address and can make that available to a proxy.
The default network driver is usually slirp4netns but it’s good practice to set it here.
After you create the file, restart docker.
Note that you will need to allow user access to lower port ranges. CAP_NET_BIND_SERVICE will not work. I believe this is because rootlesskit must still create a namespace and that is locked down by the kernel, regardless of the permission given to rootlesskit.
You can use sudo sysctl net.ipv4.ip_unprivileged_port_start=80, for a web server.
(Save that to /etc/sysctl.d/99-rootless-ports.conf to make it permanent).
This method allows you to use standard discovery in Traefik with rootless Docker and still get the client IP address.