本指南将引导你设置按主机名 authenticated origin pulls,使用 mutual TLS verify ↗ 安全连接到 AWS Application Load Balancer。
- 你应已有 AWS 账户并已配置 EC2 ↗。
- 请注意,本教程使用命令行界面 (CLI) 生成自定义证书,并使用 API 调用 配置 Cloudflare Authenticated Origin Pulls。
- 有关 AWS 最新设置文档,请参阅 AWS 文档 ↗。
- 运行以下命令生成 4096 位 RSA 私钥,使用 AES-256 加密。出现提示时输入密码短语。
openssl genrsa -aes256 -out rootca.key 4096- 创建 CA 根证书。出现提示时,填写要包含在证书中的信息。对于
Common Name字段,使用域名作为值,而非主机名。
openssl req -x509 -new -nodes -key rootca.key -sha256 -days 1826 -out rootca.crt- 创建证书签名请求(CSR)。出现提示时,填写要包含在请求中的信息。对于
Common Name字段,使用主机名作为值。
openssl req -new -nodes -out cert.csr -newkey rsa:4096 -keyout cert.key- 使用前面步骤创建的
rootca.key和rootca.crt签署证书。
openssl x509 -req -in cert.csr -CA rootca.crt -CAkey rootca.key -CAcreateserial -out cert.crt -days 730 -sha256 -extfile ./cert.v3.ext- 确保证书扩展文件
cert.v3.ext指定以下内容:
basicConstraints=CA:FALSE- 将
rootca.cert上传到 S3 存储桶 ↗。 - 在 EC2 控制台创建信任存储 ↗,指定上传证书的 S3 URI。
- 创建 EC2 实例并安装 HTTPD 守护进程。根据需求选择实例类型 ↗——可使用符合 AWS Free Tier ↗ 的最小实例。本教程基于 t2.micro 和 Amazon Linux 2023 ↗ 示例。
sudo yum install -y httpd
sudo systemctl start httpd- 为 Application Load Balancer 创建目标组 ↗。
- 选择 Instances(实例) 作为目标类型。
- 指定端口
HTTP/80。
- 完成目标组配置后,确认目标组处于健康 ↗状态。
- 配置负载均衡器和监听器 ↗。
- 选择 Internet-facing(面向互联网) 方案。
- 将监听器切换到端口
443,以便 mTLS 选项可用,并选择前面创建的目标组。 - 对于 Default SSL/TLS server certificate(默认 SSL/TLS 服务器证书),选择 Import certificate(导入证书) > Import to ACM(导入到 ACM),并添加证书私钥和正文。
- 在 Client certificate handling(客户端证书处理) 下,选择 Verify with trust store(使用信任库验证)。
- 保存设置。
- (可选)运行以下命令确认 Application Load Balancing 请求客户端证书。
openssl s_client -verify 5 -connect <your-application-load-balancer>:443 -quiet -state由于你尚未将证书上传到 Cloudflare,连接应失败(例如 read:errno=54)。
你也可以运行 curl --verbose 并确认 SSL/TLS 握手中存在 Request CERT (13):
curl --verbose https://<your-application-load-balancer>
...
* TLSv1.2 (IN), TLS handshake, Request CERT (13):
...- 将步骤 1 中创建的证书上传到 Cloudflare。应使用 leaf 证书,而非 root CA。
使用以下命令通过 API 上传 per-hostname 证书:
MYCERT="$(cat cert.crt|perl -pe 's/\r?\n/\\n/'|sed -e 's/..$//')"
MYKEY="$(cat cert.key|perl -pe 's/\r?\n/\\n/'|sed -e's/..$//')"
request_body=$(< <(cat <<EOF
{
"certificate": "$MYCERT",
"private_key": "$MYKEY",
"bundle_method":"ubiquitous"
}
EOF
))
# Push the certificate
curl --silent \
"https://api.cloudflare.com/client/v4/zones/$ZONEID/origin_tls_client_auth/hostnames/certificates" \
--header "Content-Type: application/json" \
--header "X-Auth-Email: $MYAUTHEMAIL" \
--header "X-Auth-Key: $MYAUTHKEY" \
--data "$request_body"Required API token permissions
At least one of the following token permissions is required:SSL and Certificates Write
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/origin_tls_client_auth/hostnames" \
--request PUT \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
--json '{
"config": [
{
"enabled": true,
"cert_id": "<CERT_ID>",
"hostname": "<YOUR_HOSTNAME>"
}
]
}'-
使用
PUT请求 在主机名上禁用 Authenticated Origin Pulls。
At least one of the following token permissions is required:Required API token permissions
SSL and Certificates Write
Enable or Disable a Hostname for Client Authenticationbash curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/origin_tls_client_auth/hostnames" \ --request PUT \ --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \ --json '{ "config": [ { "enabled": false, "cert_id": "<CERT_ID>", "hostname": "<YOUR_HOSTNAME>" } ] }' -
(可选)使用
GET请求 获取客户端证书 ID 列表。下一步移除证书时需要您要移除的证书 ID。
At least one of the following token permissions is required:Required API token permissions
SSL and Certificates WriteSSL and Certificates Read
List Certificatesbash curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/origin_tls_client_auth/hostnames/certificates" \ --request GET \ --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" -
使用 Delete hostname client certificate 端点移除您上传的证书。
At least one of the following token permissions is required:Required API token permissions
SSL and Certificates Write
Delete Hostname Client Certificatebash curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/origin_tls_client_auth/hostnames/certificates/$CERTIFICATE_ID" \ --request DELETE \ --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"