Introduction

We have introduced the proxy protocol proposed by haproxy. Through the proxy protocol, the server can obtain the real IP address and port of the client, so that some very meaningful operations can be performed.

Why would it make a lot of sense to get the real IP address of the client?

Consider a database hidden behind a proxy. If there are multiple clients connecting to the database through the proxy, in fact, because they are all connected through the proxy, all operations in the database are the IP address of the proxy server. The performance monitoring and optimization of the database is disadvantageous because we do not know the real abnormal server IP address.

In this case, the proxy protocol needs to be used, so that the database can reflect the IP address of the real client, so as to facilitate the monitoring of the database and the problem location.

In fact, the database is only a specific example, we may also need to know the real IP of the client in many other situations.

Taking the most popular http server and proxy server nginx as an example, let's take a look at how to configure proxy protocol in nginx.

Application of proxy protocol in nginx

We know that nginx is a web server and proxy server, which generally works behind a proxy server or load balancing software (Haproxy, Amazon Elastic Load Balancer (ELB).

The client first requests the proxy server or LSB load balancing software, and then goes to nginx for real web access.

Because of the multi-layer software, some information of the client such as ip address, port number, etc. may be hidden, which is unfavorable for our problem analysis and data statistics. Because for nginx, we want to be able to get the real client IP address so that we can get the real request environment.

In this case, the PROXY protocol is required.

If the proxy or LSB mentioned above implements the PROXY protocol, no matter whether it is HTTP, SSL, HTTP/2, SPDY, WebSocket or TCP protocol, nginx can get the original IP address of the client, so as to perform processing according to the original IP address. Some special operations, such as blocking access to malicious IPs, displaying different languages or pages according to different IPs, or simpler logging and statistics, are very effective.

Of course, if you want to support the PROXY protocol, there are also requirements for the version of nginx. The specific version requirements are as follows:

  • To support PROXY protocol v2, NGINX Plus R16 or NGINX Open Source 1.13.11 is required.
  • To support ROXY protocol for HTTP, NGINX Plus R3 or NGINX Open Source 1.5.12 is required.
  • To support the TCP client‑side PROXY protocol, NGINX Plus R7 or NGINX Open Source 1.9.3 is required.
  • To support PROXY protocol for TCP, NGINX Plus R11 or NGINX Open Source 1.11.4 is required.

In nginx, the corresponding client information can be obtained through the following variables, specifically as follows:

$proxy_protocol_addr and $proxy_protocol_port represent the original client's IP address and port number, respectively.

$remote_addr and $remote_port represent the IP address and port of the load balancer.

If you use the RealIP extension module, then this module will rewrite the $remote_addr and $remote_port these two values, replacing them with the original client's IP address and port number.

Then use $realip_remote_addr and $realip_remote_port to indicate the IP address and port of the load balancer.

In the RealIP extension module, the meanings of $proxy_protocol_addr and $proxy_protocol_port remain unchanged, and are still the IP address and port number of the original client.

Configure and use proxy protocol in nginx

Above we mentioned the basic application of proxy protocol in nginx. Let's talk about how to configure it in nginx.

Enable proxy protocol in nginx

If your nginx is already a version that supports the proxy protocol, enabling the proxy protocol is very simple, just add proxy_protocol to the listen in the server, as shown below:

 http {
    #...
    server {
        listen 80   proxy_protocol;
        listen 443  ssl proxy_protocol;
        #...
    }
}
   
stream {
    #...
    server {
        listen 112233 proxy_protocol;
        #...
    }
}

You may be familiar with the http block, which means that nginx supports http/https. The stream module may be unfamiliar to everyone. This is the support for the tcp/udp protocol provided by nginx.

Through the above configuration, nginx can support proxy protocol in both tcp/udp protocol and http/https protocol.

Using Real‑IP modules

Real-IP modules is a module that comes with nginx. You can run the following command to check whether nginx has installed the real-ip module:

 nginx -V 2>&1 | grep -- 'http_realip_module'
nginx -V 2>&1 | grep -- 'stream_realip_module'

If the version you are currently using does not have a real ip, don't worry, you may need to compile from source at this time.

During the compilation process, we need to execute a configure command, in which we can specify the functions to be enabled, such as stream or http_ssl_module:

 $ ./configure
--sbin-path=/usr/local/nginx/nginx
--conf-path=/usr/local/nginx/nginx.conf
--pid-path=/usr/local/nginx/nginx.pid
--with-pcre=../pcre-8.44
--with-zlib=../zlib-1.2.11
--with-http_ssl_module
--with-stream
--with-mail

If you want to enable the real-ip function, you can add:

 --with-http_realip_module

If nginx is running behind SLB or proxy, you can use the set_real_ip_from command to specify the IP range of the proxy or load balancing server, as follows:

 server {
    #...
    set_real_ip_from 192.168.1.0/24;
   #...
}

Then we need to replace the IP address of the proxy or SLB with the address of the real client, then we can use it like this:

 http {
    server {
        #...
        real_ip_header proxy_protocol;
      }
}

request forwarding

Whether it is http or stream block, they may encounter the situation that the request is forwarded to the subsequent upstream. For upstream, they want to receive the real client IP address instead of the proxy or slb address, then they can pass the following The settings to solve:

 http {
    proxy_set_header X-Real-IP       $proxy_protocol_addr;
    proxy_set_header X-Forwarded-For $proxy_protocol_addr;
}
 stream {
    server {
        listen 12345;
        proxy_pass example.com:12345;
        proxy_protocol on;
    }
}

The way http and stream are set up is different.

logging

The log is a very important function, which is very useful for locating problems and performing statistical analysis of data. Of course, what we need is the real client IP address.

We can log the corresponding logs in the http and stream blocks by using the variable $proxy_protocol_addr as follows:

 http {
    #...
    log_format combined '$proxy_protocol_addr - $remote_user [$time_local] '
                        '"$request" $status $body_bytes_sent '
                        '"$http_referer" "$http_user_agent"';
}
 stream {
    #...
    log_format basic '$proxy_protocol_addr - $remote_user [$time_local] '
                      '$protocol $status $bytes_sent $bytes_received '
                      '$session_time';
}

Summarize

With the above settings, nginx can already use the proxy protocol, which will make our subsequent analysis easier.

For more information, please refer to http://www.flydean.com/02-nginx-proxy-protocol/

The most popular interpretation, the most profound dry goods, the most concise tutorial, many you do not know

Welcome to pay attention to my official account: "Program those things", understand technology, understand you better!


flydean
890 声望437 粉丝

欢迎访问我的个人网站:www.flydean.com