需求:
- 一个域名
- 一个服务器(有命令行权限)
完整手册详见官方手册
ACME.sh: Starting from August-1st 2021, acme.sh will release v3.0, in which the default CA will use ZeroSSL instead.
1. 下载ACME.sh
本文选择使用 acme.sh来获取证书。它是一个一个纯粹用Shell语言编写的ACME协议客户端。支持ACME v1和ACME v2 支持ACME v2通配符证书。而且是纯粹用Shell编写的,不依赖于python或官方的Let's Encrypt客户端。并且只需一个脚本即可自动颁发,续订和安装证书。 不需要root/sudoer访问权限。
使用以下命令来安装ACME.sh,并且普通用户和 root 用户都可以安装使用
curl https://get.acme.sh | sh -s email=替换为你的电子邮箱
执行这条命令后将会把 acme.sh 安装到你的 home 目录下 ~/.acme.sh/。并且会自动创建 crontab job每天定时检测所有证书,在快过期的时候自动续订。
如果你想要更多的安装方法,也可以参考 官方安装手册。
2. 生成HTTPS证书
acme.sh 支持多种验证方法。
a. HTTP验证方法
这种方法通过在你的网站目录下放置一个文件来通过验证,使用以下命令。
acme.sh --issue -d mydomain.com -d www.mydomain.com --webroot /home/wwwroot/mydomain.com/
你需要替换上文的域名为你的域名,上文--webroot后的地址为你的网站地址。acme.sh会自动放置一个文件,验证完成后删除文件,不留下一点痕迹。
如果你用的 apache服务器, acme.sh 还可以智能的从 apache的配置中自动完成验证, 你不需要指定网站根目录:
acme.sh --issue -d mydomain.com --apache
如果你用的 nginx服务器, acme.sh 还可以智能的从 nginx的配置中自动完成验证, 你不需要指定网站根目录:
acme.sh --issue -d mydomain.com --nginx
如果你还没有运行任何 web 服务, 80 端口是空闲的, 那么 acme.sh 还能假装自己是一个webserver, 临时听在80 端口, 完成验证:
acme.sh --issue -d mydomain.com --standalone
b.DNS验证方法
首先需要确定你的域名注册商或域名托管商。如果出现在下述列表代表可以使用域名商的API实现自动验证。
- Cloudflare
- DNSPod.cn
- CloudXNS.com
- GoDaddy.com
- PowerDNS
- OVH/kimsufi/soyoustart/runabove
- LuaDNS
- DNSMadeEasy
- Amazon Route53
- Aliyun
- Linode domain
- FreeDNS
更详细的列表请参见 官方手册。
这里只介绍 Cloudflare的配置方法,其他的服务商的配置方法都是大同小异的。
方法A
首先你需要获取你的Cloudflare Global API Key。访问上面这个链接,然后在API 密钥选项卡中找到Global API Key,点击后面的查看按钮。然后在Shell中执行以下命令,不要忘记替换以下命令行中的部分参数。
export CF_Key="这里替换为你的Global API Key"
export CF_Email="这里替换为你的Cloudflare账户的电子邮箱"
acme.sh --issue --dns dns_cf -d example.com -d '*.example.com'
CF_Key 和 CF_Email 将保存在 ~/.acme.sh/account.conf中,并在下次需要时重复使用。
方法B
因为某些原因不想使用Global API Key还可以使用Api Token
export CF_Token="替换为TOKEN"
export CF_Account_ID="替换为账户ID"
在
Cloudflare页的随便一个域名的Overview页面的右下角就可以获取到Account ID。
其次你需要获取你的API Tokens 。点击这个链接,然后在API Tokens选项卡中创建你所需要的Token。
注意:令牌当前需要在对指定区域包含Zone.Zone 的读取访问权限和对 Zone.DNS 的写入访问权限。如果指定了IP限制要注意服务器是否有IPV6地址,acme.sh可能会使用IPV6地址访问服务器,如果没有加入白名单可能会导致证书申请失败。
3. 安装证书
证书获取以后你需要安装到指定位置。
acme.sh --install-cert -d example.com \
--cert-file /你想要的证书路径/cert.pem \
--key-file /你想要的证书路径/key.pem \
--fullchain-file /你想要的证书路径/fullchain.pem \
--reloadcmd "systemctl restart httpd"
4. 配置Web服务器
Apache配置文件示例
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite HIGH:3DES:!aNULL:!MD5:!SEED:!IDEA
SSLCertificateFile /你安装的路径/cert.pem
SSLCertificateKeyFile /你安装的路径/key.pem
SSLCertificateChainFile /你安装的路径/fullchain.pem
Nginx 配置文件示例
ssl_session_timeout 5m;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE;
ssl_prefer_server_ciphers on;
ssl_certificate /你安装的路径/fullchain.pem;
ssl_certificate_key /你安装的路径/key.pem;
5. 注意事项
- 你可以使用命令更新acme.sh
acme.sh --upgrade - 证书在60天以后会自动更新, 无需任何操作。更新的原理是在crontab添加一个任务,请不要删除这个任务。
- 如果你没有
acme.sh这个命令,那这个命令文件应该在/root/.acme.sh/acme.sh - acme.sh 开启自动升级
acme.sh --upgrade --auto-upgrade,关闭自动升级acme.sh --upgrade --auto-upgrade 0
6. 常见问题
invalid domain
通常错误是: invalid domain, Error add txt for domain
出现这种问题可以使用debug开关来打开调试输出。例如这条命令
acme.sh --renew -d example.com --debug 2
找到错误输出中的invalid domain。然后向上寻找可能的错误点。例如cloudflare返回的错误信息之类。
如果返回了:
response='{"success":false,"errors":[{"code":9109,"message":"Invalid access token"}],"messages":[],"result":null}'
则代表是 access token出现问题。通常需要检查access token是否正确。
值得注意的是,如果 acme.sh目录下account.conf中的SAVED_CF_Token即使是正确的,也要去域名目录下检查域名的配置文件的CF_Token是否正确。域名配置文件的文件名通常是example.com/example.com.conf。
除了access token设置错误以外,还可能能是开启了IP限制导致的失败。错误输出通常是这样的:
response='{"success":false,"errors":[{"code":9109,"message":"Cannot use the access token from location: xxxxxxxxxxxxxxxxxxxx"}],"messages":[],"result":null}'
修复方法也很简单,只要根据返回的错误信息中的IP去cloudflare设置IP就可以。
对于不同的DNS验证方式,上文提到的选项可能有所不同,需要变通处理。