

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

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

HTTP 請求和 HTTP 回應使用標頭欄位來傳送有關 HTTP 訊息的資訊。HTTP 標頭會自動新增。標頭欄位是以冒號分隔的名稱值組，以歸位字元 (CR) 和換行 (LF) 分隔。一組以 RFC 2616 定義的標準 HTTP 標頭欄位，[訊息標頭](https://datatracker.ietf.org/doc/html/rfc2616)。也有應用程式廣泛採用的非標準 HTTP 標頭可用 (而且會自動新增)。有些非標準 HTTP 標頭擁有 `X-Forwarded` 字首。Application Load Balancer 支援以下 `X-Forwarded` 標頭。

如需 HTTP 連線的詳細資訊，請參閱 *Elastic Load Balancing 使用者指南*中的[請求路由](https://docs.aws.amazon.com/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` 屬性。此屬性可讓您在 Application Load Balancer 將 HTTP 請求傳送至目標之前，修改、保留或移除該請求中的 `X-Forwarded-For` 標頭。此屬性的可能值為 `append`、`preserve` 和 `remove`。此屬性的預設值為 `append`。

**重要**  
由於可能存在安全風險，因此應謹慎使用 `X-Forwarded-For`標頭。只有在由網路內適當保護的系統新增時，才能將項目視為值得信任。

**Topics**
+ [附加](#x-forwarded-for-append)
+ [保留](#x-forwarded-for-preserve)
+ [移除](#x-forwarded-for-remove)

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

Application Load Balancer 依預設會將用戶端的 IP 地址儲存在 `X-Forwarded-For` 請求標頭，並將標頭傳遞給伺服器。如果 `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 地址 `2001:DB8::21f:5bff:febf:ce22:8a2e` 之用戶端的範例 `X-Forwarded-For` 請求標頭。

```
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`，連接埠號碼為 `8080`) 的 `X-Forwarded-For` 請求標頭範例。

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

下列是用戶端 (IPv6 地址為 `2001:db8:85a3:8d3:1319:8a2e:370:7348`，連接埠號碼為 `8080`) 的 `X-Forwarded-For` 請求標頭範例。

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

### 保留
<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`，則 Application Load Balancer 會覆寫用戶端連接埠保留屬性。此屬性可將 `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.aws.amazon.com/ec2/) 開啟 Amazon EC2 主控台。

1. 在導覽窗格上選擇 **Load Balancers (負載平衡器)**。

1. 選取負載平衡器。

1. 在**屬性**索引標籤中，選擇**編輯**。

1. 在**流量組態**區段的**封包處理**下，針對 **X-Forwarded-For 標頭**，選擇**附加 **（預設）、**保留**或**移除**。

1. 選擇**儲存變更**。

------
#### [ AWS CLI ]

**管理 X-Forwarded-For標頭**  
以 [ 屬性來使用 ](https://docs.aws.amazon.com/cli/latest/reference/elbv2/modify-load-balancer-attributes.html)modify-load-balancer-attributes`routing.http.xff_header_processing.mode` 命令。可能的值為 `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.aws.amazon.com/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
```

以下範例包含適用於從用戶端產生的 `X-Forwarded-Proto` 請求標頭，以做為 HTTPS 請求：

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

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

`X-Forwarded-Port` 請求標頭協助您識別用戶端用於連接到負載平衡器的目的地連接埠。