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

主要步骤:

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

下面详细介绍.

1. 安装 acme.sh

安装很简单, 一个命令:

curl  https://get.acme.sh | sh

或者

wget -O -  https://get.acme.sh | sh

普通用户和 root 用户都可以安装使用. 安装过程进行了以下几步:

1) 把 acme.sh 安装到你的 home 目录下:

~/.acme.sh/

并创建 一个 bash 的 alias, 方便你的使用: alias acme.sh=~/.acme.sh/acme.sh

2). 自动为你创建 cronjob, 每天 0:00 点自动检测所有的证书, 如果快过期了, 需要更新, 则会自动更新证书.

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

2. 生成证书

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

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

以 Nginx 配置为例 (推荐)

server {
  listen 80;

  server_name mydomain.com mydomain.com;
  access_log /data/wwwlogs/mydomain.com_nginx.log combined;
  index index.html index.htm index.php;
  root /data/wwwroot/domain.com;

  # 加上以下2条配置
  location ^~ /.well-known/acme-challenge/ {
	default_type "text/plain";
	root     /data/wwwroot/domain.com; # 要和你的网站根目录一致, 等一下有用到
  }

  location = /.well-known/acme-challenge/ {
	return 404;
  }

  # 其他配置
}

然后重启或重新加载 Nginx

service nginx reload

接下来生成证书

acme.sh  --issue  -d mydomain.com -d www.mydomain.com  --webroot  /data/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

报错如下

[Wed Feb 27 13:11:04 CST 2019] Single domain='<domain>'
[Wed Feb 27 13:11:04 CST 2019] Getting domain auth token for each domain
[Wed Feb 27 13:11:04 CST 2019] Getting webroot for domain='<domain>'
[Wed Feb 27 13:11:04 CST 2019] Getting new-authz for domain='<domain>'
[Wed Feb 27 13:11:06 CST 2019] The new-authz request is ok.
[Wed Feb 27 13:11:06 CST 2019] Verifying: bbs.shipingmi.net
[Wed Feb 27 13:11:06 CST 2019] Nginx mode for domain:bbs.shipingmi.net
[Wed Feb 27 13:11:06 CST 2019] '' doesn't exist.
[Wed Feb 27 13:11:06 CST 2019] Please add '--debug' or '--log' to check more details.
[Wed Feb 27 13:11:06 CST 2019] See: https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh

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

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

# 这种方法我没试过, 不过不启动 Apache or Nginx 的情况下还是挺好的
acme.sh  --issue -d mydomain.com   --standalone

2. dns 方式, 在域名上添加一条 txt 解析记录, 验证域名所有权.

本文不解释 dns 方式, 更详细的 api 用法:
https://github.com/Neilpang/acme.sh/blob/master/dnsapi/README.md

3. copy/安装 证书

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

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

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

acme.sh  --installcert  -d  <domain>.com   \
        --key-file   /etc/nginx/ssl/<domain>.key \
        --fullchain-file /etc/nginx/ssl/fullchain.cer \
        --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 错误。

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

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

4. 更新证书

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

5. 更新 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

6. 出错怎么办:

如果出错, 请添加 debug log:

acme.sh  --issue  .....  --debug 

或者

acme.sh  --issue  .....  --debug  2

请参考: https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh

最后, 本文并非完全的使用说明, 还有很多高级的功能, 更高级的用法请参看其他 wiki 页面.

https://github.com/Neilpang/acme.sh/wiki