Application Load Balancer - 弹性负载均衡

Application Load Balancer

负载均衡器充当客户端的单一接触点。客户端将请求发送到负载均衡器,负载均衡器再将它们发送到具体目标(例如 EC2 实例)。要配置您的负载均衡器,可以创建目标组,然后将目标注册到目标组。您还可以创建侦听器来检查来自客户端的连接请求,并创建侦听器规则以将来自客户端的请求路由到一个或多个目标组中的目标。

有关更多信息,请参阅 Elastic Load Balancing 用户指南中的 Elastic Load Balancing 工作原理

您的负载均衡器的子网

创建 Application Load Balancer 时,必须指定下列子网类型之一:可用区、本地扩展区或 Outpost。

可用区

您必须至少选择两个可用区子网。以下限制适用:

  • 每个子网都必须来自不同的可用区。

  • 要确保您的负载均衡器可以正确扩展,请验证您的负载均衡器的每个可用区子网都具有一个带有至少一个 /27 位掩码的 CIDR 数据块(例如,10.0.0.0/27)以及每个子网至少 8 个空闲 IP 地址。您的负载均衡器将使用这些 IP 地址与目标建立连接。根据您的流量配置文件,负载均衡器可以进一步扩展,最多可使用分布在所有已启用子网中的 100 个 IP 地址。

本地区域

您可以指定一个或多个本地区域子网。以下限制适用:

  • 您不能与负载均衡器一起使用 AWS WAF。

  • 您不能将 Lambda 函数用作目标。

Outposts

您可以指定单个 Outpost 子网。以下限制适用:

  • 您必须已在本地数据中心中安装并配置了 Outpost。Outpost 与其 AWS 区域之间必须具有可靠的网络连接。有关更多信息,请参阅 AWS Outposts 用户指南

  • 负载均衡器需要在 Outpost 上为负载均衡器节点设置两个 large 实例。支持的实例类型见下表。负载均衡器可根据需要进行扩展,每次可将节点大小调整一个型号(从 largexlarge,然后从 xlarge2xlarge,然后从 2xlarge4xlarge)。将节点扩展到最大实例型号后,如果您还需要额外的容量,负载均衡器会添加 4xlarge 实例以作为负载均衡器节点。如果您没有足够的实例容量或可用 IP 地址来扩展负载均衡器,负载均衡器将向 AWS Health Dashboard 报告事件,并且负载均衡器状态为 active_impaired

  • 您可以通过实例 ID 或 IP 地址注册目标。如果您在 AWS 区域中为 Outpost 注册目标,则不会使用这些目标。

  • 以下功能不可用:Lambda 函数作为目标、AWS WAF 集成、粘性会话、身份验证支持以及与 AWS Global Accelerator 的集成。

Application Load Balancer 可以在 Outpost 上的 c5/c5d、m5/m5d 或 r5/r5d 实例上部署。下表显示了负载均衡器在 Outpost 上可以使用的每个实例类型的大小和 EBS 卷:

实例类型和大小 EBS 卷 (GB)
c5/c5d
large 50
xlarge 50
2xlarge 50
4xlarge 100
m5/m5d
large 50
xlarge 50
2xlarge 100
4xlarge 100
r5/r5d
large 50
xlarge 100
2xlarge 100
4xlarge 100

负载均衡器安全组

安全组起到防火墙的作用,可控制允许往返于负载均衡器的流量。您可以选择端口和协议以允许入站和出站流量。

与负载均衡器关联的安全组的规则必须允许侦听器和运行状况检查端口上的双向流量。当您将侦听器添加到负载均衡器或更新目标组的运行状况检查端口时,您必须检查您的安全组规则,确保它们允许新端口上的双向流量。有关更多信息,请参阅 推荐的规则

负载均衡器状态

负载均衡器可能处于下列状态之一:

provisioning

正在设置负载均衡器。

active

负载均衡器已完全设置并准备好路由流量。

