

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# HTTP 标头和 Application Load Balancer
<a name="x-forwarded-headers"></a>

HTTP 请求和 HTTP 响应使用标头字段发送有关 HTTP 消息的信息。HTTP 标头会自动添加。标头字段为冒号分隔的名称值对，各个值对之间由回车符 (CR) 和换行符 (LF) 进行分隔。RFC 2616 [信息标头](https://datatracker.ietf.org/doc/html/rfc2616)中定义了标准 HTTP 标头字段集。此外还有应用程序广泛使用和自动添加的非标准 HTTP 标头。某些非标准 HTTP 标头具有 `X-Forwarded` 前缀。Application Load Balancer 支持以下 `X-Forwarded` 标头。

有关 HTTP 连接的更多信息，请参阅 *Elastic Load Balancing 用户指南*中的[请求路由](https://docs.amazonaws.cn/elasticloadbalancing/latest/userguide/how-elastic-load-balancing-works.html#request-routing)。

**Topics**
+ [X-Forwarded-For](#x-forwarded-for)
+ [X-Forwarded-Proto](#x-forwarded-proto)
+ [X-Forwarded-Port](#x-forwarded-port)

## X-Forwarded-For
<a name="x-forwarded-for"></a>

在您使用 HTTP 或 HTTPS 负载均衡器时，`X-Forwarded-For` 请求标头可帮助您识别客户端的 IP 地址。由于负载均衡器会拦截客户端和服务器之间的流量，因此您的服务器访问日志中将仅包含负载均衡器的 IP 地址。要查看客户端的 IP 地址，请使用 `routing.http.xff_header_processing.mode` 属性。借助此属性，您可以在应用程序负载均衡器将请求发送到目标之前修改、保留或移除 HTTP 请求中的 `X-Forwarded-For` 标头。此属性的可能值为 `append`、`preserve` 和 `remove`。此属性的默认值为 `append`。

**重要**  
由于存在安全风险，应谨慎使用 `X-Forwarded-For` 标头。只有由网络内得到妥善保护的系统添加的条目才被视为可信。

**Topics**
+ [Append](#x-forwarded-for-append)
+ [Preserve](#x-forwarded-for-preserve)
+ [删除](#x-forwarded-for-remove)

### Append
<a name="x-forwarded-for-append"></a>

默认情况下，应用程序负载均衡器会在 `X-Forwarded-For` 请求标头中存储客户端的 IP 地址，并将该标头传递到您的服务器。如果 `X-Forwarded-For` 请求标头未包含在原始请求中，则负载均衡器会创建一个以客户端 IP 地址作为请求值的标头。否则，负载均衡器会将客户端 IP 地址附加到现有标头，然后将该标头传递到您的服务器。`X-Forwarded-For` 请求标头可能包含多个以逗号分隔的 IP 地址。

`X-Forwarded-For` 请求标头采用以下形式：

```
X-Forwarded-For: client-ip-address
```

下面是 IP 地址为 `203.0.113.7` 的客户端的 `X-Forwarded-For` 请求标头的示例。

```
X-Forwarded-For: 203.0.113.7
```

以下是 IPv6 地址为的客户端的`X-Forwarded-For`请求标头示例`2001:DB8::21f:5bff:febf:ce22:8a2e`。

```
X-Forwarded-For: 2001:DB8::21f:5bff:febf:ce22:8a2e
```

在负载均衡器上启用客户端端口保留属性（`routing.http.xff_client_port.enabled`）后，`X-Forwarded-For` 请求标头包括附加到 `client-ip-address` 的 `client-port-number`（以冒号分隔）。然后标头采用以下形式：

```
IPv4 -- X-Forwarded-For: client-ip-address:client-port-number
```

```
IPv6 -- X-Forwarded-For: [client-ip-address]:client-port-number
```

对于 IPv6，请注意，当负载均衡器将附加`client-ip-address`到现有标头时，它会将地址括在方括号中。

以下是 IPv4 地址为、端口号为的客户端`12.34.56.78`的`X-Forwarded-For`请求标头示例`8080`。

```
X-Forwarded-For: 12.34.56.78:8080
```

以下是 IPv6 地址为、端口号为的客户端`2001:db8:85a3:8d3:1319:8a2e:370:7348`的`X-Forwarded-For`请求标头示例`8080`。

```
X-Forwarded-For: [2001:db8:85a3:8d3:1319:8a2e:370:7348]:8080
```

### Preserve
<a name="x-forwarded-for-preserve"></a>

属性中的 `preserve` 模式会确保在将 HTTP 请求发送到目标之前不会以任何方式进行修改其中的 `X-Forwarded-For` 标头。

### 删除
<a name="x-forwarded-for-remove"></a>

属性中的 `remove` 模式会在将 HTTP 请求发送到目标之前移除其中的 `X-Forwarded-For` 标头。

如果您启用了客户端端口保留属性（`routing.http.xff_client_port.enabled`），同时还为 `routing.http.xff_header_processing.mode` 属性选择了 `preserve` 或 `remove`，则应用程序负载均衡器将覆盖客户端端口保留属性。它会将 `X-Forwarded-For` 标头保留不变，或者根据您选择的模式将其移除，然后再将请求发送到目标。

当您选择 `append`、`preserve` 或者 `remove` 模式时目标将收到的 `X-Forwarded-For` 标头示例见下表。在此例中，最后一跳的 IP 地址为 `127.0.0.1`。


| 请求描述 | 示例请求 | append | preserve | remove | 
| --- | --- | --- | --- | --- | 
| 发送请求时没有 XFF 标头 | GET /index.html HTTP/1.1 Host: example.com | X-Forwarded-For: 127.0.0.1 | 不存在 | 不存在 | 
| 发送请求时包含一个 XFF 标头和一个客户端 IP 地址。 | GET /index.html HTTP/1.1 Host: example.com X-Forwarded-For: 127.0.0.4 | X-Forwarded-For: 127.0.0.4, 127.0.0.1 | X-Forwarded-For: 127.0.0.4 | 不存在 | 
| 发送请求时包含一个 XFF 标头和多个客户端 IP 地址。 | GET /index.html HTTP/1.1 Host: example.com X-Forwarded-For: 127.0.0.4, 127.0.0.8 | X-Forwarded-For: 127.0.0.4, 127.0.0.8, 127.0.0.1 | X-Forwarded-For: 127.0.0.4, 127.0.0.8 | 不存在 | 

------
#### [ Console ]

**管理 X-Forwarded-For 标头**

1. 打开位于 [https://console.aws.amazon.com/ec2/](https://console.amazonaws.cn/ec2/) 的 Amazon EC2 控制台。

1. 在导航窗格中，选择**负载均衡器**。

1. 选择负载均衡器。

1. 在**属性**选项卡上，选择**编辑**。

1. 在 “**流量配置**” 部分的 “**数据包处理**” 下，为 “**X-Forwarded-For 标题**” 选择 “**追加**（默认）”、“**保留**” 或 “**移除**”。

1. 选择**保存更改**。

------
#### [ Amazon CLI ]

**管理 X-Forwarded-For 标头**  
使用带 `routing.http.xff_header_processing.mode` 属性的 [modify-load-balancer-attributes](https://docs.amazonaws.cn/cli/latest/reference/elbv2/modify-load-balancer-attributes.html) 命令。可能的值为 `append`、`preserve` 和 `remove`。默认为 `append`。

```
aws elbv2 modify-load-balancer-attributes \
    --load-balancer-arn load-balancer-arn \
    --attributes "Key=routing.http.xff_header_processing.mode,Value=preserve"
```

------
#### [ CloudFormation ]

**管理 X-Forwarded-For 标头**  
更新[AWS::ElasticLoadBalancingV2::LoadBalancer](https://docs.amazonaws.cn/AWSCloudFormation/latest/TemplateReference/aws-resource-elasticloadbalancingv2-loadbalancer.html)资源以包含该`routing.http.xff_header_processing.mode`属性。可能的值为 `append`、`preserve` 和 `remove`。默认为 `append`。

```
Resources:
  myLoadBalancer:
    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
    Properties:
      Name: my-alb
      Type: application
      Scheme: internal
      Subnets: 
        - !Ref subnet-AZ1
        - !Ref subnet-AZ2
      SecurityGroups: 
        - !Ref mySecurityGroup
      LoadBalancerAttributes: 
        - Key: "routing.http.xff_header_processing.mode"
          Value: "preserve"
```

------

## X-Forwarded-Proto
<a name="x-forwarded-proto"></a>

`X-Forwarded-Proto` 请求标头可帮助您识别客户端与您的负载均衡器连接时所用的协议 (HTTP 或 HTTPS)。您的服务器访问日志仅包含在服务器和负载均衡器之间使用的协议；不含任何关于在客户端和负载均衡器之间使用的协议之信息。如需判断在客户端和负载均衡器之间使用的协议，使用 `X-Forwarded-Proto` 请求标题。Elastic Load Balancing 会在 `X-Forwarded-Proto` 请求标头中存储客户端和负载均衡器之间使用的协议，并将标头传递到您的服务器。

您的应用程序或网站可以使用存储在 `X-Forwarded-Proto` 请求标头中的协议来呈现重新定向至适用 URL 的响应。

`X-Forwarded-Proto` 请求标头采用以下形式：

```
X-Forwarded-Proto: originatingProtocol
```

以下示例包含以 HTTPS 请求形式源自客户端的请求的 `X-Forwarded-Proto` 请求标头：

```
X-Forwarded-Proto: https
```

## X-Forwarded-Port
<a name="x-forwarded-port"></a>

`X-Forwarded-Port` 请求标头可帮助您识别客户端与您的负载均衡器连接时所用的目标端口。