Java Interview-How to get the client's real IP

Java Interview-How to get the client's real IP

When developing some small games, one of the functions we often pay attention to is sharing. For sharing, we hope to have different sharing texts according to different cities or regions. If the function of identifying regions is completed by the server, we need to know the real IP of the client. Today we will see how the server obtains the real IP of the client.

[[280536]]

nginx configuration

First of all, a request can be divided into a request header and a request body, and the IP address information of our client is generally stored in the request header. If your server uses Nginx for load balancing, you need to configure the X-Real-IP and X-Forwarded-For request headers in your location:

  1. location ^~ /your-service/ {
  2. proxy_set_header X-Real-IP $remote_addr;
  3. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  4. proxy_pass http://localhost:60000/your-service/;
  5. }

1. X-Real-IP

In "Practical nginx", there is such a sentence:

After the reverse proxy, since an intermediate layer is added between the client and the web server, the web server cannot directly obtain the client's IP address. What is obtained through the $remote_addr variable will be the IP address of the reverse proxy server.

This means that when you use nginx reverse server, you use request.getRemoteAddr() (essentially to get $remote_addr) on the web side, and you get the address of nginx, that is, the $remote_addr variable encapsulates the address of nginx, and of course you can't get the real IP of the user. However, nginx can get the real IP of the user, that is, when nginx uses the $remote_addr variable, it gets the real IP of the user. If we want to get the real IP of the user on the web side, we must make an assignment operation in nginx, that is, my configuration above:

  1. proxy_set_header X-Real-IP $remote_addr;

2. X-Forwarded-For

X-Forwarded-For variable, this is a non-RFC standard developed by squid to identify the client address connected to the web server through the original IP of HTTP proxy or load balancer. If X-Forwarded-For is set, there will be a record every time it is forwarded by proxy. The format is client1, proxy1, proxy2, separated by commas. Since it is a non-RFC standard, it is not available by default and needs to be added by force. By default, for requests forwarded by proxy, the remote address is the ip of the proxy end in the backend. That is to say, by default, we cannot get the user's ip using request.getAttribute("X-Forwarded-For"), if we want to get the user's ip through this variable, we need to add the configuration in nginx ourselves:

  1. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

It means adding a $proxy_add_x_forwarded_for to X-Forwarded-For. Note that it is adding, not overwriting. Of course, since the default X-Forwarded-For value is empty, we always feel that the value of X-Forwarded-For is equal to the value of $proxy_add_x_forwarded_for. In fact, when you build two nginx on different IPs and use this configuration, you will find that the client IP and the first nginx IP will be obtained through request.getAttribute("X-Forwarded-For") on the web server side.

3. So what is $proxy_add_x_forwarded_for?

The $proxy_add_x_forwarded_for variable contains the X-Forwarded-For and $remote_addr parts of the client request header, separated by commas.

For example, there is a web application that is forwarded by two nginx servers before it, that is, users access the web through two nginx servers.

In the first nginx, use:

  1. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

Now the X-Forwarded-For part of the $proxy_add_x_forwarded_for variable is empty, so there is only $remote_addr, and the value of $remote_addr is the user's IP address. Therefore, after the assignment, the value of the X-Forwarded-For variable is the user's real IP address.

On the second nginx, use:

  1. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

Now the $proxy_add_x_forwarded_for variable, the X-Forwarded-For part contains the user's real IP, and the value of the $remote_addr part is the IP address of the previous nginx. Therefore, after this assignment, the current value of X-Forwarded-For becomes "the user's real IP, the IP of the first nginx", which is clear now.

Get the real IP address of the server

