

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

# DDoS 保护带有 Amazon GameLift Servers
<a name="ddos-protection-intro"></a>

Amazon GameLift Servers玩家网关是一个基于中继的网络，用于在游戏客户端和托管的游戏服务器之间路由 UDP 流量。Amazon GameLift ServersPlayer Gateway 通过在流量到达游戏服务器之前对其进行验证、限制玩家流量、向公众隐藏游戏服务器 IP 地址以及在中继端点变得不健康时提供更新的端点来提供主动的 DDo S 保护。此功能有助于保护您的游戏服务器免受容量攻击，延迟可以忽略不计。

玩家网关要求游戏服务器在基于 Linux 的Amazon GameLift Servers托管 EC2 队列或容器队列上运行。您必须在舰队创建期间启用玩家网关，并更新游戏客户端和游戏后端才能使用此功能。

## 主要优势
<a name="ddos-protection-intro-benefits"></a>

玩家网关具有以下安全性和运营优势：
+ **隐藏游戏服务器 IP 地址** — 游戏客户端通过中继端点而不是直接连接到游戏服务器，从而向公众隐藏您的游戏服务器地址。
+ **验证流量**-所有通过玩家网关的流量都需要玩家网关令牌，仅允许来自经过身份验证的玩家的流量到达您的游戏服务器。
+ **动态端点替换** — 当中继端点变得不健康时，Amazon GameLift Servers可以快速替换端点，并在下次调用时提供更新的健康端点以刷新玩家连接详细信息。
+ **分配玩家流量**-中继端点因玩家而异，从而减少单个不健康的中继端点对同一游戏会话中其他玩家的影响。

# 玩家网关的工作原理
<a name="ddos-protection-howitworks"></a>

玩家网关使用中继网络在游戏客户端和游戏服务器之间路由 UDP 流量。这通过在流量到达游戏服务器之前对其进行验证、限制玩家流量、向公众隐藏游戏服务器 IP 地址以及在中继端点变得不健康时提供更新的端点来防御 DDo S 攻击。

## 流量流
<a name="ddos-protection-howitworks-traffic-flow"></a>

当玩家连接到游戏会话时，您的游戏后端会从 `GetPlayerConnectionDetails` API 中检索中继端点和玩家网关令牌，并将其发送到游戏客户端。游戏客户端将玩家网关令牌预置在 UDP 数据包中，并将数据包发送到中继端点。中继网络验证令牌并将合法流量路由到游戏服务器。在交付之前，中继网络会剥离玩家网关令牌，以便游戏服务器接收原始游戏客户端有效负载，并且不需要更改代码。从游戏服务器返回到游戏客户端的通信通过中继网络返回，无需修改。