active_impaired

负载均衡器正在路由流量,但没有扩展所需的资源。

failed

负载均衡器无法设置。

负载均衡器属性

以下是负载均衡器属性:

access_logs.s3.enabled

指示是否启用存储在 Amazon S3 中的访问日志。默认为 false

access_logs.s3.bucket

访问日志所用的 Amazon S3 存储桶的名称。如果启用访问日志,则此属性是必需的。有关更多信息,请参阅启用访问日志

access_logs.s3.prefix

Amazon S3 存储桶中位置的前缀。

deletion_protection.enabled

指示是否启用删除保护。默认为 false

idle_timeout.timeout_seconds

空闲超时值 (以秒为单位)。默认值为 60 秒。

ipv6.deny_all_igw_traffic

阻止 Internet 网关 (IGW) 访问负载均衡器,以防通过 Internet 网关意外访问内部负载均衡器。对于面向互联网的负载均衡器,它设置为 false;对于内部负载均衡器,它设置为 true。此属性不会阻止非 IGW Internet 访问(例如,通过对等连接、Transit Gateway、AWS Direct Connect 或者AWS VPN)。

routing.http.desync_mitigation_mode

确定负载均衡器如何处理可能对您的应用程序构成安全风险的请求。可能的值为 monitordefensivestrictest。默认为 defensive

routing.http.drop_invalid_header_fields.enabled

指示具有无效标头字段的 HTTP 标头是被负载均衡器删除 (true) 还是路由到目标 (false)。默认为 false。Elastic Load Balancing 要求有效的 HTTP 标头名称符合正则表达式 [-A-Za-z0-9]+,如 HTTP 字段名注册表中所述。每个名称都由字母数字字符或连字符组成。如果您想从请求中删除不符合此模式的 HTTP 标头,请选择 true

routing.http.preserve_host_header.enabled

指示应用程序负载均衡器是否应保留 HTTP 请求中的 Host 标头,并将请求发送到目标而不作任何更改。可能的值为 truefalse。默认为 false

routing.http.x_amzn_tls_version_and_cipher_suite.enabled

指示两个标头(x-amzn-tls-versionx-amzn-tls-cipher-suite)在发送到目标之前是否将被添加到客户端请求,标头中包含有关协商 TLS 版本和密码套件的信息。x-amzn-tls-version 标头包含有关与客户端协商的 TLS 协议版本的信息,x-amzn-tls-cipher-suite 标头包含有关与客户端协商的密码套件的信息。两个标头都采用 OpenSSL 格式。属性的可能值为 truefalse。默认为 false

routing.http.xff_client_port.enabled

指示 X-Forwarded-For 标头是否应保留客户端用于连接负载均衡器的源端口。可能的值为 truefalse。默认为 false

routing.http.xff_header_processing.mode

这让您可以在应用程序负载均衡器将请求发送到目标之前修改、保留或移除 HTTP 请求中的 X-Forward-For 标头。可能的值为 appendpreserveremove。默认为 append

  • 如果该值为 append,则应用程序负载均衡器会将客户端 IP 地址(最后一跳)添加到 HTTP 请求的 X-Forward-For 标头,然后再将请求发送到目标。

  • 如果该值为 preserve,则应用程序负载均衡器会保留 HTTP 请求中的 X-Forward-For 标头,并将请求发送到目标而不作任何更改。

  • 如果该值为 remove,则应用程序负载均衡器会移除 HTTP 请求中的 X-Forward-For 标头,然后再将请求发送到目标。

routing.http2.enabled

指示是否启用了 HTTP/2。默认为 true

waf.fail_open.enabled

指示如果启用 AWS WAF 的负载均衡器无法将请求转发到 AWS WAF,是否允许其将请求路由到目标。可能的值为 truefalse。默认为 false

注意

