# AWS ALB 配置 HTTPS：ACM 免费证书、DNS 验证与自动续期

> 用 AWS Certificate Manager 申请免费证书并做 DNS 验证，挂到应用负载均衡器（ALB）的 HTTPS 监听器，配置 TLS 1.3 策略和 HTTP 跳转，附 AWS 中国区差异。

Source: https://ssl.sh/zh/guides/aws-acm-alb/
Last updated: 2026-11-10

AWS 应用负载均衡器（ALB）配置 HTTPS 分三步：在 ACM 申请免费证书并用 DNS 验证，把证书挂到 443 监听器，再把 80 端口改成 301 跳转。DNS 验证的 ACM 证书到期前由 ACM 自动续期。

命令用 AWS CLI v2（控制台步骤相同），以截至 2026 年 11 月的 ACM 和 Elastic Load Balancing 为准。用亚马逊云科技中国区（北京、宁夏）的读者，先看下一节。

## 全球区域和中国区有什么不同

ALB 加 ACM 的做法在中国区基本一样，差别在账户、ARN、CloudFront 和端口备案。

- **运营方和账户**：中国区由本地合作伙伴运营，北京区域（`cn-north-1`）由光环新网运营，宁夏区域（`cn-northwest-1`）由西云数据运营。要用中国区必须单独注册亚马逊云科技中国区账户，凭证和全球账户不通用，全球账户也登录不了中国区控制台。
- **ARN 前缀**：中国区资源的 ARN 以 `arn:aws-cn:` 开头，下面命令里的 ARN 要整段换成中国区的，比如 `arn:aws-cn:elasticloadbalancing:cn-north-1:...`。
- **ACM 可以用**：ACM 从 2020 年 3 月起在两个中国区域都能签发公有证书，并部署到 ELB、API Gateway 等集成服务，官方的中国区说明页写明 ACM 与全球区域没有差异。所以下面的申请、DNS 验证和自动续期步骤在中国区同样适用。
- **CloudFront 不支持 ACM**：中国区的 CloudFront 目前不支持 ACM，只能把第三方 CA 签发的证书上传到 IAM 证书库再关联；而且 `*.cloudfront.cn` 默认域名不能直接对外提供内容，必须配置已备案的自定义域名（CNAME）。
- **端口和备案**：按国内法规，中国区默认关闭 80、8080、443 端口。北京区域通过光环新网、宁夏区域通过西云数据办理 ICP 备案，备案流程的最后一步才是开放这几个端口。没有备案或许可证的域名不得提供互联网信息服务，所以 ALB 的 HTTPS 监听器要等备案完成后才能对外提供服务。

网站不托管在中国大陆境内的，继续用全球区域的账户即可，下面的流程不变，也不涉及中国区的备案和端口限制。

## 前提条件

ALB 和目标组要已经能用 HTTP 正常提供服务。

