0

I have been struggling with the above question for countless hours and haven't been able to find an explanation for the behavior either on this site or any other site for that matter. Might be me using the wrong queries though. This is my first question on stack overflow, so please be gentle ;)

The setup I'm using:

I have a server behind my router (which has internal IP 192.168.2.254) and use port forwarding to forward public ports 80 and 443 to my (ubuntu) server. I can access that server either by typing in it's public IP (say 80.81.82.83) or by going to a domain (say example.org) which A records contain the same public IP or by typing in it's internal IP (say 192.168.2.1) when on the same network. I use NGINX on that server as a reverse proxy to delegate the request to the appropriate (web) applications on the same server. The router is the standard router I got from my internet provider.

I have two clients connecting to that server, client A is on the same network as the server (say 192.168.2.2), while client B is not on the same network, but anywhere else in the world (say 90.91.92.93).

When I connect with client B (i.e. not on the same network) to my server (either using the public IP or the domain name) and I check the NGINX access logs for the client IP (i.e. $remote_addr) the correct/expected IP address is shown: 90.91.92.93.

Now the part I don't understand:

When I connect with client A (same network as server) to the server using the internal IP of the server (192.168.2.1) the access logs show the correct/expect IP address from the client: 192.168.2.2. But when I connect from the same client to the server either using the public IP address or the domain name, the NGINX access logs shows the IP address from the router: 192.168.2.254.

Why does this happen? This way I cannot log (and act on) which internal clients connect to the server.

4
  • 2
    The problem is hairpin routing and NAT translation that happens with that. You should use split DNS so that the local DNS gives you the local server address. That way, the traffic stays on the LAN, never passing through the router. Hairpin routing wastes router resources and bandwidth on the router connection to and from the LAN. – Ron Maupin May 3 at 21:32
  • How can one use split DNS? i.e. is it client-side or done on the router? – Maanloper May 3 at 21:40
  • If you have only two clients, much simpler than setting up split DNS will be to use hosts file on these clients, and just put your internal IP for your domain name in this file. – raj May 3 at 21:43
  • It is done on your local DNS server. Alternatively, you could change the hosts file on your workstation. – Ron Maupin May 3 at 21:43
2

But when I connect from the same client to the server either using the public IP address or the domain name, the NGINX access logs shows the IP address from the router: 192.168.2.254.

Why does this happen? This way I cannot log (and act on) which internal clients connect to the server.

This happens because when you connect to the public IP address (or public domain name which uses the public IP address), the connection goes from your client (192.168.2.2), to the router (192.168.2.254), then the router NATs the source address of the connection to it's own interface, i.e. to the IP address of interface closest to destination.

1
  • To extend this answer, the connection must go that way, because the public IP address is outside of your local network, so it must be handled by the router. It is exactly as if you were connecting to a server somewhere outside in the Internet; the server will see only your public IP address and not your client's internal IP address. – raj May 3 at 21:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.