jlesage / docker-nginx-proxy-manager

Docker container for Nginx Proxy Manager
MIT License
784 stars 177 forks source link

[Feature request] Real client IP to final host #309

Closed xeviff closed 11 months ago

xeviff commented 1 year ago

Idea

Hello. I have a serious issue: All external traffic (hackers included) is represented as coming from the same IP and as a local one! (the NPM docker one), like 192.168.80.2 and then, when I receive a brute force attack, my NAS blocks the IP, leaving myself and all my users unable to access anymore to any of my services (all DNS requests are blocked) until I unblock it manually, opening the door again to the next hacker try. I was thinking about solving this issue making the network_mode="host", and probably the NAS will have the real visibility to the external IPs (not sure, though), but it's not feasible anyways because the ports would need to be 443 and 80, instead of different ones.

jlesage commented 11 months ago

How the NAS blocks the IP ? I assume it's based on the content of a log file ?

but it's not feasible anyways because the ports would need to be 443 and 80, instead of different ones.

Why not feasible ? You still need to do port forwarding on your router.

xeviff commented 11 months ago

Hello. I define a security rule on the NAS based on number attempts per time. For example in my case I set it to block an IP where tries more than two wrong logins in the course of 1 hour.

image

That's why identifing the real IP on the NAS point of view is critic. In my case all attacks pointing to my IP, the real source IP is identified, but all pointing to my domain are identified as 192.168.80.2 as you can see on the image:

image

On the other hand, it's true that if I configure the router to port forwarding 4443->443 I could try the network_mode="host" trick, but in my case I want to reach my services in the same way either if I'm at home or outside, for example I want to point to myservice.mydomain.com always (port 443) rather to remember changing the port when I'm at home (using LAN), like myservice.mydomain.com:4443 (I use a local DNS server to reach the LAN IP when I point to my domain). Thanks for yout attention!

jlesage commented 11 months ago

but in my case I want to reach my services in the same way either if I'm at home or outside

This can be done with a router feature called NAT loopback/reflection/hairpin.

xeviff commented 11 months ago

Muy current router does not have that feature. Anyways I want to keep my configurations into configuration files (f.i. docker-compose.yml) not in devices such a router that I probably change it often (every time I hire a different IPS, for sure). Just for curiosity, why you decided to choose 4443/8000 as internal docker ports rather than 80/443?

jlesage commented 11 months ago

The reason was to run Nginx as non-root by using unprivileged ports.

xeviff commented 11 months ago

Ok. Finally I run it as network=host and did the test. Here's the result when I fail some login from my phone connected by satelite (outsite LAN): image

The expected was to see some random IP of the phone company, but it's even worse than I though because the identified IP is 192.168.1.22, the NAS IP (!!!), I don't want to imagine what would happen if the NAS blocks itself :-)

Then, the issue is maybe more complex to fix than it seems. Right now I don't have any idea on how to solve it. I guess it's a common issue to all people using NPM on a NAS applying some security rule as IP blocking.

jeremysherriff commented 11 months ago

@xeviff you need to tell the NAS that the connection is from a proxy: image

Put something like this, the IP should be your NPM proxy internal IP address: image

xeviff commented 11 months ago

Thanks for the comment @jeremysherriff ! I guess this avoid blocking the IP but also opens the door to infinite login attempts from hackers, right?

jeremysherriff commented 11 months ago

I guess this avoid blocking the IP but also opens the door to infinite login attempts from hackers, right?

It shouldn't, no. It's not saying "always allow this proxy to be used, at all times, for any purpose", its saying "look for the extra info in the header to apply appropriate security rules". So the X-FORWARDED-FOR header is very important.

xeviff commented 11 months ago

ok, finally solved. Here the concrete details. As this is a already existing feature, I close the issue. Thanks agani for your time!!

xeviff commented 11 months ago

A final note. I enabled NAT loopback in my router (didn't know it had the feature, I'm sourprised honestly). It works but now if I fail logins from LAN, the IP identified is my public IP: User [admin] from [83.xx.xx.228] failed to sign in to [DSM] via [password] due to authorization failure. I guess at the end of the day, this may have negative impact to the users, and I'm not sure what benefits brings the fact of runnning Nginx as non-root by using unprivileged ports. I guess is not mandatory, as the official image works with 80:80 and 443:443 (I must say though, I always liked more this one because of the no need of having a separated DB docker)