acme.sh + Cloudflare SSL 证书管理 🔐

🔐 自动化管理泛域名 SSL 证书,支持多级子域名安全加密


✨ 特点和功能

acme.sh 是一个强大且轻量的 ACME 协议客户端,具有以下特点:

  • 🚀 完全自动化:支持证书自动申请、更新和部署
  • 🔒 安全可靠:支持 ECC、RSA 多种密钥类型,集成 OCSP Stapling
  • 🌐 多域名支持:支持泛域名证书和多域名 SAN 证书
  • 📦 易于部署:一键安装,简单配置即可使用
  • 🔄 持续维护:活跃的开源社区,定期更新和维护
  • 🛡️ 零依赖:纯 Shell 编写,无需额外依赖环境
  • 💡 多模式验证:支持 DNS、HTTP、TLS-ALPN 等多种验证方式

📖 目录导航


🚀 快速开始

🌟 一站式安装脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash
# 🚀 acme.sh 快速安装和配置脚本

echo "开始安装 acme.sh..."
curl https://get.acme.sh | sh -s email=meimolihan@live.com

echo "配置环境..."
source ~/.bashrc
alias acme.sh=~/.acme.sh/acme.sh

echo "设置默认 CA..."
acme.sh --set-default-ca --server letsencrypt

echo "安装完成!版本信息:"
acme.sh -v

📦 acme.sh 安装

🐧 安装方法

1
2
3
4
5
6
7
8
9
10
# 方法一:国际源安装(推荐)
curl https://get.acme.sh | sh -s email=meimolihan@live.com

# 方法二:国内源安装
curl https://gitcode.net/cert/cn-acme.sh/-/raw/master/install.sh?inline=false | sh -s email=meimolihan@live.com

# 方法三:Git 克隆安装
git clone --depth 1 https://github.com/acmesh-official/acme.sh.git
cd acme.sh
./acme.sh --install -m meimolihan@live.com

🔧 安装后配置

1
2
3
4
5
6
7
8
9
10
11
# 重新加载 Shell 配置
source ~/.bashrc

# 创建别名方便使用
alias acme.sh=~/.acme.sh/acme.sh

# 验证安装
acme.sh -v

# 设置自动升级
acme.sh --upgrade --auto-upgrade

🎯 支持的证书颁发机构

1
2
3
4
5
6
7
8
9
# 查看所有支持的 CA
acme.sh --list-server

# 设置默认 CA
acme.sh --set-default-ca --server letsencrypt # Let's Encrypt
acme.sh --set-default-ca --server buypass # Buypass
acme.sh --set-default-ca --server zerossl # ZeroSSL
acme.sh --set-default-ca --server ssl.com # SSL.com
acme.sh --set-default-ca --server google # Google Public CA

🔑 Cloudflare API 配置

🌐 获取 Cloudflare API Token

  1. 登录 Cloudflare: https://dash.cloudflare.com/
  2. 进入 API Tokens: 右上角用户图标 → My Profile → API Tokens
  3. 创建 Token:
    • 使用模板 “Edit zone DNS”
    • 权限: Zone - DNS - Edit
    • 资源: Include - All zones (或指定域名)
  4. 保存 Token: 复制生成的 API Token

Cloudflare API Token

📝 配置环境变量

1
2
3
4
5
6
7
8
9
# 设置 Cloudflare API Token
export CF_Token="your_cloudflare_api_token_here"

# 可选:设置 Zone ID(如果管理多个区域)
export CF_Zone_ID="your_zone_id_here"

# 验证配置
echo "CF_Token: $CF_Token"
echo "CF_Zone_ID: $CF_Zone_ID"

🔒 安全配置建议

1
2
3
4
5
6
7
8
9
# 创建专用配置文件
mkdir -p ~/.acme.sh/conf
cat > ~/.acme.sh/conf/cloudflare.env << EOF
CF_Token="your_cloudflare_api_token_here"
CF_Zone_ID="your_zone_id_here"
EOF

# 设置严格权限
chmod 600 ~/.acme.sh/conf/cloudflare.env

📝 证书申请

🎯 申请泛域名证书

1
2
3
4
5
6
7
8
9
10
11
# 申请泛域名证书(支持多级子域名)
acme.sh --issue --dns dns_cf \
-d "mobufan.eu.org" \
-d "*.mobufan.eu.org" \
--keylength ec-256

