美文网首页证书
acme 免费证书申请

acme 免费证书申请

作者: thepoy | 来源:发表于2023-02-21 14:28 被阅读0次

acme.sh 实现了 acme 协议, 可以从 letsencrypt 生成免费的证书.

主要步骤:

  1. 安装 acme.sh
  2. 生成证书
  3. copy 证书到 nginx/apache 或者其他服务
  4. 更新证书
  5. 更新 acme.sh
  6. 出错怎么办, 如何调试

下面详细介绍.

1. 安装 acme.sh

现在申请 letsencrypt 需要填写一个邮箱用来注册,但不需要验证,填一个你常用的邮箱即可,比如example@xxx.com

安装很简单,一行命令:

curl https://get.acme.sh | sh -s email=example@xxx.com

普通用户和 root 用户都可以安装使用。

安装过程进行了以下几步:

  • 将 acme.sh 安装到 ~/.acme.sh/中。
  • 自动为你创建 cronjob,每天 0:00 点自动检测所有的证书,如果快过期了,需要更新,则会自动更新证书。

虽然脚本说明里有写会自动创建一个 alias,但实操下来没有创建,所以需要手动创建一个 alias 到当前 shell 中:

  • bash: echo 'alias acme.sh=~/.acme.sh/acme.sh' >> ~/.bashrc
  • zsh: echo 'alias acme.sh=~/.acme.sh/acme.sh' >> ~/.zshrc
  • fish: echo 'alias acme.sh '~/.acme.sh/acme.sh'' >> ~/.config/fish/config.fish

安装过程不会污染已有的系统任何功能和文件,所有的修改都限制在安装目录中:~/.acme.sh/

2. 生成证书

acme.sh 实现了 acme 协议支持的所有验证协议。一般有两种方式验证:http 和 dns 验证。

2.1 http 方式(不推荐,但是简单)

此方式需要在你的网站根目录下放置一个文件,来验证你的域名所有权,完成验证,然后就可以生成证书了。

以下代码假设域名为mydomain.com

acme.sh --issue -d mydomain.com -d www.mydomain.com --webroot /home/wwwroot/mydomain.com/

只需要指定域名,并指定域名所在的网站根目录。acme.sh 会全自动的生成验证文件,并放到网站的根目录,然后自动完成验证,最后会聪明的删除验证文件,整个过程没有任何副作用。

如果你用的 apache 服务器,acme.sh 还可以智能的从 apache 的配置中自动完成验证,你不需要指定网站根目录:

acme.sh --issue -d mydomain.com --apache

如果你用的 nginx 服务器,或者反代,acme.sh 还可以智能的从 nginx 的配置中自动完成验证,你不需要指定网站根目录:

acme.sh --issue -d mydomain.com --nginx

:warning:无论是 apache 还是 nginx 模式,acme.sh在完成验证之后,会恢复到之前的状态,都不会私自更改你本身的配置。好处是你不用担心配置被搞坏,也有一个缺点,你需要自己配置 ssl 的配置,否则只能成功生成证书,你的网站还是无法访问https。但是为了安全,你还是自己手动改配置吧。

如果你还没有运行任何 web 服务,80 端口是空闲的,那么 acme.sh 还能假装自己是一个webserver,临时听在80 端口,完成验证:

acme.sh --issue -d mydomain.com --standalone

2.2 DNS 方式

这种方式的好处是,你不需要任何服务器,不需要任何公网 ip,只需要 dns 的解析记录即可完成验证。坏处是,如果不同时配置 Automatic DNS API,使用这种方式 acme.sh 将无法自动更新证书,每次都需要手动再次重新解析验证域名所有权。

此处采用的是阿里云 DNS 解析服务,其他服务商可以参考。

首先,创建一个阿里云 RAM 用户:RAM 访问控制 (aliyun.com)

capture_20230222135420606

起一个名字,选中OpenAPI 调用访问

image-20230222135835565

创建成功后跳转的页面里有两个字段AccessKey IDAccessKey Secret需要保存下来:

屏幕截图_20230222_140757

将这两个字段添加到环境变量:

# bash/zsh
export Ali_Key <AccessKey ID>
export Ali_Secret <AccessKey Secret>
# fish
set -x Ali_Key <AccessKey ID>
set -x Ali_Secret <AccessKey Secret>

上面的环境变量在接下来的申请命令中会保存到~/.acme.sh/account.conf中。

点击上图中的添加权限按钮,给用户授权:

