All Products
Search
Document Center

Edge Security Acceleration:Preserve client IP addresses with NGINX

Last Updated:Mar 31, 2026

When you use ESA TCP/UDP proxy, client IP addresses are not transported by default. Configure NGINX with PROXY protocol v1 or v2 to pass real client IPs to your backend for accurate logging, access control, and geolocation.

Scenario

Your website uses TCP-based backend services with ESA. To enable access control, accurate logging, and visitor geolocation, you need the real client IP on your origin server. NGINX supports the PROXY protocol, which passes client IPs through the proxy chain.

Configure NGINX to accept the PROXY protocol and your application to read the client IP from the protocol header.

Before you begin

  • NGINX Plus R3 and later or NGINX Open Source 1.5.12 and later support PROXY protocol v1.

  • NGINX Plus R16 and later or NGINX Open Source 1.13.11 and later support PROXY protocol v2.

Install NGINX

# Install dependencies for compiling NGINX.
yum -y install gcc gcc-c++ autoconf automake
yum -y install zlib zlib-devel openssl openssl-devel pcre-devel
# Download the installation package.
wget http://nginx.org/download/nginx-1.20.0.tar.gz
# Decompress the source package.
tar -zxvf nginx-1.20.0.tar.gz
# Go to the NGINX directory.
cd nginx-1.20.0
# Configure NGINX build settings, including the --with-stream module.
./configure --prefix=/usr/local/nginx --sbin-path=/usr/local/nginx/sbin/nginx --conf-path=/usr/local/nginx/conf/nginx.conf --with-http_stub_status_module --with-http_gzip_static_module --with-stream
# Compile NGINX.
make
# Install NGINX.
make install

Configure NGINX to support PROXY protocol v1/v2

Step 1: Update the NGINX configuration

Add the proxy_protocol parameter to the listen directive in the server block. For details, see Accepting the PROXY Protocol. Example:

http {
    log_format combined '$proxy_protocol_addr - $remote_user [$time_local] '
                        '"$request" $status $body_bytes_sent '
                        '"$http_referer" "$http_user_agent"';
    #...

    server {
        server_name localhost;

        listen 80   proxy_protocol;
        listen 443  ssl proxy_protocol;

        ssl_certificate      /etc/nginx/ssl/public.example.com.pem;
        ssl_certificate_key  /etc/nginx/ssl/public.example.com.key;

        location /app/ {
            proxy_pass       http://backend1;
            proxy_set_header Host            $host;
            proxy_set_header X-Real-IP       $proxy_protocol_addr;
            proxy_set_header X-Forwarded-For $proxy_protocol_addr;
        }
    }
}

stream {
    log_format basic '$proxy_protocol_addr - $remote_user [$time_local] '
                     '$protocol $status $bytes_sent $bytes_received '
                     '$session_time';
    #...
    server {
        listen              8080 ssl proxy_protocol;

        ssl_certificate     /etc/nginx/ssl/cert.pem;
        ssl_certificate_key /etc/nginx/ssl/cert.key;

        proxy_pass          esa.example.com:8080;
        proxy_protocol      on;
    }
}

Step 2: Create a Layer 4 proxy

In the ESA console, go to your website details page. In the left navigation pane, choose TCP/UDP Proxy > Settings, and then click Create Application. Set Protocol to TCP and Pass Client IP to PROXY Protocol v1 or PROXY Protocol v2. Configure other parameters as needed.

image

Verify the configuration

  1. Start a simple HTTP server.

    python -m SimpleHTTPServer 8080
  2. Use curl to send a test request to the HTTP server.

    curl -i "https://esa.example.com:8080"
  3. Check the NGINX logs. The real client IP address appears in the log entries.

    image

Note

For information about the support of HAProxy for the PROXY protocol, see Use the Proxy Protocol to Preserve a Client’s IP Address.