![\[架构图显示了游戏客户端通过中继网络连接到游戏服务器\]](http://docs.aws.amazon.com/zh_cn/gameliftservers/latest/developerguide/images/player_gateway_architecture.png)


## 核心概念
<a name="ddos-protection-howitworks-components"></a>

### 中继端点
<a name="ddos-protection-howitworks-endpoints"></a>

中继端点是游戏客户端用来通过玩家网关发送流量的 IP 地址和端口组合。每个玩家都会收到多个端点，这些端点因玩家而异，以分配流量并减少攻击对同一游戏会话中其他玩家的影响。

![\[该图显示了多个玩家在相同的游戏会话中接收不同的中继端点\]](http://docs.aws.amazon.com/zh_cn/gameliftservers/latest/developerguide/images/player_gateway_relay_endpoints.png)


### 玩家网关代币
<a name="ddos-protection-howitworks-tokens"></a>

玩家网关令牌是加密的字节数组，授权玩家通过玩家网关向游戏会话发送流量。`GetPlayerConnectionDetails`API 以 base64 编码的字符串形式返回令牌。游戏客户端必须在每个 UDP 数据包中预先添加玩家网关令牌。中继网络验证令牌并拒绝带有无效或缺失令牌的数据包。

**重要**  
玩家网关令牌不得加密，并且必须出现在游戏客户端发送的每个 UDP 数据包的开头。如果您的游戏对有效负载进行加密，请在加密游戏数据后预先添加未修改的玩家网关令牌。

玩家网关代币的有效期至少为 3 分钟。我们建议每 60 秒刷新一次令牌，以确保玩家在中继端点变得不健康时收到更新的端点。

### GetPlayerConnectionDetails API
<a name="ddos-protection-howitworks-api"></a>

您的游戏后端调用 `GetPlayerConnectionDetails` API 来检索游戏会话中玩家的连接详细信息。API 返回中继端点和玩家网关令牌，或者回退到游戏服务器的 IP 地址和端口进行直接连接。您的游戏客户端应设计为可以处理这两种连接类型。要在中继端点变得不健康时接收更新的端点，请在整个游戏会话中定期调用此 API（建议每 60 秒调用一次）。

有关更多信息，请参阅 [GetPlayerConnectionDetails API](ddos-protection-integrate.md#ddos-protection-integrate-backend-api)。

## 监控玩家网关
<a name="ddos-protection-howitworks-monitoring"></a>

Player gateway CloudWatch 向 Amazon 发布指标，以帮助您监控网络流量模式、识别潜在的 DDo S 攻击并跟踪中继性能。指标包括入/出的数据包和字节、限制的流量以及玩家会话。有关玩家网关指标的完整列表，请参阅[DDoS 保护（玩家网关）指标](monitoring-cloudwatch.md#gamelift-metrics-fleet-playergateway)。

## IPv4 和 IPv6 兼容性
<a name="ddos-protection-howitworks-ipv4-ipv6"></a>

游戏客户端使用进行通信 IPv4。玩家网关 IPv6 用于与游戏服务器通信。 Amazon GameLift Servers IPv6 根据您的舰队配置自动处理 IPv4 和之间的转换。

有关在舰队上配置玩家网关的更多信息，请参阅[CreateFleet](https://docs.aws.amazon.com/gameliftservers/latest/apireference/API_CreateFleet.html#gameliftservers-CreateFleet-request-PlayerGatewayMode)或[CreateContainerFleet](https://docs.aws.amazon.com/gameliftservers/latest/apireference/API_CreateContainerFleet.html#gameliftservers-CreateContainerFleet-request-PlayerGatewayMode)。有关 IPv4 和 IPv6 支持的更多信息，请参阅[IPv4 和 IPv6 兼容性](ddos-protection-enable.md#ddos-protection-enable-ip-protocol)。

# 在舰队上启用玩家网关
<a name="ddos-protection-enable"></a>

在创建队列时启用玩家网关，通过中继端点路由游戏流量，这些中继端点验证并限制传入游戏服务器的 UDP 流量。

## 先决条件
<a name="ddos-protection-enable-prerequisites"></a>

在启用玩家网关之前，请验证以下要求：
+ **支持的地点**-有关支持玩家网关 AWS 的地点列表，请参阅[Amazon GameLift Servers 服务位置](gamelift-regions.md)。
+ **舰队类型** — 玩家网关支持基于 Linux 的托管 EC2 队列和托管容器队列。
+ **服务器 SDK** — 玩家网关需要Amazon GameLift Servers服务器 SDK 5.0 或更高版本。

## 玩家网关模式
<a name="ddos-protection-enable-modes"></a>

使用以下`PlayerGatewayMode`属性为您的舰队配置玩家网关兼容性：

已禁用（默认）  
舰队与玩家网关不兼容。

已启用  
Fleet 在支持的地方与玩家网关兼容。不支持该功能的舰队位置仍然可以直接使用游戏服务器 IP 地址添加到舰队中，但不会使用玩家网关。

REQUIRED  
舰队与玩家网关兼容。不支持该功能的舰队位置无法添加到舰队中。

## IPv4 和 IPv6 兼容性
<a name="ddos-protection-enable-ip-protocol"></a>

游戏客户端必须通过 IPv4 与玩家网关通信。玩家网关中继网络使用 IPv6 与游戏服务器通信。托管容器队列会自动将 IPv6 流量转换为 IPv4。对于托管 EC2 队列，请使用以下`GameServerIpProtocolSupported`属性配置队列处理 IPv6 流量的方式：`PlayerGatewayConfiguration`

IPv4 （默认）  
您的游戏服务器仅接受传入 IPv4 流量。将在您的实例上安装和执行轻量级 IP 转换软件，以接收和转换传入的 IPv6 流量 IPv4。

DUAL\$1STACK  
您的游戏服务器与传入 IPv6 流量兼容。不会在您的实例上安装或执行 IP 转换软件。 IPv6 原生支持的游戏服务器的性能可能稍高一些。

# 将玩家网关集成到游戏中
<a name="ddos-protection-integrate"></a>

创建支持玩家网关的舰队后，必须更新游戏客户端和游戏后端才能与玩家网关集成。您的游戏后端会检索中继端点和玩家网关令牌，然后将其提供给游戏客户端。游戏客户端将所有 UDP 流量发送到这些中继端点。

集成遵循以下调用路径：

1. 您的游戏后端调用 `GetPlayerConnectionDetails` API 来检索游戏会话中每位玩家的中继端点和玩家网关令牌。

1. 您的游戏后端将中继端点和玩家网关令牌发送到游戏客户端。

1. 您的游戏客户端将玩家网关令牌预先添加到所有传出的 UDP 数据包中，并将数据包发送到中继端点。

1. 中继网络验证玩家网关令牌并将流量路由到您的游戏服务器。

1. 您的游戏服务器通过相同的中继路径将流量发送回游戏客户端。

## 后端集成
<a name="ddos-protection-integrate-backend"></a>

您的游戏后端必须调用 `GetPlayerConnectionDetails` API 来检索玩家的中继端点和玩家网关令牌。然后，后端将这些信息提供给游戏客户端。

### GetPlayerConnectionDetails API
<a name="ddos-protection-integrate-backend-api"></a>

`GetPlayerConnectionDetails`API 会返回游戏会话中玩家的连接详情：

中继端点和令牌  
当该位置启用并支持玩家网关时，将返回：  
+ **中继端点** — 多个中继端点（IP 地址和端口）因玩家而异
+ **玩家网关令**牌 — 客户端必须在所有 UDP 数据包之前添加的令牌（有效期至少 3 分钟）
+ **过期**-玩家网关令牌到期时间戳

直接连接  
如果该位置未启用或不支持玩家网关，则返回游戏服务器的 IP 地址和端口

您的游戏客户端应设计为可以处理这两种连接类型。

API 调用示例：

```
// C++ example using AWS SDK
Aws::GameLift::GameLiftClient client;
Aws::GameLift::Model::GetPlayerConnectionDetailsRequest request;
request.SetGameSessionId(gameSessionId);
request.SetPlayerIds(playerIds);  // Vector of player IDs

auto outcome = client.GetPlayerConnectionDetails(request);
if (outcome.IsSuccess()) {
    auto result = outcome.GetResult();
    auto connectionDetails = result.GetPlayerConnectionDetails();
    
    // Process each player's connection details
    for (const auto& detail : connectionDetails) {
        std::string playerId = detail.GetPlayerId();
        
        // Get relay endpoints (IP address and port)
        auto endpoints = detail.GetEndpoints();
        for (const auto& endpoint : endpoints) {
            std::string ipAddress = endpoint.GetIpAddress();
            int port = endpoint.GetPort();
        }
        
        // Get player gateway token
        auto token = detail.GetPlayerGatewayToken();
        
        // Get expiration time
        auto expiration = detail.GetExpiration();
        
        // Send endpoints and token to game client
    }
}
```

请参阅[GetPlayerConnectionDetails](https://docs.aws.amazon.com/gameliftservers/latest/apireference/API_GetPlayerConnectionDetails.html)《*Amazon GameLift ServersAPI 参考*》。

### 刷新中继端点
<a name="ddos-protection-integrate-backend-refresh"></a>

当中继端点变得不健康时，请`GetPlayerConnectionDetails`定期致电为玩家提供更新的端点。我们建议每隔 60 秒为游戏会话中的所有玩家调用 API。要优化 API 的使用，请在单个 API 调用 IDs 中批量处理多个玩家。

**重要**  
定期刷新调用是向玩家提供更新的端点的主要机制。虽然玩家网关令牌的有效期至少为 3 分钟，但每 60 秒刷新一次可确保玩家定期收到更新的终端节点。

## 客户端集成
<a name="ddos-protection-integrate-client"></a>

您的游戏客户端必须在所有传出的 UDP 数据包中预先添加玩家网关令牌，并将数据包发送到提供的中继端点。C\$1\$1 for C\$1\$1 和虚幻引擎的Amazon GameLift Servers客户端 SDK 提供了简化这种集成的实用工具。

### 客户端要求
<a name="ddos-protection-integrate-client-requirements"></a>

要通过玩家网关路由流量，您的游戏客户端必须：
+ **预置玩家网关令牌 — 将玩家网关令牌**预置到所有传出的 UDP 数据包中。玩家网关令牌不得加密，必须出现在每个数据包的开头。没有有效玩家网关令牌的数据包将被丢弃。
+ **发送到中继端点**-将所有 UDP 数据包发送到提供的中继端点。
+ **保持连接活动** — 确保游戏客户端向游戏服务器发送数据包，或者游戏服务器至少每 30 秒向玩家发送一次数据包。本活动通过中继网络维护连接。
+ **处理端点更新**-从您的后端接受更新的中继端点和玩家网关令牌（建议每 60 秒一次），并在不中断连接的情况下过渡到新的端点。

### 客户端 SDK
<a name="ddos-protection-integrate-client-sdk"></a>

C\$1\$1 for C\$1\$1 和虚幻引擎的Amazon GameLift Servers客户端 SDK 提供了简化玩家网关集成的实用工具：
+ **令牌管理** — 将玩家网关令牌预置到所有传出的 UDP 数据包中。
+ **端点选择**-使用可配置算法将流量路由到中继端点。
+ **端点刷新**-计划定期回调，以从您的后端检索更新的中继端点和玩家网关令牌。

### 端点选择算法
<a name="ddos-protection-integrate-client-algorithms"></a>

客户端 SDK 提供了两种内置算法，用于选择要使用的中继端点：

后备算法  
使用一个端点直到其运行状况不佳，然后切换到另一个端点。最适合可以短暂中断的菜单、大厅和回合制游戏。在端点故障转移期间，数据包可能会在配置的超时时间内丢失（默认值：2 秒）。

预测性旋转算法  
持续轮换所有可用端点，并在故障发生之前对其进行预测。最适合实时游戏玩法，例如第一人称射击游戏和赛车游戏，在这些游戏中，持续的数据包传输至关重要。要求游戏服务器以一致的频率发送消息。

您还可以通过扩展 SDK 的基础算法类来实现自定义算法。

### 客户端 SDK 资源
<a name="ddos-protection-integrate-client-resources"></a>

有关完整的集成说明和示例代码，请参阅以下资源：

C\$1\$1  
适用于 C\$1\$1 的客户端 SDK 可在适用于 C\$1 [\$1 的Amazon GameLift Servers客户端 SDK](https://github.com/amazon-gamelift/amazon-gamelift-servers-client-sdk-for-cpp) 中找到。

Unreal Engine  
虚幻引擎的插件可在虚幻引擎[的Amazon GameLift Servers客户端 SDK](https://github.com/amazon-gamelift-for-unreal/amazon-gamelift-servers-client-sdk-for-unreal) 中找到。访问权限需要在 Epic Games 组织中的成员资格 GitHub。详情请[访问虚幻引擎](https://www.unrealengine.com/en-US/ue-on-github)。 GitHub

## 测试您的集成。
<a name="ddos-protection-integrate-testing"></a>

在部署到队列之前，请使用玩家网关测试工具在本地测试您的玩家网关集成。该工具模拟玩家网关 UDP 代理基础架构，可帮助您验证游戏客户端是否正确预置了玩家网关令牌、通过多个端点路由流量以及处理网络退化问题。

有关设置和使用说明，请参阅上的 P [layer Gateway 测试应用程序](https://github.com/amazon-gamelift/amazon-gamelift-toolkit/tree/main/player-gateway-testing-app) GitHub。

## 最佳实践
<a name="ddos-protection-integrate-best-practices"></a>

集成玩家网关时，请遵循以下最佳实践：
+ **每 60 秒刷新一次端点** — `GetPlayerConnectionDetails` 每 60 秒调用一次，以确保玩家定期收到更新的端点。
+ **Batch API 调**用 — 在同一个游戏会话中`GetPlayerConnectionDetails`为多个玩家调用时，批量调用以减少 API 开销。
+ **保持连接活动**-确保流量至少每 30 秒在游戏客户端和游戏服务器之间流动一次。这可以是 client-to-server或 server-to-client流量。
+ **优雅地处理端点更新** — 当您的游戏客户端从后端收到更新的端点时，在不中断玩家连接的情况下过渡到新的端点。
+ **选择正确的算法** — 选择最符合游戏要求的端点选择算法。回合制游戏使用后备算法，实时游戏使用预测轮换算法。