使用 ACME 申请证书
网站想要升级到 HTTPS,首先得申请下发个安全证书,现在下发证书很简单,方式也很多,很多域名提供商都提供免费证书申请。但是,很多证书都是有时间限制(3个月或者1年),时间到期就需要手动重新,手续麻烦而且还会忘记续期,如果想一劳永逸可以用工具自动生成证书并且自动续租。续租工具和方式也很多,本文将讲解用 ACME 实现证书申请和证书自动续期。
# 安装 ACME
apt install socat
curl https://get.acme.sh | sh
2
安装程序会自动做以下操作:
- 自动把 acme.sh 安装到你的 home 的
.acme.sh
目录下,即~/.acme.sh/
- 自动创建一个 bash 的 alias,方便你的使用:
alias acme.sh=~/.acme.sh/acme.sh
- 自动为你创建 cronjob,每天 0:00 点自动检测所有的证书,如果快过期了,需要更新,则会自动更新证书。
# 更改默认证书
acme.sh --set-default-ca --server letsencrypt
acme 被 ZeroSSL 收购,其默认的证书方式为 ZeroSSL,但此证书生成时会携带邮箱,因此更换为 letsencrypt。
当然,也可以在生成证书时加一个--server
参数来决定生成什么证书
--server letsencrypt
# 生成证书
使用acme.sh --issue
命令生成证书,但生成证书的同时会进行域名的所有权的验证。 acme.sh 有两种方式验证:HTTP 和 DNS 验证。
注意:如果需要生成泛域名(
*.example.com
)的证书,不能使用 HTTP 认证域名,需要改用 DNS 认证的方式。
# HTTP 验证方式
HTTP 方式需要通过
- 配置网站根目录,命令参数为(
--webroot /home/wwwroot/example.com/
) - 或关联服务器的 nginx 服务,命令参数为(
--nginx
) - 或关联服务器的 apache 服务,命令参数为(
--apache
) - 或自建虚拟 webserver(服务器没有占用 80 端口),命令参数为(
--standalone
)
来验证你的域名所有权来完成验证。
本服务器已搭建 nginx 服务,因此关联即可
acme.sh --issue -d example.com -d *.example.com --nginx
参数解析:
--issue
请求证书的签发参数-d
定义需要生成证书的域名,如有多个域名需使用多次
如果觉得麻烦可以使用第一种配置网站根目录。或者停止占用 80 端口的服务,然后通过添加--standalone
参数,等生成证书后再启动原来的服务。如果服务器已有 80 端口的服务,不建议使用自建虚拟 webserver,此方式续租时略麻烦需要改造。
# DNS 验证方式
需要在域名上添加一条 txt 解析记录,验证域名所有权
DNS 方式的真正强大之处在于可以使用域名解析商提供的 API 自动添加 txt 记录完成验证.
在域名提供商中,生成你的 API 令牌
引入 API key,以 Cloudflare 为例
export CF_Key="1234567890" export CF_Email="[email protected]"
1
2生成证书
# 申请 ECC 证书 acme.sh --issue --dns dns_cf -d example.com -d *.example.com # 申请 RSA 证书 acme.sh --issue --dns dns_cf -d example.com -d *.example.com -k 2048
1
2
3
4
5--dns
的配置值也是根据域名提供商来决定,dns_cf 表示 cloudflare。不同提供商,API 参数值各不同,可参考下面的表格
服务商名称 | 服务商简称 | 所需API参数 | 获取API参数地址 |
---|---|---|---|
cloudxns | cx | export CX_Key="123456" export CX_Secret="abcdef" | 点击访问 (opens new window) |
dnspod.cn | dp | export DP_Id="123456" export DP_Key="abcdef" | 点击访问 (opens new window) |
aliyun | ali | export Ali_Key="123456" export Ali_Secret="abcdef" | 点击访问 (opens new window) |
cloudflare | cf | export CF_Key="123456" export CF_Email="[email protected]" | 点击访问 (opens new window) |
linode | linode | export LINODE_API_KEY="123456" | 点击访问 (opens new window) |
he | he | export HE_Username="username" export HE_Password="password" | he (opens new window) 的用户名密码 |
digitalocean | dgon | export DO_API_KEY="123456" | 点击访问 (opens new window) |
namesilo | namesilo | export Namesilo_Key="123456" | 点击访问 (opens new window) |
aws | aws | export AWS_ACCESS_KEY_ID=123456 export AWS_SECRET_ACCESS_KEY=abcdef | 点击访问 (opens new window) |
namecom | namecom | export Namecom_Username="username" export Namecom_Token="123456" | 点击访问 (opens new window) |
freedns | freedns | export FREEDNS_User="username" export FREEDNS_Password="password" | freedns (opens new window) 的用户名密码 |
godaddy | gd | export GD_Key="123456" export GD_Secret="abcdef" | 点击访问 (opens new window) |
yandex | yandex | export PDD_Token="abcdef" | 点击访问 (opens new window) |
# 安装证书
默认生成的证书都放在安装目录下: ~/.acme.sh/
,但是不要在 web 服务器中直接引用目录下的证书文件,也不要手动来拷贝证书文件到具体的 web 服务器中,手动拷贝会导致之后更新证书流程不能完全自动。
正确方式是使用 acme.sh 的安装证书命令,acme.sh 自动拷贝证书文件到具体目录中,拷贝命令会被记录下来,之后自动更新证书流程也会执行此拷贝步骤,从而实现更新证书流程的完全自动化。
格式例子如下:
acme.sh --install-cert -d example.com -d *.example.com \
--key-file /etc/nginx/cert_file/key.pem \
--fullchain-file /etc/nginx/cert_file/fullchain.pem \
--reloadcmd "service nginx force-reload"
2
3
4
根据 web 服务器需要的文件按需引入对应的参数,reloadcmd 定义证书更新后重启对应的 web 服务命令。
# 更新证书
目前证书在 60 天以后会自动更新,你无需任何操作,因为在 acme.sh 安装时,已经把相关的自动更新程序写入到 crontab 中,如果想要查看,可以通过以下命令:
crontab -l
输出内容包含一个自动更新程序,大致内容如下:
56 * * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
# 查看证书
acme.sh --list
# 吊销证书
acme.sh --remove -d example.com *.example.com
或者手动在~/.acme.sh/
目录下删除对应的域名目录,如~/.acme.sh/example.com
。
# 升级 ACME
acme.sh --upgrade