屏幕截图_20230222_135948

搜索 dns 权限,添加云解析 DNS 权限,点确定即可:

屏幕截图_20230222_140300

至此阿里云的 DNS API 管理就配置完成。

接下来只需要一行命令就可以把证书申请下来了:

acme.sh --issue --dns dns_ali -d mydomain.com

申请日志:

[Wednesday, February 22, 2023 PM01:31:25 HKT] Using CA: https://acme.zerossl.com/v2/DV90
[Wednesday, February 22, 2023 PM01:31:25 HKT] Single domain='mydomain.com'
[Wednesday, February 22, 2023 PM01:31:25 HKT] Getting domain auth token for each domain
[Wednesday, February 22, 2023 PM01:31:33 HKT] Getting webroot for domain='mydomain.com'
[Wednesday, February 22, 2023 PM01:31:33 HKT] Adding txt value: PGxt8rb5DGqnU3kq8B4j_0-L-7mftfcQqKrMb-IDIBU for domain:  _acme-challenge.mydomain.com
[Wednesday, February 22, 2023 PM01:31:40 HKT] The txt record is added: Success.
[Wednesday, February 22, 2023 PM01:31:40 HKT] Let's check each DNS record now. Sleep 20 seconds first.
[Wednesday, February 22, 2023 PM01:32:01 HKT] You can use '--dnssleep' to disable public dns checks.
[Wednesday, February 22, 2023 PM01:32:01 HKT] See: https://github.com/acmesh-official/acme.sh/wiki/dnscheck
[Wednesday, February 22, 2023 PM01:32:01 HKT] Checking mydomain.com for _acme-challenge.mydomain.com
[Wednesday, February 22, 2023 PM01:32:02 HKT] Domain mydomain.com '_acme-challenge.mydomain.com' success.
[Wednesday, February 22, 2023 PM01:32:02 HKT] All success, let's return
[Wednesday, February 22, 2023 PM01:32:02 HKT] Verifying: mydomain.com
[Wednesday, February 22, 2023 PM01:32:05 HKT] Processing, The CA is processing your order, please just wait. (1/30)
[Wednesday, February 22, 2023 PM01:32:11 HKT] Success
[Wednesday, February 22, 2023 PM01:32:11 HKT] Removing DNS records.
[Wednesday, February 22, 2023 PM01:32:11 HKT] Removing txt: PGxt8rb5DGqnU3kq8B4j_0-L-7mftfcQqKrMb-IDIBU for domain: _acme-challenge.mydomain.com
[Wednesday, February 22, 2023 PM01:32:19 HKT] Removed: Success
[Wednesday, February 22, 2023 PM01:32:19 HKT] Verify finished, start to sign.
[Wednesday, February 22, 2023 PM01:32:19 HKT] Lets finalize the order.
[Wednesday, February 22, 2023 PM01:32:19 HKT] Le_OrderFinalize='https://acme.zerossl.com/v2/DV90/order/juR2CPn0l-4Ye89H4bk5nA/finalize'
[Wednesday, February 22, 2023 PM01:32:22 HKT] Order status is processing, lets sleep and retry.
[Wednesday, February 22, 2023 PM01:32:22 HKT] Retry after: 15
[Wednesday, February 22, 2023 PM01:32:38 HKT] Polling order status: https://acme.zerossl.com/v2/DV90/order/juR2CPn0l-4Ye89H4bk5nA
[Wednesday, February 22, 2023 PM01:32:41 HKT] Downloading cert.
[Wednesday, February 22, 2023 PM01:32:41 HKT] Le_LinkCert='https://acme.zerossl.com/v2/DV90/cert/HhyIPG8YquZXqrqVSiWGlg'[Wednesday, February 22, 2023 PM01:32:43 HKT] Cert success.
-----BEGIN CERTIFICATE-----
MIID/DCCA4OgAwIBAgIRAJa3bPLyv3v1hOT0Ac7EPVYwCgYIKoZIzj0EAwMwSzEL
...
e6Q864KuMKPlWN9tocECMHdGhAlvwS5JUKsM36qFtNKG6u0hmivMi3ag4k4AWbmc
2k+mxNL86dlph8ENgqJrng==
-----END CERTIFICATE-----
[Wednesday, February 22, 2023 PM01:32:43 HKT] Your cert is in: /home/xxx/.acme.sh/mydomain.com_ecc/mydomain.com.cer[Wednesday, February 22, 2023 PM01:32:43 HKT] Your cert key is in: /home/xxx/.acme.sh/mydomain.com_ecc/mydomain.com.key
[Wednesday, February 22, 2023 PM01:32:43 HKT] The intermediate CA cert is in: /home/xxx/.acme.sh/mydomain.com_ecc/ca.cer
[Wednesday, February 22, 2023 PM01:32:43 HKT] And the full chain certs is there: /home/xxx/.acme.sh/mydomain.com_ecc/fullchain.cer