- 已配置好的 AWS CLI v2，有 ACM 和 Elastic Load Balancing 权限（`aws sts get-caller-identity` 能正常返回）。
- 一个面向互联网的 ALB、它的目标组和两者的 ARN；安全组放行入站 80 和 443。
- 能修改域名 DNS（Route 53 或其他服务商，国内的云解析、DNSPod 都可以），用来添加验证 CNAME，并把 `example.com` 指向 ALB。
- 如果设置了 CAA 记录，要允许 Amazon（`amazon.com`、`amazontrust.com`、`awstrust.com` 或 `amazonaws.com` 之一），可以用 [CAA 检查](https://ssl.sh/zh/tools/caa-checker/) 确认。
- 中国区：域名已完成 ICP 备案，80 和 443 端口已开放。

## 第一步：申请证书

ACM 证书按区域划分，要在 ALB 所在的区域申请：

```bash
export AWS_REGION=eu-west-1        # 中国区换成 cn-north-1 或 cn-northwest-1
CERT_ARN=$(aws acm request-certificate \
  --domain-name example.com \
  --subject-alternative-names www.example.com \
  --validation-method DNS \
  --key-algorithm EC_prime256v1 \
  --query CertificateArn --output text)
echo "$CERT_ARN"
```

`EC_prime256v1` 申请的是 ECDSA 密钥，需要兼容很老的客户端时改用 `RSA_2048`。

## 第二步：添加 DNS 验证记录

ACM 用 CNAME 记录验证域名，先列出它要求的记录：

```bash
aws acm describe-certificate --certificate-arn "$CERT_ARN" \
  --query 'Certificate.DomainValidationOptions[].ResourceRecord' --output table
```

到 DNS 服务商逐条添加（域名在 Route 53 时，控制台的证书页面有 **Create records in Route 53** 按钮）。国内 DNS 服务商的“主机记录”一栏通常只填前缀，不要把完整域名填进去。然后等待验证完成：

```bash
aws acm wait certificate-validated --certificate-arn "$CERT_ARN"
```

这条 CNAME 以后也不要删，自动续期要靠它。

## 第三步：创建 HTTPS 监听器

HTTPS 监听器在 443 端口终止 TLS，引用 ACM 证书和安全策略，再把请求转发到目标组：

```bash
ALB_ARN=arn:aws:elasticloadbalancing:eu-west-1:111122223333:loadbalancer/app/web/0123456789abcdef
TG_ARN=arn:aws:elasticloadbalancing:eu-west-1:111122223333:targetgroup/web/0123456789abcdef
aws elbv2 create-listener --load-balancer-arn "$ALB_ARN" \
  --protocol HTTPS --port 443 \
  --certificates CertificateArn="$CERT_ARN" \
  --ssl-policy ELBSecurityPolicy-TLS13-1-2-2021-06 \
  --default-actions Type=forward,TargetGroupArn="$TG_ARN"
```

把 ARN 换成你自己的（`aws elbv2 describe-load-balancers` 和 `describe-target-groups` 能查到），中国区的 ARN 以 `arn:aws-cn:` 开头。`ELBSecurityPolicy-TLS13-1-2-2021-06` 同时启用 TLS 1.3 和 1.2；各区域可用的新策略用 `aws elbv2 describe-ssl-policies` 查看。TLS 1.3 现行规范是 2026 年 7 月发布的 RFC 9846。

## 第四步：HTTP 跳转 HTTPS，并把域名指向 ALB

把 80 端口监听器的默认动作改成跳转（没有就先创建一个）：

```bash
HTTP_LISTENER_ARN=$(aws elbv2 describe-listeners --load-balancer-arn "$ALB_ARN" \
  --query 'Listeners[?Port==`80`].ListenerArn' --output text)
aws elbv2 modify-listener --listener-arn "$HTTP_LISTENER_ARN" \
  --default-actions 'Type=redirect,RedirectConfig={Protocol=HTTPS,Port=443,StatusCode=HTTP_301}'
```

然后把 `example.com`（Route 53 用别名记录）和 `www.example.com`（别名或 CNAME）指向 ALB 的 DNS 名称。用国内 DNS 服务商时，根域名不能设 CNAME 的，可以只让 `www` 指向 ALB，再把根域名跳转到 `www`。

## 验证

配置正确时，证书颁发者是 Amazon，`http://` 返回 301 跳转到 `https://`。用 [SSL 证书检查](https://ssl.sh/zh/tools/ssl-checker/) 从外部检查，或在终端运行：

```bash
curl ssl.sh/example.com
curl -sI http://example.com | grep -iE '^(HTTP|location)'
```

在 AWS 里查看证书状态、关联的资源和到期时间：

```bash
aws acm describe-certificate --certificate-arn "$CERT_ARN" --query 'Certificate.[Status,InUseBy,NotAfter]'
```

## 自动续期

DNS 验证的 ACM 公有证书会自动续期，前提有两个：证书仍关联在 ALB 这类 AWS 服务上，验证用的 CNAME 一直留在 DNS 里。续期后 ARN 不变，监听器不用任何改动。随时可以查看续期状态：

```bash
aws acm describe-certificate --certificate-arn "$CERT_ARN" --query 'Certificate.RenewalSummary'
```

导入到 ACM 的证书不会被续期，要自己换。公网证书的最长有效期由 CA/浏览器论坛规定，2026 年 3 月 15 日起是 200 天，2027 年 3 月 15 日起 100 天，2029 年 3 月 15 日起 47 天，ACM 续期会越来越频繁，但只要 CNAME 在就是全自动的。中国区 CloudFront 用的 IAM 证书同样不会自动续期，必须自己按时替换。建议把域名加到 [ssl.sh 监控](https://ssl.sh/zh/monitor/)（开发中） 作为外部检查，长期规划见 [为 47 天证书做准备](https://ssl.sh/zh/guides/prepare-for-47-day-certificates/)。

## 常见问题排查

- **状态一直是 PENDING_VALIDATION**：CNAME 没加，或者主机记录里多拼了一次主域名，对照 `describe-certificate` 的输出检查。
- **CAA_ERROR 或验证失败**：CAA 记录没有允许 Amazon，见 [CAA 记录阻止签发](https://ssl.sh/zh/errors/caa-record-prevents-issuance/)。
- **创建监听器时找不到证书**：证书申请在了别的区域，或者在全球区域申请的证书想用在中国区。
- **中国区 ALB 配好了但外部访问不通**：80/443 端口尚未开放，先确认 ICP 备案已完成。
- **浏览器提示域名不匹配**：证书里没有这个域名，或者 DNS 指向了别的负载均衡器，见 [NET::ERR_CERT_COMMON_NAME_INVALID](https://ssl.sh/zh/errors/net-err-cert-common-name-invalid/)。
- **老客户端握手失败**：TLS 1.3/1.2 策略或 ECDSA 密钥不兼容，见 [ERR_SSL_VERSION_OR_CIPHER_MISMATCH](https://ssl.sh/zh/errors/err-ssl-version-or-cipher-mismatch/)。
