znlgis 博客

GIS开发与技术分享 — GDAL · GeoServer · PostGIS · QGIS · OpenLayers · Cesium · FreeCAD · NPOI

第06章 - 国际云服务商集成使用

本章介绍 acme.sh 与国际主流云服务商和 DNS 服务商的集成使用,包括 Cloudflare、AWS(亚马逊云)、Google Cloud、Microsoft Azure、DigitalOcean、Oracle Cloud、Vultr、Hetzner 等。


6.1 Cloudflare

Cloudflare 是全球最流行的 DNS 服务商和 CDN 提供商,acme.sh 对 Cloudflare 的支持非常完善。

6.1.1 获取 Cloudflare API 凭据

推荐方式:API Token(最小权限)

  1. 登录 Cloudflare 控制台
  2. 点击”创建令牌” → 选择”编辑区域 DNS”模板
  3. 在”区域资源”下选择对应的域名区域(或”所有区域”)
  4. 创建令牌,保存 Token 值
  5. 同时获取账户 ID(在控制台右侧边栏可见)

旧方式:Global API Key(不推荐)

全局 API Key 拥有账户的完整权限,泄露风险较高,不推荐使用。

6.1.2 申请证书

# ============================================================
# 方式一:使用 API Token(推荐)
# ============================================================
export CF_Token="zfNp-Xm0VhSaCNun7dkLzwnw0UN7FNjaMurUZ8vf"
export CF_Account_ID="763eac4f1bcebd8b5c95e9fc50d010b4"

# 单个 Zone 的 Token 可以只提供 Zone ID(不需要 Account ID)
# export CF_Zone_ID="3cc91d809a6ff7a93eb48877bf0ec3ef"

# 申请通配符证书
acme.sh --issue --dns dns_cf -d example.com -d *.example.com

# 申请 ECC 证书
acme.sh --issue --dns dns_cf \
  -d example.com -d *.example.com \
  --keylength ec-256

# ============================================================
# 方式二:使用 Global API Key(不推荐)
# ============================================================
export CF_Key="a62e9c685ac445fce1b3c098dc1790dc"
export CF_Email="alice@example.com"

acme.sh --issue --dns dns_cf -d example.com -d *.example.com

6.1.3 Cloudflare Proxy(CDN 代理)注意事项

如果域名在 Cloudflare 开启了”代理”(橙色云图标),HTTP-01 验证可能会受影响,建议:

  • 使用 DNS API 模式(推荐,本身就是 DNS-01 验证,不受代理影响)
  • 如果必须使用 HTTP-01,临时关闭代理(灰色云图标)

6.1.4 Cloudflare Worker / Pages 环境

在 Cloudflare Workers 或 Pages 环境中,可以使用 acme.sh 的 SSH deploy hook 将证书推送到后端服务器,或者使用 Cloudflare 自己的证书服务(通常无需 acme.sh)。


6.2 AWS(Amazon Web Services)

6.2.1 AWS Route53 DNS API(dns_aws)

AWS Route53 是亚马逊云的 DNS 服务,acme.sh 通过 AWS CLI 凭据或 IAM Role 访问 Route53 API。

获取 AWS 凭据:

  1. 登录 AWS IAM 控制台
  2. 创建 IAM 用户,选择”程序化访问”
  3. 附加以下权限策略(或创建自定义策略):
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "route53:GetChange",
        "route53:ChangeResourceRecordSets",
        "route53:ListResourceRecordSets"
      ],
      "Resource": [
        "arn:aws:route53:::hostedzone/*",
        "arn:aws:route53:::change/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "route53:ListHostedZones",
        "route53:ListHostedZonesByName"
      ],
      "Resource": ["*"]
    }
  ]
}
  1. 保存 Access Key ID 和 Secret Access Key

申请证书:

# 使用 Access Key
export AWS_ACCESS_KEY_ID="AKIAIOSFODNN7EXAMPLE"
export AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"

acme.sh --issue --dns dns_aws -d example.com -d *.example.com

# 如果遇到 API 速率限制,添加延迟
export AWS_DNS_SLOWRATE=1
acme.sh --issue --dns dns_aws -d example.com -d *.example.com

EC2 IAM Role(免密钥方式):

如果 acme.sh 运行在 EC2 实例上,并且该实例绑定了具有 Route53 权限的 IAM Role,则无需配置任何密钥:

# 不需要设置任何 AWS 环境变量
acme.sh --issue --dns dns_aws -d example.com -d *.example.com

6.2.2 AWS EC2 完整部署流程

