All Products
Search
Document Center

Server Load Balancer:Enable ALB to preserve client IP addresses

Last Updated:Jan 16, 2024

If you use an Application Load Balancer (ALB) to forward network traffic, you can use the X-Forwarded-For header to preserve client IP addresses.

How X-Forwarded-For works

HTTP and HTTPS listeners support the X-Forwarded-For header. You can configure backend servers to retrieve client IP addresses from the X-Forwarded-For header.

Format of X-Forwarded-For:

X-Forwarded-For: <Client IP address, IP address of Proxy Server 1, IP address of Proxy Server 2, ...>

Therefore, the leftmost IP address carried in the X-Forwarded-For header is the client IP address.

Procedure

Step 1: Check whether the listener uses the X-Forwarded-For header to preserve client IP addresses

  1. Log on to the ALB console.

  2. In the top navigation bar, select the region in which the ALB instance is deployed.

  3. On the Instances page, click the ID of the instance that you want to manage.

  4. On the instance details page, click the Listener tab and click the ID of the listener that you want to manage.

  5. On the listener details page, check whether Add HTTP Header includes the option Add X-Forwarded-For to Retrieve Client IP.

    Note

    By default, ALB uses the X-Forwarded-For header to preserve client IP addresses. This feature cannot be disabled.

Step 2: Configure backend servers

The following procedures show how to configure backend servers. Choose a procedure based on the type of backend server that you use.

Configure an NGINX server

In this example, the CentOS 7.9 operating system and NGINX 1.20.1 are used. Adjust the configurations based on the environment that you use.

  1. Run the command nginx -V | grep http_realip_module on the NGINX server to check whether the http_realip_module module is installed on the NGINX server. NGINX servers use the http_realip_module module to parse the value of X-Forwarded-For.

    If --with-http_realip_module is included in the output, it indicates that http_realip_module is installed on the NGINX server and you can proceed to the next step.

    Sample output which shows that http_realip_module is installed

    nginx version: nginx/1.20.1
    built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) 
    built with OpenSSL 1.1.1k  FIPS 25 Mar 2021
    TLS SNI support enabled
    configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-compat --with-debug --with-file-aio --with-google_perftools_module --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_degradation_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_mp4_module --with-http_perl_module=dynamic --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-http_xslt_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-stream_ssl_preread_module --with-threads --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mtune=generic' --with-ld-opt='-Wl,-z,relro -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-E'
    
    Note
    • NGINX 1.0.4, which was released in 2011, and later support the http_realip_module module. If your NGINX version is earlier than 1.0.4, we recommend that you back up data and upgrade to a later version.

    • If the http_realip_module module is not installed on the NGINX server, compile and install NGINX again, and then install http_realip_module. We recommend that you use package managers such as YUM to install and manage NGINX. Packet managers simplify the process.

  2. Modify and save the NGINX configuration file. The following code block shows an example. Run the nginx -t command to query the path of the configuration file, which is /etc/nginx/nginx.conf by default. The path may vary based on the environment that you use.

    http {
      # Set the variable $http_x_forwarded_for, which is used to record the value of X-Forwarded-For.
      log_format  main  '$remote_addr- $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
      
      # ...
    }
    

  3. Run the sudo nginx -s reload command to reload the NGINX configuration file.

Configure an Apache server

In this example, the CentOS 7.9 operating system and Apache 2.4.6 are used. Adjust the configurations based on the environment that you use.

  1. Run the command httpd -M | grep remoteip_module on the Apache server to check whether the remoteip_module module is installed on the Apache server. Apache uses remoteip_module to parse the value of X-Forwarded-For.

    If remoteip_module (shared) is included in the output, it indicates that the module is installed on the Apache server and you can proceed to the next step.

    Note
    • Apache 2.4.0, which was released in 2012, and later support the remoteip_module module. If your Apache version is earlier than 2.4.0, we recommend that you back up data and upgrade to a later version.

    • If the remoteip_module module is not installed on the Apache server, compile and install Apache again, and then install remoteip_module. We recommend that you use package managers such as YUM to install and manage Apache. Packet managers simplify the process.

  2. Modify and save the Apache configuration file. The following code block shows an example. The default path of the configuration file is /etc/httpd/conf/httpd.conf. The path may vary based on the environment that you use.

    # ...
    <IfModule log_config_module>
    	# Add the LogFormat directive %{X-Forwarded-For}i, which is used to record the information about X-Forwarded-For.
      LogFormat "%{X-Forwarded-For}i %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
      LogFormat "%{X-Forwarded-For}i %h %l %u %t \"%r\" %>s %b" common
    	#...
    </IfModule>
    # ...

  3. Run the command sudo systemctl restart httpd to restart Apache.