# 使用 RSA 密钥(兼容性更好)
acme.sh --issue --dns dns_cf \
-d "mobufan.eu.org" \
-d "*.mobufan.eu.org" \
--keylength 2048

📊 申请多个域名

1
2
3
4
5
6
7
# 同时申请多个域名证书
acme.sh --issue --dns dns_cf \
-d "example.com" \
-d "*.example.com" \
-d "test.org" \
-d "*.test.org" \
--keylength ec-256

🔍 调试模式

1
2
3
4
5
6
7
8
9
10
11
# 启用调试模式查看详细过程
acme.sh --issue --dns dns_cf \
-d "mobufan.eu.org" \
-d "*.mobufan.eu.org" \
--debug

# 更详细的调试
acme.sh --issue --dns dns_cf \
-d "mobufan.eu.org" \
-d "*.mobufan.eu.org" \
--debug 2

📁 证书部署

🗂️ 创建证书目录

1
2
3
4
5
6
7
# 创建 Nginx 证书目录
sudo mkdir -p /etc/nginx/ssl
sudo chmod 755 /etc/nginx/ssl

# 创建其他服务证书目录
sudo mkdir -p /etc/ssl/private
sudo chmod 700 /etc/ssl/private

📋 安装证书到 Nginx

1
2
3
4
5
6
7
8
9
# 安装证书并设置自动重载
acme.sh --install-cert -d mobufan.eu.org \
--key-file /etc/nginx/ssl/key.pem \
--fullchain-file /etc/nginx/ssl/cert.pem \
--reloadcmd "systemctl reload nginx"

# 验证证书安装
ls -la /etc/nginx/ssl/
openssl x509 -in /etc/nginx/ssl/cert.pem -noout -text

🔄 多服务部署

1
2
3
4
5
6
7
8
9
10
# 部署到多个服务
acme.sh --install-cert -d mobufan.eu.org \
--key-file /etc/nginx/ssl/key.pem \
--fullchain-file /etc/nginx/ssl/cert.pem \
--reloadcmd "systemctl reload nginx"

acme.sh --install-cert -d mobufan.eu.org \
--key-file /etc/apache2/ssl/key.pem \
--fullchain-file /etc/apache2/ssl/cert.pem \
--reloadcmd "systemctl reload apache2"

📊 证书格式转换

1
2
3
4
5
6
7
8
9
10
# 转换为 PKCS12 格式(用于 Java 应用)
openssl pkcs12 -export \
-in /etc/nginx/ssl/cert.pem \
-inkey /etc/nginx/ssl/key.pem \
-out /etc/nginx/ssl/cert.p12 \
-passout pass:password

# 转换为 DER 格式
openssl x509 -in /etc/nginx/ssl/cert.pem \
-outform der -out /etc/nginx/ssl/cert.der

⚡ 自动维护

🕐 自动续签配置

1
2
3
4
5
6
7
8
# 查看当前计划任务
crontab -l

# 添加自动续签任务
(crontab -l; echo '0 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null') | crontab -

# 验证计划任务
crontab -l | grep acme

📋 证书管理命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 查看所有证书
acme.sh --list

# 查看证书详细信息
acme.sh --info -d mobufan.eu.org

# 手动续签证书
acme.sh --renew -d mobufan.eu.org --force

# 检查证书有效期
openssl x509 -in /etc/nginx/ssl/cert.pem -noout -dates

# 撤销证书
acme.sh --remove -d mobufan.eu.org
acme.sh --revoke -d mobufan.eu.org

🔄 更新和维护

1
2
3
4
5
6
7
8
9
10
11
# 更新 acme.sh
acme.sh --upgrade

# 关闭自动更新
acme.sh --upgrade --auto-upgrade 0

# 重新启用自动更新
acme.sh --upgrade --auto-upgrade 1

# 卸载 acme.sh
acme.sh --uninstall

🔧 故障排除

🐛 常见问题解决

1. DNS 验证失败

1
2
3
4
5
6
7
8
9
10
# 检查 DNS 记录
dig TXT _acme-challenge.mobufan.eu.org

# 手动验证 DNS
nslookup -type=TXT _acme-challenge.mobufan.eu.org

# 检查 Cloudflare API 连接
curl -X GET "https://api.cloudflare.com/client/v4/zones" \
-H "Authorization: Bearer $CF_Token" \
-H "Content-Type: application/json"

2. 权限问题