# 1. 安装 acme.sh
curl https://get.acme.sh | sh -s email=your@email.com
source ~/.bashrc

# 2. 配置 AWS 凭据
export AWS_ACCESS_KEY_ID="your_key_id"
export AWS_SECRET_ACCESS_KEY="your_secret_key"

# 3. 申请证书
acme.sh --issue --dns dns_aws \
  -d example.com -d *.example.com \
  --server letsencrypt  # 可选:指定 CA

# 4. 安装证书到 Nginx
mkdir -p /etc/nginx/ssl/example.com
acme.sh --install-cert -d example.com \
  --key-file       /etc/nginx/ssl/example.com/privkey.pem \
  --fullchain-file /etc/nginx/ssl/example.com/fullchain.pem \
  --reloadcmd      "systemctl reload nginx"

6.2.3 AWS ELB / ALB 证书上传

AWS 的弹性负载均衡器(ELB/ALB)使用 AWS Certificate Manager(ACM)管理证书。可以通过 AWS CLI 将 acme.sh 签发的证书上传到 ACM:

# 安装 AWS CLI
pip install awscli

# 上传证书到 ACM
aws acm import-certificate \
  --certificate fileb://~/.acme.sh/example.com/example.com.cer \
  --private-key fileb://~/.acme.sh/example.com/example.com.key \
  --certificate-chain fileb://~/.acme.sh/example.com/fullchain.cer \
  --region us-east-1

# 配置自动更新脚本
cat > /opt/upload_cert_to_acm.sh << 'EOF'
#!/bin/bash
CERT_ARN="arn:aws:acm:us-east-1:123456789012:certificate/xxxxxx"
aws acm import-certificate \
  --certificate-arn $CERT_ARN \
  --certificate fileb:///etc/ssl/example.com/fullchain.pem \
  --private-key fileb:///etc/ssl/example.com/privkey.pem \
  --region us-east-1
EOF
chmod +x /opt/upload_cert_to_acm.sh

# 在 install-cert 中调用此脚本
acme.sh --install-cert -d example.com \
  --fullchain-file /etc/ssl/example.com/fullchain.pem \
  --key-file /etc/ssl/example.com/privkey.pem \
  --reloadcmd "systemctl reload nginx && /opt/upload_cert_to_acm.sh"

6.3 Google Cloud Platform(GCP)

6.3.1 Google Cloud DNS(dns_gcloud)

前提条件:服务器上已安装并认证了 gcloud CLI

# 安装 gcloud CLI(如果尚未安装)
curl https://sdk.cloud.google.com | bash

# 初始化并认证
gcloud init
gcloud auth application-default login

# 确认当前配置
gcloud config list

申请证书:

export CLOUDSDK_ACTIVE_CONFIG_NAME=default

acme.sh --issue --dns dns_gcloud -d example.com -d *.example.com

所需 GCP IAM 权限:dns.admin 或自定义角色(包含 dns.resourceRecordSets.createdns.resourceRecordSets.deletedns.resourceRecordSets.listdns.changes.createdns.managedZones.list)。

6.3.2 Google Compute Engine 完整流程

# 1. 在 GCE 实例上安装 acme.sh
curl https://get.acme.sh | sh -s email=your@email.com
source ~/.bashrc

# 2. 使用 GCE 元数据服务认证(如果实例有 DNS 权限的服务账号)
export CLOUDSDK_ACTIVE_CONFIG_NAME=default
gcloud auth application-default login

# 3. 申请证书
acme.sh --issue --dns dns_gcloud -d example.com -d *.example.com

# 4. 安装到 Nginx
acme.sh --install-cert -d example.com \
  --key-file       /etc/nginx/ssl/privkey.pem \
  --fullchain-file /etc/nginx/ssl/fullchain.pem \
  --reloadcmd      "systemctl reload nginx"

6.4 Microsoft Azure

6.4.1 Azure DNS(dns_azure)

获取凭据(Service Principal 方式):

# 安装 Azure CLI
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash

# 登录
az login

# 创建服务主体
az ad sp create-for-rbac \
  --name acme-dns-sp \
  --role "DNS Zone Contributor" \
  --scopes /subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/providers/Microsoft.Network/dnszones/<DNS_ZONE>

# 输出示例:
# {
#   "appId": "xxxxxx",         <- AZUREDNS_APPID
#   "displayName": "acme-dns-sp",
#   "password": "xxxxxx",     <- AZUREDNS_CLIENTSECRET
#   "tenant": "xxxxxx"        <- AZUREDNS_TENANTID
# }