Configure an IIS server

In this example, the Windows Server 2016 operating system is used. Adjust the configurations based on the environment that you use.

  1. Download and decompress the F5XForwardedFor file.

  2. Copy the F5XFFHttpModule.dll and F5XFFHttpModule.ini files from the x86\ or x64 directory to a directory on the IIS server. Make sure that the IIS process has read and write permissions on the directory.

  3. Open IIS Manager in Server Manager.

  4. Select the IIS server and double-click Modules.

  5. Click Configure Native Modules, and then click Register in the dialog box that appears.

  6. Add the downloaded .dll file.

    1. Enter a file name, select a path, and then click OK.

    2. The module to be registered is automatically selected. Click OK.

  7. Return to the homepage of IIS Manager and double-click Logging. Configure a log format to record the information about X-Forwarded-For.

    1. Click Select Fields.

      image.png

    2. Click Add Field in the lower-left corner, add the following field, and then click OK.

      image.png

    3. Click Apply in the right-side Actions pane.

  8. Restart the IIS server and wait until the configurations take effect.

Step 3: Test whether the backend server can retrieve client IP addresses

The following procedures show how to run tests. Choose a procedure based on the type of backend server that you use.

NGINX server

If you use an NGINX server, you can check the NGINX log to determine whether the backend server can retrieve client IP addresses.

The default path of the NGINX log is /var/log/nginx/access.log.

In each log entry, the leftmost IP address in the $http_x_forwarded_for variable is the client IP address.

image.png

Apache server

If you use an Apache server, you can check the Apache log to determine whether the backend server can retrieve client IP addresses.

The default path of the Apache log is /var/log/httpd/access_log.

In each log entry, the leftmost IP address in the %{X-Forwarded-For}i variable is the client IP address.

image.png

IIS server

If you use an IIS server, you can check the IIS log to determine whether the backend server can retrieve client IP addresses.

You can find the path to the log file in the Logging module.

image.png

In each log entry, the leftmost IP address in X-Forwarded-For is the client IP address.

image.png

FAQ

Why do IP addresses that start with 100 frequently access backend ECS instances?

ALB forwards external requests to backend ECS instances by using the private IP address of the system server. ALB also accesses the ECS instances to perform health checks and monitor service availability.

The system CIDR block of ALB is 100.64.0.0/10, which is reserved by Alibaba Cloud. To prevent security issues, this CIDR block is not allocated to other network elements. As a result, the backend ECS instances are accessed by IP addresses that start with 100.

To ensure service availability, we recommend that you add a security rule which allows access from these IP addresses to all backend servers.

How does ALB preserve client IP addresses when it is used together with Web Application Firewall (WAF), Content Delivery Network (CDN), or Global Accelerator (GA)?

If requests are filtered by WAF, CDN, or GA before they reach ALB, you can use the X-Forwarded-For header to preserve client IP addresses. WAF, CDN, and GA can pass the X-Forwarded-For header to backend servers by default. No additional configurations are required.

If you want to prevent X-Forwarded-For spoofing, which can compromise service security, you can specify a header to record client IP addresses. For example, if a request travels through the client, CDN, WAF, ALB, and ECS, and CDN passes the Ali-Cdn-Real-Ip header to backend servers, you can enable Ali-Cdn-Real-Ip to record client IP addresses and add the $http_Ali_Cdn_Real_Ip variable to the NGINX configuration file. The IP address recorded by $http_Ali_Cdn_Real_Ip is the client IP address.

You can also take the following measures to improve system security:

  • Authenticate the X-Forwarded-For header: Enable backend servers to filter out requests that contain invalid or untrusted X-Forwarded-For headers. You can check the format and IP address of the X-Forwarded-For header to determine whether it is valid and trusted.

  • Enable firewalls and access control lists (ACLs): Deploy a firewall and an ACL between ALB and its backend servers to filter out malicious requests that may manipulate the X-Forwarded-For header.

  • Enable SSL/TLS encryption: Enable SSL/TLS encryption to encrypt data transmission, including the transmission of the X-Forward-For header. This measure prevents man-in-the-middle (MITM) attacks and data tampering.

How does ALB preserve client IP addresses when it is deployed in a Container Service for Kubernetes (ACK) cluster?

ALB can preserve client IP addresses when it is deployed in an ACK cluster. Client IP preservation may be implemented in different ways. For more information, see How do I configure the pods to obtain the real IP addresses of clients?

References

ALB, Classic Load Balancer (CLB), and Network Load Balancer (NLB) use different methods to preserve client IP addresses.