在AI盛行的时代,一句话就能解决问题,却还要坚持手搓的时候属实不多了。
原本我也是让Agent去VPS做这些事的,注册证书、自动更新,等等,但经过多次下来,发现VPS上的配置被它改的东一块、西一块的,最后就只好手动整理了一下,在此做个记录。
1. 简介
我用到证书的场景,主要是搭配域名一块儿使用,在VPS上暴露了几个服务,想要用https就需要有证书,权威机构颁发的证书动辄就几百几千,本着能省则省的原则,选了免费组织的证书:Let’s Encrypt。申请证书、更新证书,都是免费的,每次有效期90天,所以需要定时刷新证书。
对于这些操作,官方提供了一个工具,叫做:certbot,常见的申请、更新证书操作,通过这个工具都可实现。
2. 颁发流程
这里需要先说下Let’s Encrypt这个CA机构颁发证书的大致流程,这个说明白,后面关于certbot的多个参数就很好理解了。
假设,我需要给example.com这个域名申请证书,把这个请求发给机构之后,机构会返回一个token,之后,机构会访问一个固定URL,来验证我是不是这个域名的所有者:
1 | http://example.com/.well-known/acme-challenge/<token> |
所以,我拿到token之后,需要存到本地,并对外暴露,添加路由映射,比如通过Nginx,使得访问上面这个链接时,可以正确返回token,token是个文件名,文件内容除了包含token,还有一些其他用于验证的数据,机构访问URL,验证通过,则正式签发证书。
本质上,就是需要一个验证的操作:需要验证我是我申请的这个域名的所有者。
访问固定URL来验证是常见的方式,既然有常见的,就会有不太常见的,比如通过DNS验证:向机构申请某个域名的证书,机构会返回用于验证用的信息,在DNS解析中增加一条TXT类型的记录,内容就是这些验证用的信息,然后机构通过解析这条TXT类型的DNS记录,同样可以验证我就是这个域名的所有者,验证通过后,则正式签发证书。
添加TXT记录,一般都通过域名服务商提供的API来完成,比如Cloudflare,这种方式的优点是不受VPS端口限制,适用于无法暴露80端口,或者80端口在提供其他服务的情况。
证书下发到本地之后,要想证书生效,还需要一个操作:安装。
所谓安装证书,其实就是应用证书,对于需要证书的服务,把证书路径配置进去,对于正在使用证书的服务,能重载的就热重载一下,不支持重载的就重启一下,然后就可以了。
验证Authenticator + 安装Installer,就是全部流程。
3. 安装工具
我用的Linux是Debian,安装方式如下,root登录的话不用加sudo,直接跑即可:
1 | $ sudo apt update |
4.证书验证和安装
上面提到了多种证书验证的方式,这里只说其中的第一种,也就是通过80端口访问token文件的方式,而,对于这种方式,certbot提供了多种模式,分别是:
- standalone
- webroot
- nginx
standalone是起一个单独的、临时的Python Web服务器,占用80端口,以供机构访问验证,webroot则是需要借用Nginx服务提供80端口,供机构访问验证,这2种都只是提供验证,不管安装,nginx模式则是在webroot的基础上,还提供安装证书,属于验证、安装一把抓,虽然省心,但是它会动态修改nginx的配置文件,修改端口,这是个很危险的操作,容易产生副作用。
这里我用的都是webroot方式,也是业内较为标准的方式。不使用standalone是因为大多数VPS都安装了Nginx,使用很方便,同时,certbot提供了hook,每次申请、更新证书之后,都会执行hook,在hook中,重启或者重载一下用到证书的服务,也不用每次都手动安装证书。
1 | certbot certonly --webroot -w /var/www/html -d sub.domain.com |
这里需要带着certonly,表示只申请、更新证书,不安装,使用webroot这种不带安装的方式时,就需要带着这个参数,不然就会报错,使用nginx则可以不带。后面的-w就是token文件存放的位置,这个也可以写别的路径,但一般都用这个,最终的存放路径是:
1 | /var/www/html/.well-known/acme-challenge/<token> |
Nginx还需要增加配置,让这个token可访问,80端口如果没用,直接加载default中就可以了:
1 | # /etc/nginx/sites-enabled/default |
证书验证完成并下发后,存储的路径是:
1 | /etc/letsencrypt/live/sub.domain.com/cert.pem |
证书自动更新的配置路径是:
1 | /etc/letsencrypt/renewal/sub.domain.com.conf |
可通过这个命令查看当前所有证书信息:
1 | $ certbot certificates |
5. hooks
在/etc/letsencrypt/renewal-hooks下有3个目录,分别是:pre、deploy和post,分别对应3个回调时机:
- pre:续签前调用
- deploy:续签成功后调用
- post:续签结束后调用,成功、失败都会调用
在deploy下创建文件reload.sh,并增加如下内容:
1 | /etc/letsencrypt/renewal-hooks/deploy/reload.sh |
给hook增加执行权限:
1 | sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload.sh |
这样,当签发成功后,会自动调用reload.sh,完成证书安装。
至此,证书自动更新就算完成了。