证书会保存到~/.acme.sh/<域名>目录中。

3. copy/安装 证书

前面证书生成以后,接下来需要把证书 copy 到真正需要用它的地方。

:warning: 默认生成的证书都放在安装目录下:~/.acme.sh/,请不要直接使用此目录下的文件,例如:不要直接让 nginx/apache 的配置文件使用这下面的文件。这里面的文件都是内部使用,而且目录结构可能会变化。

正确的使用方法是使用 --install-cert 命令,并指定目标位置,然后证书文件会被copy到相应的位置,例如:

Apache example:

acme.sh --install-cert -d example.com \
--cert-file      /path/to/certfile/in/apache/cert.pem  \
--key-file       /path/to/keyfile/in/apache/key.pem  \
--fullchain-file /path/to/fullchain/certfile/apache/fullchain.pem \
--reloadcmd     "service apache2 force-reload"

Nginx example:

acme.sh --install-cert -d example.com \
--key-file       /path/to/keyfile/in/nginx/key.pem  \
--fullchain-file /path/to/fullchain/nginx/cert.pem \
--reloadcmd     "service nginx force-reload"

(一个小提醒,这里用的是 service nginx force-reload,不是 service nginx reload,据测试,reload 并不会重新加载证书,所以用的 force-reload)

Nginx 的配置 ssl_certificate 使用 /etc/nginx/ssl/fullchain.cer ,而非 /etc/nginx/ssl/<domain>.cer ,否则 SSL Labs 的测试会报 Chain issues Incomplete 错误。

--install-cert命令可以携带很多参数,来指定目标文件,并且可以指定 reloadcmd,当证书更新以后,reloadcmd 会被自动调用,让服务器生效。

值得注意的是,这里指定的所有参数都会被自动记录下来,并在将来证书自动更新以后,被再次自动调用。

4. 查看已安装证书信息

$ acme.sh --info -d example.com
DOMAIN_CONF=/root/.acme.sh/example.com/example.com.conf
Le_Domain=example.com
Le_Alt=no
Le_Webroot=dns_ali
Le_PreHook=
Le_PostHook=
Le_RenewHook=
Le_API=https://acme-v02.api.letsencrypt.org/directory
Le_Keylength=
Le_OrderFinalize=https://acme-v02.api.letsencrypt.org/acme/finalize/23xxxx150/781xxxx4310
Le_LinkOrder=https://acme-v02.api.letsencrypt.org/acme/order/233xxx150/781xxxx4310
Le_LinkCert=https://acme-v02.api.letsencrypt.org/acme/cert/04cbd28xxxxxx349ecaea8d07
Le_CertCreateTime=1649358725
Le_CertCreateTimeStr=Thu Apr  7 19:12:05 UTC 2022
Le_NextRenewTimeStr=Mon Jun  6 19:12:05 UTC 2022
Le_NextRenewTime=1654456325
Le_RealCertPath=
Le_RealCACertPath=
Le_RealKeyPath=/etc/acme/example.com/privkey.pem
Le_ReloadCmd=service nginx force-reload
Le_RealFullChainPath=/etc/acme/example.com/chain.pem

5. 更新证书

目前证书在 60 天以后会自动更新,你无需任何操作。今后有可能会缩短这个时间,不过都是自动的,你不用关心。

请确保 cronjob 正确安装,看起来是类似这样的:

$ crontab  -l
56 * * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null

6. 更新 acme.sh

目前由于 acme 协议和 letsencrypt CA 都在频繁的更新,因此 acme.sh 也经常更新以保持同步。

升级 acme.sh 到最新版:

acme.sh --upgrade

如果你不想手动升级,可以开启自动升级:

acme.sh --upgrade --auto-upgrade

之后,acme.sh 就会自动保持更新了。

你也可以随时关闭自动更新:

acme.sh --upgrade --auto-upgrade  0

相关文章

网友评论

    本文标题:acme 免费证书申请

    本文链接:https://www.haomeiwen.com/subject/lxankdtx.html