Skip to content

How to Identify the Real Client IP on ALB When Using CloudFront as a Front End

3 minute read
Content level: Intermediate
0

When you use an Application Load Balancer (ALB) as a CloudFront origin, the ALB sees CloudFront edge server IPs as the client — not the actual viewer's IP. This article explains three methods to retrieve the real client IP at your ALB target.

Background

In a Client → CloudFront → ALB → Target architecture:

  • The ALB receives requests from CloudFront edge servers, not directly from the end user.
  • In ALB access logs, the client:port field contains the CloudFront edge server IP.
  • To identify the real viewer IP, you need to use specific HTTP headers.

Methods to Retrieve the Real Client IP

1. X-Forwarded-For Header

X-Forwarded-For is the de facto standard header for identifying the originating client IP. When a request passes through multiple proxies, each proxy appends its IP:

X-Forwarded-For: <client>, <proxy1>, <proxy2>

The leftmost value is the original client IP.

ALB X-Forwarded-For behavior:

ALB supports three modes for this header, configurable via load balancer attributes:

ModeBehavior
Append (default)ALB appends its own node IP to the existing header
PreserveALB passes the header through without modification
RemoveALB strips the header before forwarding to the target

Note: ALB also supports client port preservation via the routing.http.xff_client_port.enabled attribute. When enabled, the client port is appended to the IP in X-Forwarded-For (e.g., 130.176.96.72:8080). For IPv6, the address is enclosed in square brackets (e.g., [2600:9000:a518:2d8c::1]:8080).

Note: In most CloudFront + ALB setups, the default Append mode is appropriate. The X-Forwarded-For header will contain: <viewer IP>, <CloudFront edge IP>.

2. CloudFront-Viewer-Address Header

CloudFront can add the CloudFront-Viewer-Address header, which contains the viewer's IP and source port:

CloudFront-Viewer-Address: <client_ip>:<port>

This is available at no additional cost.

How to enable:

  • Option A: In your CloudFront distribution's origin request policy, use the managed policy: AllViewerAndCloudFrontHeaders-2022-06
  • Option B: Create a custom origin request policy and add CloudFront-Viewer-Address under "Include the following headers"

3. True-Client-IP Header (via CloudFront Functions)

You can use a CloudFront Function to set a True-Client-IP header from the viewer request event:

async function handler(event) {
    var request = event.request;
    var clientIP = event.viewer.ip;

    //Add the true-client-ip header to the incoming request
    request.headers['true-client-ip'] = {value: clientIP};

    return request;
}

Note: This example uses CloudFront Functions JavaScript runtime 2.0, which supports async handlers.

Requirements:

  • Associate this function as a viewer request function on your CloudFront distribution.
  • Ensure your origin request policy forwards the True-Client-IP header. The managed policy AllViewerAndCloudFrontHeaders-2022-06 includes it.

Recommendation

  • Use CloudFront-Viewer-Address for the most reliable single-value client IP — it's set by CloudFront itself and not subject to spoofing via the request chain.
  • Use X-Forwarded-For if your application already parses this standard header, but be aware it can be spoofed by the client prepending arbitrary values.
  • Use True-Client-IP via CloudFront Functions if you need a clean, single-value header and want explicit control.

References

AWS
SUPPORT ENGINEER
published a month ago167 views