acme.sh签发SSL证书简单记录

简单介绍如何使用acme.sh使用http模式或dns模式签发并安装证书,实现服务器的https访问

# 什么是acme.sh

  • acme.sh是一个开源项目,github地址为链接
  • acme.sh 实现了 acme 协议, 可以从 letsencrypt 生成免费的SSL证书。
  • acme.sh生成的证书拥有自动更新的功能,配置完成后可一直自动运行,保持证书有效性

# 为什么写这个文章

每次开vps需要申请域名https证书时,都忘记如何使用acme.sh。写这个文章用来记录一下自己的理解。acme.sh经常更新,本文可能过时,建议有条件的还是按照官方的文档进行操作

# 准备

本文章中使用acme.sh的前提:

  1. 你拥有一台暴露在公网的虚拟或实体的基于linux服务器
  2. 服务器上已经有nginx等提供web服务
  3. 你有一个域名
  4. 你想把这个域名配置到这个服务器的SSL证书中

需要进行的步骤:

  1. 安装acme.sh
  2. 签发SSL证书(有多种方式)
  3. 安装证书
  4. 配置NGINX

# 安装acme.sh

  1. 部分linux系统的普通用户执行acme.sh容易出现权限错误,建议切换到root用户
  2. 执行如下命令安装acme.sh:(email中输入任意邮箱,不会有校验信息)
1
curl https://get.acme.sh | sh -s email=[email protected]
  1. 配置shell alias。将acme.sh加入shell命令中
1
source ~/.bashrc

acme.sh 安装程序会:

  1. acme.sh程序会被安装到home路径下~/.acme.sh/。安装过程不会污染已有的系统任何功能和文件, 所有的修改都限制在安装目录中
  2. ~/.bashrc中创建alias acme.sh=~/.acme.sh/acme.sh
  3. 还会创建一个cronjob。每天0:00自动检测并更新即将过期的证书

# 使用acme.sh签发SSL证书

acme.sh可以用多种方式签发SSL证书。

# 方式一:http模式(不推荐)

首先假设你的服务器上配置了nginx或apache等提供web服务软件,并在nginx中将/path/to/example.com配置作为网站html的根目录

那么,可以使用如下命令生成SSL证书

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

如果使用的是nginx或apache,那么也可以用如下等价命令。acme.sh会自动读取nginx或apache的配置,找到对应的网站html根目录,进行后续的配置流程

1
2
acme.sh --issue -d example.com --nginx
acme.sh --issue -d example.com --apache

签发时的大致流程如下:

  1. 在指定的根目录生成一个验证文件
  2. acme.sh请求SSL证书服务器验证
  3. 证书服务器通过互联网访问http://example.com/验证文件中的文件
  4. 证书服务器确认acme.sh的调用方(就是执行程序的你)拥有example.com这个域名
  5. 证书服务器下发证书给acme.sh
  6. acme.sh将证书保存到本地
  7. acme.sh将验证文件删除,恢复原样

缺点:

  1. 使用前必须先安装配置nginx或apache,并在80端口提供web服务。如果你目前服务器中的服务不是这个结构,可能并不适用
  2. 生成的证书后,必须手动修改nginx的443端口配置,将证书加入。如果需要自动化配置则需要准备一份用于认证的80端口配置文件和最终用于生产的443端口配置文件,对于自动化流程不够友好

# 方式二:DNS API方式(推荐)

acme.sh 真正强大的dns模式的优势是可以使用域名解析商提供的api自动添加记录完成认证。acme.sh 目前支持 cloudflare, dnspod, cloudxns, godaddy 以及 ovh 等数十种解析商的自动集成。

以Cloudflare 为例。首先到cloudflare官网中的api控制台链接中创建一个Cloudflare API key(具体流程可以自行搜索)。然后来到acme.sh的安装文件夹,修改~/.acme.sh/account.conf,加入

1
2
export CF_Token="your api key"
export CF_Account_ID="xxxxxxxxxxxxx"

随后执行如下命令,即可完成证书签发

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

签发时的大致流程:通过cloudflare的api查询该域名的所有权,验证成功后直接签发证书

# 其他方式

acme.sh脚本还支持其他的验证方式。但不太适用于个人服务器用户。可以自行访问官方github项目文档中查找

# 安装证书

获取证书后,我们需要在网站的web服务端提供的http中带上证书,才能成为真正的https服务。

这里以nginx为例。假设我们想将证书放在/etc/nginx/ssl中,并让nginx读取这个路径。首先,我们就需要用acme.sh将证书安装到路径/etc/nginx/ssl

1
2
3
acme.sh --install-cert -d example.com \
--key-file       /etc/nginx/ssl/example.com.key  \
--fullchain-file /etc/nginx/ssl/example.com.cer \

接着,我们可以将nginx的443端口配置设为

1
2
3
4
5
6
7
8
server {
    listen  443 ssl http2 default_server;
    server_name  example.com;
    ssl_certificate       /etc/nginx/ssl/example.com.cer;
    ssl_certificate_key   /etc/nginx/ssl/example.com.key;

    其他配置略
}

然后重启nginx

1
nginx -s reload

注意:不能使用cp命令直接将证书文件复制过去,而是需要用acme.sh的安装命令。这样才能借助acme.sh在证书过期后自动续签

# 查看证书信息

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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

# 验证

完成nginx的配置后,理论上https的配置就完成了。我们可以直接用浏览器访问https://example.com查看工作是否正常。如果浏览器没有提示证书不安全等警告信息,那么就可以祝贺你,配置成功了!

# 后记

当然,本文仅介绍最基本的证书申请与安装功能。acme.sh还有许多其他功能,可以访问github项目

使用 Hugo 构建
主题 StackJimmy 设计