引入了 routing.http.drop_invalid_header_fields.enabled 属性以提供 HTTP 不同步保护。添加 routing.http.desync_mitigation_mode 属性以为您的应用程序提供更全面的保护,使其免受 HTTP 不同步的影响。您无需同时使用这两个属性,可以根据应用程序的要求选择其中一个。

IP 地址类型

您可以设置客户端可用于访问面向 Internet 和内部的负载均衡器的 IP 地址类型。

以下是 IP 地址类型:

ipv4

客户端必须使用 IPv4 地址连接到负载均衡器(例如 192.0.2.1)。

dualstack

客户端可以同时使用 IPv4 地址(例如 192.0.2.1)和 IPv6 地址(例如,2001:0db8:85a3:0:0:8a2e:0370:7334)连接到负载均衡器。

双堆栈负载均衡器注意事项
  • 负载均衡器根据目标组的 IP 地址类型与目标进行通信。

  • 当您为负载均衡器启用双堆栈模式时,Elastic Load Balancing 为负载均衡器提供 AAAA DNS 记录。使用 IPv4 地址与负载均衡器通信的客户端解析 A DNS 记录。使用 IPv6 地址与负载均衡器通信的客户端解析 AAAA DNS 记录。

  • 阻止通过互联网网关对内部双堆栈负载均衡器的访问,以防意外访问互联网。但是,这不会阻止非 IGW(例如,通过对等连接、Transit Gateway、AWS Direct Connect 或者 AWS VPN)访问互联网。

跨可用区负载均衡

对于应用程序负载均衡器,默认情况下启用跨可用区负载均衡,无法在负载均衡器级别进行更改。有关更多信息,请参阅《Elastic Load Balancing 用户指南》中的跨可用区负载均衡

可以在目标组级别关闭跨可用区负载均衡。有关更多信息,请参阅关闭跨可用区负载均衡

连接空闲超时

对于客户端通过负载均衡器发出的每个请求,负载均衡器将维护两个连接。前端连接位于客户端和负载均衡器之间。后端连接位于负载均衡器和目标之间。负载均衡器具有应用于其连接的已配置空闲超时期限。超过空闲超时期限后,如果没有发送或接收任何数据,负载均衡器将关闭连接。为确保长时间运行的操作 (例如文件上传) 有足够时间来完成,请在到达每个空闲超时期限前发送至少 1 个字节的数据,并根据需要增大空闲超时期限的长度。

对于后端连接,我们建议您对 EC2 实例启用 HTTP 保持连接选项。您可以在 EC2 实例的 Web 服务器设置中启用 HTTP 保持活动选项。如果您启用 HTTP 保持活动选项,负载均衡器即可重复使用后端连接,直到保持活动超时过期。此外,我们建议您将应用程序的空闲超时配置为大于负载均衡器的空闲超时的值。否则,如果应用程序不正常地关闭了与负载均衡器的 TCP 连接,则负载均衡器可能会在收到数据包之前向应用程序发送请求,表明连接已关闭。如果是这种情况,则负载均衡器将向客户端发送 HTTP 502 Bad Gateway(HTTP 502 无效网关)错误。

默认情况下,Elastic Load Balancing 将负载均衡器的空闲超时值设置为 60 秒。使用以下过程设置不同的空闲超时值。

使用控制台更新空闲超时值
  1. 通过以下网址打开 Amazon EC2 控制台:https://console.aws.amazon.com/ec2/

  2. 在导航窗格中,选择 Load Balancers

  3. 选择负载均衡器。

  4. Attributes(属性)选项卡上,选择 Edit(编辑)。

  5. 流量配置下,输入空闲超时的值(以秒为单位)。有效端口范围从 1 到 4000。

  6. 选择 Save changes(保存更改)。

使用 AWS CLI 更新空闲超时值

使用带 idle_timeout.timeout_seconds 属性的 modify-load-balancer-attributes 命令。

删除保护

为了防止您的负载均衡器被意外删除,您可以启用删除保护。默认情况下,已为负载均衡器禁用删除保护。