# 获取 Subscription ID
az account show --query id -o tsv

申请证书:

# 方式一:Service Principal(适合大多数场景)
export AZUREDNS_SUBSCRIPTIONID="12345678-1234-1234-1234-123456789012"
export AZUREDNS_TENANTID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
export AZUREDNS_APPID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
export AZUREDNS_CLIENTSECRET="your_client_secret"

acme.sh --issue --dns dns_azure -d example.com -d *.example.com

# 方式二:Managed Identity(在 Azure VM 上使用,无需密钥)
export AZUREDNS_SUBSCRIPTIONID="12345678-1234-1234-1234-123456789012"
export AZUREDNS_MANAGEDIDENTITY=true

acme.sh --issue --dns dns_azure -d example.com -d *.example.com

6.4.2 将证书上传到 Azure Key Vault

# 安装证书到本地
acme.sh --install-cert -d example.com \
  --fullchain-file /etc/ssl/example.com/fullchain.pem \
  --key-file /etc/ssl/example.com/privkey.pem

# 将证书导入 Azure Key Vault(需要 PFX 格式)
openssl pkcs12 -export \
  -in /etc/ssl/example.com/fullchain.pem \
  -inkey /etc/ssl/example.com/privkey.pem \
  -out /tmp/example.com.pfx \
  -passout pass:""

az keyvault certificate import \
  --vault-name MyKeyVault \
  --name example-com-cert \
  --file /tmp/example.com.pfx

6.5 DigitalOcean

6.5.1 获取 API 凭据

  1. 登录 DigitalOcean 控制台
  2. 创建个人访问令牌(Personal Access Token)
  3. 权限选择:Domains(Read + Write)
export DO_API_KEY="your_digitalocean_personal_access_token"

acme.sh --issue --dns dns_dgon \
  -d example.com -d *.example.com

# 安装到 Nginx
acme.sh --install-cert -d example.com \
  --key-file       /etc/nginx/ssl/privkey.pem \
  --fullchain-file /etc/nginx/ssl/fullchain.pem \
  --reloadcmd      "systemctl reload nginx"

6.6 Oracle Cloud Infrastructure(OCI)

6.6.1 Oracle Cloud DNS(dns_oci)

OCI DNS 是 Oracle 提供的 DNS 服务,acme.sh 支持通过 OCI API 进行 DNS-01 验证。

获取 OCI API 凭据:

  1. 登录 OCI 控制台
  2. 进入 Identity → API Keys
  3. 生成 API Key 对,下载私钥文件
  4. 记录 Tenancy OCID、User OCID、Key Fingerprint 等信息

配置 OCI CLI(推荐):

# 安装 OCI CLI
bash -c "$(curl -L https://raw.githubusercontent.com/oracle/oci-cli/master/scripts/install/install.sh)"

# 配置
oci setup config
# 申请证书
acme.sh --issue --dns dns_oci -d example.com -d *.example.com

6.7 Vultr

# 获取 API Key:https://my.vultr.com/settings/#settingsapi
export VULTR_API_KEY="your_vultr_api_key"

acme.sh --issue --dns dns_vultr -d example.com -d *.example.com

6.8 Hetzner

Hetzner 是德国知名的高性价比 VPS 服务商。

# 获取 API Token:https://dns.hetzner.com/settings/api-token
export HETZNER_Token="your_hetzner_dns_token"

acme.sh --issue --dns dns_hetzner -d example.com -d *.example.com

6.9 Linode(Akamai Cloud)

Linode(现已更名为 Akamai Cloud)支持 DNS API 验证。

# 获取 API Key:https://cloud.linode.com/profile/tokens
export LINODE_V4_API_KEY="your_linode_api_key"

# Linode DNS 传播较慢,建议等待 900 秒
acme.sh --issue --dns dns_linode_v4 \
  -d example.com -d *.example.com \
  --dnssleep 900

6.10 Namecheap

# 获取 API Key:https://www.namecheap.com/myaccount/api/
# 需要账号余额 $50+ 或 20+ 域名才能启用 API
export NAMECHEAP_USERNAME="your_username"
export NAMECHEAP_API_KEY="your_api_key"
export NAMECHEAP_SOURCEIP="your_server_ip"  # Namecheap 要求白名单 IP

acme.sh --issue --dns dns_namecheap -d example.com -d *.example.com

6.11 GoDaddy

# 获取 API Key:https://developer.godaddy.com/
# 注意:GoDaddy API 需要账号有 10+ 域名或开通 Discount Domain Club
export GD_Key="your_godaddy_api_key"
export GD_Secret="your_godaddy_api_secret"