1
2
3
4
5
6
7
# 修复证书文件权限
sudo chmod 644 /etc/nginx/ssl/cert.pem
sudo chmod 600 /etc/nginx/ssl/key.pem
sudo chown root:root /etc/nginx/ssl/*.pem

# 修复 acme.sh 目录权限
chmod 700 ~/.acme.sh/

3. 续签失败

1
2
3
4
5
6
7
8
# 强制续签
acme.sh --renew -d mobufan.eu.org --force

# 调试模式续签
acme.sh --renew -d mobufan.eu.org --debug

# 检查日志
tail -f ~/.acme.sh/acme.sh.log

📊 监控和日志

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 查看 acme.sh 日志
tail -f ~/.acme.sh/acme.sh.log

# 查看证书状态
acme.sh --list

# 监控证书过期
openssl x509 -in /etc/nginx/ssl/cert.pem -noout -dates

# 设置监控告警
#!/bin/bash
EXPIRY_DAYS=$(openssl x509 -in /etc/nginx/ssl/cert.pem -checkend 864000 | grep -c "will expire")
if [ $EXPIRY_DAYS -eq 1 ]; then
echo "证书即将过期" | mail -s "证书告警" admin@example.com
fi

💡 最佳实践

🛡️ 安全建议

1
2
3
4
5
6
7
8
9
10
11
12
# 使用 ECC 证书(更安全更高效)
acme.sh --issue --dns dns_cf -d mobufan.eu.org --keylength ec-256

# 定期轮换 API Token
# 每 3-6 个月更新一次 Cloudflare API Token

# 备份证书和配置
sudo tar -czvf /backup/ssl-certs-$(date +%Y%m%d).tar.gz /etc/nginx/ssl/ ~/.acme.sh/

# 设置文件权限
sudo find /etc/nginx/ssl -type f -exec chmod 644 {} \;
sudo find /etc/nginx/ssl -type f -name "*.pem" -exec chmod 600 {} \;

📈 性能优化

1
2
3
4
5
6
7
8
# 使用 OCSP Stapling
sudo openssl ocsp -noverify \
-issuer /etc/nginx/ssl/chain.pem \
-cert /etc/nginx/ssl/cert.pem \
-url http://ocsp.int-x3.letsencrypt.org

# 生成 DH 参数
sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048

🔄 自动化脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
# auto-renew-cert.sh

DOMAIN="mobufan.eu.org"
LOG_FILE="/var/log/acme-renew.log"

echo "$(date): 开始证书续签检查" >> $LOG_FILE

# 检查证书有效期
EXPIRY_DAYS=$(acme.sh --list | grep "$DOMAIN" | awk '{print $6}')
if [ -z "$EXPIRY_DAYS" ] || [ "$EXPIRY_DAYS" -lt 5 ]; then
echo "证书即将过期,执行续签..." >> $LOG_FILE
acme.sh --renew -d $DOMAIN --force
echo "证书续签完成" >> $LOG_FILE
else
echo "证书有效期剩余 ${EXPIRY_DAYS} 天,无需续签" >> $LOG_FILE
fi

📝 Docker 使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Docker 方式使用 acme.sh
docker run --rm -it \
-v "/etc/ssl/acme":/acme.sh \
-e "CF_Token=your_token_here" \
-e "CF_Zone_ID=your_zone_id" \
neilpang/acme.sh \
--issue -d mobufan.eu.org --dns dns_cf

# 使用代理
docker run --rm -it \
-v "/etc/ssl/acme":/acme.sh \
-e "CF_Token=your_token_here" \
-e "http_proxy=http://proxy:1080" \
-e "https_proxy=http://proxy:1080" \
neilpang/acme.sh \
--issue -d mobufan.eu.org --dns dns_cf --debug

🎯 提示: 建议在生产环境部署前充分测试所有配置。定期检查证书状态和日志,确保自动化流程正常运行。

📚 扩展资源:

🔧 紧急恢复:

1
2
3
4
5
6
7
8
9
10
11
# 证书续签失败时手动处理
acme.sh --renew -d mobufan.eu.org --force --debug

# 恢复备份证书
sudo tar -xzvf /backup/ssl-certs-20231201.tar.gz -C /

# 重新安装证书
acme.sh --install-cert -d mobufan.eu.org \
--key-file /etc/nginx/ssl/key.pem \
--fullchain-file /etc/nginx/ssl/cert.pem \
--reloadcmd "systemctl reload nginx"