0

Here is my understanding of the user's IP:

User's IP is REMOTE_ADDR. But if the user is using a proxy (like HotSpotSheild (HSS)) or a chain of proxies, then REMOTE_ADDR is the address of the proxy (not user's IP), and the user's IP might be in the other headers like these:

  • HTTP_CLIENT_IP
  • HTTP_X_FORWARDED_FOR
  • HTTP_X_FORWARDED
  • HTTP_X_CLUSTER_CLIENT_IP
  • HTTP_FORWARDED_FOR
  • HTTP_FORWARDED
  • Or maybe none of them.

So when an user uses the proxy, then he is undetectable.

Question1: Always one of those headers (above) is full? And are the rest empty?

Question2: Is that a good idea that I store both REMOTE_ADDR and one of those header (which isn't empty) in different fields in the database? (I mean having two separated columns for the IP, not just one column)


Here is my understanding of a load balancer:

It is a reverse proxy server that you use when you're running a cluster of servers. Clients connect to the load balancer, and it forwards the connection to one of the actual servers.


Theory:

If you use a load balancer, use HTTP_X_FORWARDED_FOR as user's IP.

Question3 Why should I store bHTTP_X_FORWARDED_FOR as the user's IP when there is a load balancer? I mean what's bHTTP_X_FORWARDED_FOR to do with load balancer?

Martin AJ
  • 6,261
  • 8
  • 53
  • 111
  • 1
    What headers your PHP app is receiving, completely depends on which headers your server is feeding the app, and which ones he's filtering out. If you want to log the IP-address of a visitor, just log the `REMOTE_ADDR`, *or* whatever header your load balancer/reverse proxy stores the address in. Have a look at nginx config files for instance. – 1sloc Jul 09 '16 at 00:44
  • @JethroVanThuyne What do you mean *" which headers your server is feeding the app"* ? – Martin AJ Jul 09 '16 at 00:52
  • Your PHP application does not interact directly with a browser. It gets it's data from the web server (nginx, apache2, ...). This means that this web server can add, remove or rename headers before they reach your app. If you are coding for a load balanced environment, you might want to talk to your sys admin about which header will contain the IP address. I've seen "X-Forwarded-For" as well as "X-Real-IP". – 1sloc Jul 09 '16 at 01:03
  • @JethroVanThuyne I see, thx – Martin AJ Jul 09 '16 at 01:06
  • @JethroVanThuyne Just one thing. may you please tell me, always **only one** of those headers is full? *(and others are empty)* ? – Martin AJ Jul 09 '16 at 01:15
  • Not necessarily. Theoretically speaking, it's all very arbitrary. However, there is a very high chance that in a standard nginx or apache setup, you'll get your IP address from `REMOTE_ADDR`. Just check with your sys admin if it doesn't look correct (e.g. if every IP you log is in the 127.0.x.x range). – 1sloc Jul 09 '16 at 01:18
  • Didn't I explain much of this in http://stackoverflow.com/questions/38276036/how-can-i-track-ips-to-block-malicious-users – Barmar Jul 09 '16 at 13:37
  • @Barmar You did .. but still I cannot make a decision. `:-(` .. btw I've asked [this](http://stackoverflow.com/questions/38282302/why-should-i-store-both-remote-and-forwarded-as-users-ip) recently. I think the answer of that question is just one word: "first approach", "second approach". – Martin AJ Jul 09 '16 at 13:39
  • You seem to have about 5 questions all dancing around different parts of this issue. – Barmar Jul 09 '16 at 13:45
  • Perhaps what you need to do is some real research to learn how all these devices work and fit together. – Barmar Jul 09 '16 at 13:45
  • @Barmar Actually I'm a little bit obsession and cannot make a decision quickly. Also I don't know why nobody doesn't give me a clear answer. Here is what I want to do: having two separated columns in the database: col1: `REMOTE_ADD` and, col2 `HTTP_...` *(one of those HTTP headers which isn't empty)*. What I want to do is ok? – Martin AJ Jul 09 '16 at 13:49
  • I don't understand why you want to do that. What's the point of saving both addresses in the database? Figure out the real IP of the user, or the best approximation you can determine, and just save that. – Barmar Jul 09 '16 at 14:01
  • @Barmar Agreed, but [this answer](http://stackoverflow.com/questions/3003145/how-to-get-the-client-ip-address-in-php#3003233) has 800 upvotes and clearly says you have to store them into two different rows .. that's exactly why I cannot make a decision. – Martin AJ Jul 09 '16 at 14:11
  • It says **if** you're going to save the forwarded address, you should also save the real address. But there's no reason to save the forwarded address, because you can't trust it. – Barmar Jul 09 '16 at 14:15
  • @Barmar You are right. And I'll follow your idea: *"the best approximation you I can determine as user's IP"*. So I think I will use something like [this](http://stackoverflow.com/questions/15699101/get-the-client-ip-address-using-php#15699240), As you said, we cannot trust `HTTP_...` headers, so should I change the order of those conditions? – Martin AJ Jul 09 '16 at 16:37

1 Answers1

2

This is all about the notion of trust and specific implementation details.

If your system trusts the proxy server (e.g. in a reverse-proxy situation), then you can trust the IP it passes onto you in one of those HTTP headers.

If there is no reasons to trust the proxy server (e.g. a random internet proxy such as Hotspot Shield), then your system has no idea whether the IP passed to you is simply made up or not.

You could have a whitelist of servers you trust based on REMOTE_ADDR, and if you get a connection from one of those then you use the IP in the HTTP header instead (although probably best to log both for completeness). You may also wish to expand this so certain headers are trusted to be supplied by certain remote proxies, otherwise there may be a security flaw where a user supplies their own header as well that manages to pass through the proxy unscathed.

Always one of those headers (above) is full? And are the rest empty?

Depends on the proxy and its software implementation.

Is that a good idea that I store both REMOTE_ADDR and one of those header (which isn't empty) in different fields in the database? (I mean having two separated columns for the IP, not just one column)

Yes, there is no harm in storing both - they may be useful for any audit trails.

Why should I store bHTTP_X_FORWARDED_FOR as the user's IP when there is a load balancer? I mean what's bHTTP_X_FORWARDED_FOR to do with load balancer?

Because your load balancer should be a trusted proxy, therefore you should be able to trust the IP it provides to you.

SilverlightFox
  • 32,436
  • 11
  • 76
  • 145
  • I see. thank you .. upvote. Just look, I bought a VPS and I configured it and now I'm using it. There isn't any load balancer, or proxy server. So how can I get user's IP? `REMOTE_ADDR` or a `HTTP_...` header? Or both? Or I must install a load balancer? *(however I don't know even what's it)* – Martin AJ Jul 11 '16 at 14:28
  • In a nutshell `REMOTE_ADDR` unless this happens to resolve to an IP of a public proxy server you explicitly trust. – SilverlightFox Jul 11 '16 at 14:42