锁上私有化部署的最后一道门:证书的集中式管理
序
在之前的文章的末尾,我提到了
同一个域名解析得到不同的证书或许不是最佳实践,集中式的证书管理获取是更好的选择,有机会再说吧。
经过在互联网上寻觅一番后,我找到了certd和certimate。在本地部署尝试后我选择了certd,因为
- certimate的docker支持仍有欠缺
- certd的流程图式部署简洁易懂,在已有TLS证书部署的基础上,几乎不需要看文档,上手就能操作
但是注意:
- certd的免费版本只能提供10条流水线的支持(考虑到我们可以使用泛域名证书,足够了)
梳理
让我们来梳理一下,一个集中式的证书管理程序需要做什么。
- 能够自动签发证书
- 能够将证书下发给主机/CDN
- 能够控制主机载入证书
简单绘制画个图
总体流程
graph LR
A(发起单个流程)-->B[从CA机构签发证书]-->C[将证书推送到主机/CDN]-->D[执行主机命令重载证书]-->E[通知结果]-->F(结束)
为了实现证书的自动续签,我们只需要在每天定时允许这个流程,视历史记录跳过其中的某些步骤。比如第10天的执行发现证书还有80天过期,那么可以跳过从CA机构签发证书
、将证书推送到主机/CDN
、执行主机命令重载证书
这些步骤;在第80天发现证书还有10天过期,那么上述所有步骤都需要执行一遍。
从其中的细节来看:
从CA机构签发证书
我们可以选用Let's Encrypt
免费签发,其中的域名验证可以使用DNS验证的方式。其流程如下:
graph LR
A(发起证书签发流程)-->B[向CA机构发起申请流程]-->C[通过API向DNS服务商发起DNS编辑请求]--等待DNS修改生效-->D[向CA机构请求证书]-->E[保存获取的证书文件]-->F(结束)
将证书推送到主机/CDN和执行主机命令重载证书
将证书推送到主机/CDN
和执行主机命令重载证书
由certd
执行,对于大多数CDN服务商,只需要使用申请到的key即可,无需我们做太多操作。但是对于自行部署的主机,我们需要手动配置这部分操作,其流程可以如下:
graph LR
A(发起主机的证书部署)-->B[ssh连接到目标主机]-->C[传输证书和密钥文件到目标主机]-->D[重载目标主机的相关服务]-->F(结束)
这部分操作是整个流程中需要我们手动配置最多的地方,我们会在下文中详细描述。在整个流程中,我们会尽量保持最小权限原则,避免授予certd服务过高的权限。
让我们从安装开始。
安装
certd提供了完整的Docker支持,我们没有理由不使用它~
我们需要找一台可以连接互联网的服务器部署,因为其采用DNS验证的方式部署,公网IP并不是必要条件。
1 |
|
编辑为以下内容,或者您也可以使用其GitHub中的版本,此文只删减了部分注释和默认配置。
其README中提供的Docker-compose文件有充足的注释,建议按照需求更改
1 |
|
使用
1 |
|
启动即可。
等待容器启动完毕,访问7001
端口即可,其默认账号为admin,密码为123456。
配置 Certd
坦率地说,这部分内容在 Certd 和其文档站中已有完整的教程,此文不再赘述。
哈哈,好吧,我还是踩坑了,第一次没看懂 Cloudflare 的令牌获取流程,如果你也需要用 Cloudflare 可以看看 ↓
Cloudflare 的 Key 获取
这个东西好像确实不那么直观,单击
获取 API 令牌
后,单击创建令牌
,选择最下方的自定义令牌。然后将相关配置按照下图配置:
确保红色框内的配置与图中相同,其他条目视自己情况编辑,默认也可。
配置上传证书到主机
至此,按照 Certd 内自带的教程和文档,我们已经可以完成一条完整的流水线,将证书部署到CDN或者对象存储服务,因为这些服务的具体操作都已有服务商和Certd配置好了,所以一切从简。接下来我们进入本文的重点:配置上传证书到主机
流程梳理
我们需要完成以下要点
- 使用 Certd 将证书推送到目标主机
- 执行目标主机的具体指令,使相关服务重载证书(本文以 Nginx 为例)
在下文中,我们假设Certd所在的服务器为Certd_server
,目标主机服务器为Nginx_server
让我们遵守最小权限原则,开始吧
创建专用于推送证书和重启服务的用户
登录到Nginx_server
创建一个名为cert_push_user
的用户,并授予其重载Nginx服务的权限
1 |
|
在/etc/ssl/
下创建一个nginx
文件夹,之后我们所有的证书文件都会上传到这里
配置文件权限,允许cert_push_user
用户和www-data
组成员(这是 Nginx 进程所属的用户组)访问和管理该目录
确保只有cert_push_user
和www-data
组可以访问目录,而其他用户无法访问
1 |
|
配置证书推送账号的SSH登录
使用 su 命令切换到 cert_push_user
账号
1 |
|
创建一个密钥对,密码可以为空
1 |
|
我们会得到两个文件:cert
和cert.pub
文件,其中cert
为私钥,cert.pub
为公钥,我们需要将公钥写入到该账号的SSH密钥认证文件中。
1 |
|
复制密钥
1 |
|
在确保密钥复制后,cert
和cert.pub
文件可以删除。
配置Certd的主机登录配置
在证书申请任务之后,我们选择上传证书到主机
任务,在下方的主机登录配置
中,单击选择
、添加
,配置Nginx_server
的SSH相关内容
其中用户名
填写我们先前创建的cert_push_user
,填写密钥登陆,粘贴我们刚才从**cert
文件中复制出来的内容**
其他按情况填写即可
配置部署证书到主机
我们需要填写证书保存路径
、私钥保存路径
和最下方的shell脚本命令
对于证书保存路径
、私钥保存路径
,我们需要填写之前创建的证书路径,并加上我们需要给证书的命名,比如我们希望证书推送到主机后的名字为baidu.com.pem
和baidu.com.key
,那么这俩个空可以这么写:
对于shell脚本命令
,没有发挥的空间,我们在前文只授予了该用户重启nginx服务的权限,此空只能填sudo service nginx reload
至此,证书的推送和目标服务的重启就此结束。按需要配置邮件通知即可。
注意:你需要确保Nginx服务读取的证书文件和上文配置的相同,视具体情况编辑你的nginx.conf
文件,避免出现证书推送成功但是Nginx找不到证书的情况
更新Certd本身的证书
如果您使用源码部署的方式,Certd服务直接处理HTTPS的情况,可以参考官方文档中的描述。
本文采用了Docker方式部署,Certd本身只提供了HTTP服务,TLS由Nginx管理,所有可以将本机(实体机,非Docker容器)也视作一个Nginx_server
,按照上文方式配置。
注意:使用Certd自身管理自身链路的TLS证书,为避免证书部署失败且过期,请确保开启邮件通知功能,在还有一定剩余天数的情况下手动修复相关问题