The code is:

  1. public static String getIpAddress(HttpServletRequest request) {
  2. String Xip = request .getHeader("X-Real-IP");
  3. String XFor = request .getHeader("X-Forwarded-For");
  4. if (!Strings.isNullOrEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)) {
  5. //After multiple reverse proxies, there will be multiple IP values, the first IP is the real IP
  6. int index = XFor .indexOf(",");
  7. if (index != -1) {
  8. return XFor.substring(0, index);
  9. } else {
  10. return XFor;
  11. }
  12. }
  13. XFor = Xip ;
  14. if (!Strings.isNullOrEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)) {
  15. return XFor;
  16. }
  17. if (Strings.nullToEmpty(XFor).trim().isEmpty() || "unknown".equalsIgnoreCase(XFor)) {
  18. XFor = request .getHeader("Proxy-Client-IP");
  19. }
  20. if (Strings.nullToEmpty(XFor).trim().isEmpty() || "unknown".equalsIgnoreCase(XFor)) {
  21. XFor = request .getHeader("WL-Proxy-Client-IP");
  22. }
  23. if (Strings.nullToEmpty(XFor).trim().isEmpty() || "unknown".equalsIgnoreCase(XFor)) {
  24. XFor = request .getHeader("HTTP_CLIENT_IP");
  25. }
  26. if (Strings.nullToEmpty(XFor).trim().isEmpty() || "unknown".equalsIgnoreCase(XFor)) {
  27. XFor = request .getHeader("HTTP_X_FORWARDED_FOR");
  28. }
  29. if (Strings.nullToEmpty(XFor).trim().isEmpty() || "unknown".equalsIgnoreCase(XFor)) {
  30. XFor = request .getRemoteAddr();
  31. }
  32. return XFor;
  33. }

Let's take a look at the meaning of each request header:

  • X-Real-IP: The nginx proxy usually adds this request header.
  • X-FORWARDED-FOR: This is a field developed by Squid. It is added only when passing through an HTTP proxy or load balancing server.
  • Proxy-Client-IP and WL-Proxy-Client-IP: This is usually only available for requests through the Apache http server. When using Apache http as a proxy, a Proxy-Client-IP request header is usually added, and WL-Proxy-Client-IP is a header added by its WebLogic plug-in.

HTTPCLIENTIP

Some proxy servers will add this request header. I searched online and found a saying:

This is a common http header, which is easy to forge. Don't trust user input easily. curl -H 'client-ip: 8.8.8.8' lidian.club/phpinfo.php | grep _SERVER You can see _SERVER["HTTP_CLIENT_IP"]. client-ip and client-host are headers sent to the server by the http transparent proxy assumed in the enterprise intranet in the era when NAPT was not popular. Only a very few manufacturers have used them. They have never been a standard and have never become a de facto standard. (The most familiar de facto standard is x-forwarded-for) The web proxy that appeared later has never used this header. TCP/IP Illustrated Vol 3 did not mention this header, and the rumors on the Internet are not credible. The earliest trace that can be verified appeared in 2005. A Japanese Perl/CGI secret book (9784798010779, 270 pages) blocked proxy user access through the two headers of client-ip and via.

Abbreviated as XFF header, it represents the client, that is, the real IP of the HTTP request end. This item is added only when passing through an HTTP proxy (such as APACHE proxy) or a load balancing server. It is not a standard request header information defined in the RFC. A detailed introduction to this item can be found in the squid cache proxy server development documentation. If there is this information, it means that you are using a proxy server, and the address is the value behind it. It can be forged. The standard format is as follows: X-Forwarded-For: client1, proxy1, proxy2

<<:  In the win-win multi-cloud era, Juniper Networks helps enterprises achieve digital transformation

>>:  From 76 million 5G connections, we found the 7 most promising 5G IoT applications

Recommend

Seize the opportunity of enterprise applications with network slicing

5G is on the rise for a reason. In addition to fa...

Can the heavy fine on Alibaba serve as a wake-up call for the Internet giant?

The State Administration for Market Regulation ha...

A review of SDWAN's martial arts schools in 2018

There is no shortage of newcomers in the network ...

Europe focuses on 6GHz rules, Wi-Fi -7 is still a long way off

European regulators have been facing increasing p...

The 2018 Secada Excellent Product Award selection is about to start

In order to support technological innovation, hel...

The 10 coolest web startups of 2020

Changing the rules of the online market It’s safe...

Let’s talk about how 5G applications can empower thousands of industries

​Based on the transmission characteristics of lar...

Nexril: $9/quarter KVM-1GB/15G SSD/1TB/Dallas data center

Nexril is a site under Corex Solutions, LLC. It w...

Net loss of fixed-line broadband users: China Unicom sounds red alert

December 22 news (Yue Ming) Recently, the three m...