# GoDaddy DNS 传播需要较长时间
acme.sh --issue --dns dns_gd \
  -d example.com -d *.example.com \
  --dnssleep 600

6.12 Porkbun

Porkbun 是一家价格实惠的域名注册商,支持 API 访问。

# 获取 API Key:https://porkbun.com/account/api
export PORKBUN_API_KEY="your_api_key"
export PORKBUN_SECRET_API_KEY="your_secret_api_key"

acme.sh --issue --dns dns_porkbun -d example.com -d *.example.com

6.13 Vercel

# 获取 Token:https://vercel.com/account/tokens
export VERCEL_TOKEN="your_vercel_token"

acme.sh --issue --dns dns_vercel -d example.com -d *.example.com

6.14 Netlify

# 获取 Token:https://app.netlify.com/user/applications/personal
export NETLIFY_ACCESS_TOKEN="your_netlify_token"

acme.sh --issue --dns dns_netlify -d example.com -d *.example.com

6.15 Bunny DNS

Bunny.net 的 DNS 服务(之前的 BunnyDNS):

# 获取 API Key:https://panel.bunny.net/account
export BUNNY_API_KEY="your_bunny_api_key"

acme.sh --issue --dns dns_bunny -d example.com -d *.example.com

6.16 NS1(NSONE)

export NS1_Key="your_ns1_api_key"

acme.sh --issue --dns dns_nsone -d example.com -d *.example.com

6.17 DNSimple

# 获取 OAuth Token:https://dnsimple.com/user/access_tokens
export DNSimple_OAUTH_TOKEN="your_dnsimple_oauth_token"

acme.sh --issue --dns dns_dnsimple -d example.com -d *.example.com

6.18 Gandi LiveDNS

# 获取 API Key:https://account.gandi.net/
export GANDI_LIVEDNS_TOKEN="your_gandi_token"

acme.sh --issue --dns dns_gandi_livedns -d example.com -d *.example.com

6.19 OVH / Kimsufi / So You Start

OVH 是欧洲著名的云服务商:

# 申请 OVH API 凭据:https://eu.api.ovh.com/createApp/
export OVH_AK="your_application_key"
export OVH_AS="your_application_secret"
export OVH_CK="your_consumer_key"
export OVH_END="ovh-eu"  # 或 ovh-us, ovh-ca, soyoustart-eu, kimsufi-eu

acme.sh --issue --dns dns_ovh -d example.com -d *.example.com

6.20 完整多云混合部署示例

以下场景:域名在 Cloudflare 管理,服务器分布在 AWS、GCP 和 DigitalOcean,使用 acme.sh 统一管理证书:

# 服务器 A(AWS EC2)- 申请证书
export CF_Token="your_cf_token"
export CF_Account_ID="your_cf_account_id"

acme.sh --issue --dns dns_cf \
  -d example.com -d *.example.com \
  --server letsencrypt \
  --keylength ec-256

# 安装本地 Nginx
acme.sh --install-cert -d example.com \
  --key-file       /etc/nginx/ssl/privkey.pem \
  --fullchain-file /etc/nginx/ssl/fullchain.pem \
  --reloadcmd      "systemctl reload nginx"

# 同时通过 SSH 部署到其他服务器
export DEPLOY_SSH_USER="ubuntu"
export DEPLOY_SSH_SERVER="gcp-server.example.com"
export DEPLOY_SSH_KEYFILE="/etc/ssl/deploy/privkey.pem"
export DEPLOY_SSH_FULLCHAIN="/etc/ssl/deploy/fullchain.pem"
export DEPLOY_SSH_REMOTE_CMD="systemctl reload nginx"

acme.sh --deploy -d example.com --deploy-hook ssh

6.21 小结

本章介绍了 acme.sh 与主要国际云服务商的集成:

  • Cloudflare:使用 API Token(最小权限),是最常用的 DNS API
  • AWS Route53:支持 Access Key 和 IAM Role(EC2 实例角色)两种方式
  • GCP Cloud DNS:通过 gcloud CLI 认证
  • Azure DNS:支持 Service Principal 和 Managed Identity
  • DigitalOcean / Vultr / Hetzner / Linode:简单的 API Key 配置
  • 域名注册商(GoDaddy、Namecheap、Porkbun):通过注册商 API 管理 DNS

各提供商 DNS 传播速度不同,必要时使用 --dnssleep 参数增加等待时间。

下一章将介绍证书的部署和安装到各种服务。