如果您为负载均衡器启用删除保护,则必须先禁用删除保护,然后才能删除负载均衡器。

使用控制台启用删除保护
  1. 通过以下网址打开 Amazon EC2 控制台:https://console.aws.amazon.com/ec2/

  2. 在导航窗格中,选择 Load Balancers

  3. 选择负载均衡器。

  4. Attributes(属性)选项卡上,选择 Edit(编辑)。

  5. 配置下,打开删除保护

  6. 选择 Save changes(保存更改)。

使用控制台禁用删除保护
  1. 通过以下网址打开 Amazon EC2 控制台:https://console.aws.amazon.com/ec2/

  2. 在导航窗格中,选择 Load Balancers

  3. 选择负载均衡器。

  4. Attributes(属性)选项卡上,选择 Edit(编辑)。

  5. 配置页面下,关闭删除保护

  6. 选择 Save changes(保存更改)。

使用 AWS CLI 启用或禁用删除保护

使用带 deletion_protection.enabled 属性的 modify-load-balancer-attributes 命令。

异步缓解模式

异步缓解模式可以保护您的应用程序不受由于 HTTP 异步造成的问题的影响。负载均衡器根据每个请求的威胁级别对请求进行分类,允许安全请求,然后根据您指定的缓解模式来减轻风险。异步缓解模式包括“监控”、“防御”和“最严格”。默认情况下采用“防御”模式,该模式可在保持应用程序可用性的同时,针对 HTTP 异步提供持久的缓解作用。您可以切换到最严格模式,确保应用程序只接收符合 RFC 7230 标准的请求。

http_desync_guardian 库会分析 HTTP 请求,防止发生 HTTP 异步攻击。有关更多信息,请参阅 GitHub 上的 HTTP 异步监护

分类

下面列出了这些分类。

  • 合规 – 请求符合 RFC 7230 标准,不构成已知的安全威胁。

  • 可接受 - 请求不符合 RFC 7230 标准,但不构成已知的安全威胁。

  • 不明确 - 请求不符合 RFC 7230 标准,会带来风险,因为各个 Web 服务器和代理可能会以不同的方式处理该请求。

  • 严重 - 请求会带来很高的安全风险。负载均衡器会阻止请求,向客户端提供 400 响应,并关闭客户端连接。

如果请求不符合 RFC 7230 标准,负载均衡器将递增 DesyncMitigationMode_NonCompliant_Request_Count 指标。有关更多信息,请参阅Application Load Balancer 指标

每个请求的分类都包含在负载均衡器访问日志中。如果请求不符合,则访问日志将包含分类原因代码。有关更多信息,请参阅分类原因

Modes

下表描述 Application Load Balancer 如何根据模式和分类来处理请求。

分类。 监控模式 防御模式 最严格模式
合规 已允许 已允许 已允许
可接受 已允许 已允许 阻止
不明确 已允许 已允许¹ 阻止
严重 已允许 阻止 阻止

¹ 系统将路由请求,但关闭客户端和目标连接。如果您的负载均衡器在防御模式下收到大量不明确请求,则可能会产生额外费用。这是因为每秒增加的新连接数会影响每小时使用的负载均衡器容量单位 (LCU)。您可以使用 NewConnectionCount 指标比较负载均衡器在监控模式和防御模式下建立新连接的方式。

使用控制台更新异步缓解模式
  1. 通过以下网址打开 Amazon EC2 控制台:https://console.aws.amazon.com/ec2/

  2. 在导航窗格中,选择 Load Balancers

  3. 选择负载均衡器。

  4. Attributes(属性)选项卡上,选择 Edit(编辑)。

  5. 数据包处理下,对于 Desync 缓解模式,选择防御最严格监控

  6. 选择 Save changes(保存更改)。

使用 AWS CLI 更新异步缓解模式

使用 modify-load-balancer-attributes 命令,并将 routing.http.desync_mitigation_mode 属性设置为 monitordefensivestrictest

