申请免费的TLS证书

背景

特别想让自己的博客支持https,奈何没有空闲搞TLS证书.
闲下来看到acme.sh项目,操作的确非常简单,于是申请一下.

Let’s Encrypt

一个非盈利机构,致力于为用户提供免费的TLS证书,并且也收到了各种大公司的捐赠.

ACME协议

Automatic Certificate Management Environment
自动证书管理环境.

由互联网安全研究小组为 Let’s Encrypt 专门开发.并于2019年3月作为互联网标准RFC8555发布.
目标是让证书的申请,更新,维护变得自动化.
开发以来协议发生过非常多的变更.目前也有更多的CA相继采用.

只要实现了该协议,任何软件都能顺利向Let’s Encrypt申请证书.

  • certbot 官方的工具,但文档不友好,解释也不充分
  • acme.sh 文档相当丰富

acme.sh

介绍

  1. 也实现了ACME协议,因此能够申请证书.
  2. 会创建 ~/.acme.sh 文件夹,并将几乎所有操作都限定在该文件夹内,不影响外部的配置.
    即使申请过程报错也没有心理负担.
  3. 文件夹结构中包含一些配置文件,环境变量等,极大减少了用户申请或更新证书时所需要输入的内容.
    即使有不明白的地方,也能够搜索到相关文件.
  4. 最近被第三方公司买下,更换了默认的CA机构,目前尝试该机构时发现常常Timeout.
    不过依然可以设置为Let’s Encrypt.

安装

1
curl https://get.acme.sh | sh -s [email protected]

注意该邮箱会被用在证书申请时,需要填好自己的邮箱,
后期更改也可以直接改配置文件,不过由于项目的更新,文件名可能会不同,需要自行处理.

申请

验证方式

目的是为了证明对该地址的所有权

  • 网页验证: 在指定路径下,让CA获取到acme准备的特定页面
  • dns验证: 不了解

申请方式

  • 复用既有服务(nginx,apache等)已经打开的端口

  • 利用 socat 临时开启一个端口,现有服务开在非标准端口时,常常可以使用这种方式

    1
    acme.sh  --issue  -d example.com  --standalone --httpport 88

不使用standalone

使用standalon的确能在第一次申请时申请下来,
但CA向本地验证时,选用的是80端口.
因此除非该网站已经配置域名并且有反向代理,否则总要配置路由器使80->88.
而正常使用时希望80->80.
因此使用其他方式

  1. nginx方式

    1
    acme.sh --issue -d example.com --nginx
    • 容易找不到 nginx 命令,因为 nginx 放在 /usr/sbin
    • 即便找到,也没有执行 nginx 的权限(可以用 sudo chmod u+s /usr/sbin/nginx 解决)
    • 即使有执行 nginx 命令的权限,也会由于没有权限操作nginx的配置文件而报错.
  2. 标准申请方式

    1
    acme.sh --issue -d example.com --webroot /path/to/web/root/

    该方法不需要修改nginx配置文件,能正常申请成功.

返回结果

大量的摘要以及文件名信息

1
2
3
4
[Wed 01 Sep 2021 09:53:03 PM CST] Your cert is in: /home/user/.acme.sh/example.com/example.com.cer
[Wed 01 Sep 2021 09:53:03 PM CST] Your cert key is in: /home/user/.acme.sh/example.com/example.com.key
[Wed 01 Sep 2021 09:53:03 PM CST] The intermediate CA cert is in: /home/user/.acme.sh/example.com/ca.cer
[Wed 01 Sep 2021 09:53:03 PM CST] And the full chain certs is there: /home/user/.acme.sh/example.com/fullchain.cer

配置证书

  1. 依然使用命令将证书放置在想放的位置
    因为 acme.sh 认为内部文件结构会变动,不方便自动更新

    1
    2
    3
    4
    acme.sh --install-cert -d example.com \
    --key-file /path/to/keyfile/in/nginx/example.com.key \
    --fullchain-file /path/to/fullchain/nginx/example.com.fullchain.cer \
    --reloadcmd "sudo nginx -s reload" # 如果平常就用sudo操作nginx的话

    如果因为某些原因(在docker内使用nginx,且该container有依赖问题重启不容易等)需要手动重启nginx,
    去掉 reloadcmc 选项即可.

  2. 配置nginx

可能的问题

默认CA出现Timeout

将默认CA替换为Let’s Encrypt

1
acme.sh --set-default-ca  --server  letsencrypt

socat没有绑定端口的权限,即使该端口没有被占用

赋予权限即可

1
sudo setcap 'cap_net_bind_service=+ep' socat

参考

  1. letsencrypt官网
  2. ACME解释
  3. acme.sh官方文档
  4. socat权限问题