主机标头保留

启用 Preserve host header(保留主机标头)属性时,应用程序负载均衡器会保留 HTTP 请求中的 Host 标头,并将请求发送到目标而不做任何修改。如果应用程序负载均衡器收到多个 Host 标头,它会保留所有这些标头。侦听器规则仅会应用于收到的第一个 Host 标头。

默认情况下,未启用 Preserve host header(保留主机标头)属性时,应用程序负载均衡器会通过以下方式修改 Host 标头:

未启用主机标头保留,且侦听器端口为非默认端口时:不使用默认端口(端口 80 或 443)时,如果客户端尚未附加端口号,我们会将端口号附加到主机标头中。例如,假设侦听器端口是非默认端口(例如 8080),HTTP 请求中具有 Host: www.example.comHost 标头将被修改为 Host: www.example.com:8080

未启用主机标头保留,并且侦听器端口为默认端口(端口 80 或 443)时:对于默认侦听器端口(端口 80 或 443),我们不会将端口号附加到传出的主机标头中。传入主机标头中已经存在的任何端口号都将被移除。

应用程序负载均衡器将如何根据侦听器端口来处理 HTTP 请求中的主机标头的更多示例见下表。

侦听器端口

示例请求

请求中的主机标头

已禁用主机标头保留(默认行为)

已启用主机标头保留
在默认的 HTTP/HTTPS 侦听器上发送请求。 GET /index.html HTTP/1.1 Host: example.com example.com example.com example.com
在默认的 HTTP 侦听器上发送请求,并且主机标头具有端口(80 或 443)。 GET /index.html HTTP/1.1 Host: example.com:80 example.com:80 example.com example.com:80
请求具有绝对路径。 GET https://dns_name/index.html HTTP/1.1 Host: example.com example.com dns_name example.com
在非默认侦听器上发送请求,并且主机标头具有端口(例如 8080)。 GET /index.html HTTP/1.1 Host: example.com example.com example.com:8080 example.com
启用主机标头保留
  1. 通过以下网址打开 Amazon EC2 控制台:https://console.aws.amazon.com/ec2/

  2. 在导航窗格中,选择 Load Balancers (负载均衡器)

  3. 选择负载均衡器。

  4. Attributes(属性)选项卡上,选择 Edit(编辑)。

  5. 数据包处理下,打开保留主机标头

  6. 选择 Save changes(保存更改)。

使用 AWS CLI 启用主机标头保留

使用 modify-load-balancer-attributes 命令,并将 routing.http.preserve_host_header.enabled 属性设置为 true

Application Load Balancer 和 AWS WAF

您可以使用 AWS WAF 和 Application Load Balancer 以根据 Web 访问控制列表 (Web ACL) 中的规则允许或阻止请求。有关更多信息,请参阅AWS WAF开发人员指南中的使用 Web ACL

要检查负载均衡器是否与 AWS WAF 集成,请在 AWS Management Console中选择负载均衡器,然后选择 Integrated services (集成的服务) 选项卡。

默认情况下,如果负载均衡器无法从 AWS WAF 获取响应,则它将返回 HTTP 500 错误且不会转发请求。如果您需要负载均衡器将请求转发到目标,即使它无法联系 AWS WAF,也可以启用 AWS WAF 失败时开放属性。

要使用控制台启用 AWS WAF 失败时开放
  1. 通过以下网址打开 Amazon EC2 控制台:https://console.aws.amazon.com/ec2/

  2. 在导航窗格中,选择 Load Balancers

  3. 选择负载均衡器。

  4. Attributes(属性)选项卡上,选择 Edit(编辑)。

  5. 流量配置下,打开打开 WAF 失败

  6. 选择 Save changes(保存更改)。

要使用 AWS CLI 启用 AWS WAF 失败时开放

使用 modify-load-balancer-attributes 命令,并将 waf.fail_open.enabled 属性设置为 true