在前两年自己部署服务,刚接触到ssh证书的时候就看到过acme.sh,但是当时感觉好麻烦,而且阿里云、腾讯云都提供很多张一年的免费证书,所以一直懒得搞。不过随着阿里云在去年调整了免费证书的有效期,今年腾讯云也进行了调整,不得不着手研究自动化方案了,毕竟一年和三个月差距还是非常大的。
实际研究下来,发现acme这套方案确实是简单且强大,本篇文章来记录一下我会用到的几种使用acme.sh签发证书的方式。
本文几乎所有内容都来源于acme.sh的官方wiki。
安装
尽管官方支持docker,但我觉得没必要,就用官方的一键脚本即可,非常简单
|
|
安装完成之后进入对应的目录,一般是cd ~/.acme.sh
,此时ls
应该可以看到有个acme.sh
的文件,后面操作都在这个目录。
签发证书
DNS API
这里以阿里云为例,因为我有一个域名是托管在阿里云的,所以很常用这种方式。
获取AcessKey和SecretKey
- 登录阿里云控制台,跳转到RAM访问控制
- 创建一个用户,名称随意,备注一下云解析DNS
- 为用户添加权限,策略名称是
AliyunDNSFullAccess
,类型是系统策略,描述写的是管理云解析(DNS)的权限 - 完成后,为该用户创建AccessKey,注意把两个key存下来,关了对话框就看不到了。
证书签发
先设置环境变量,<key>
对应刚才生成的AccessKey,<secret>
对应SecretKey
|
|
然后最简单的方式就是一行命令
|
|
不过先别急着运行,我稍微解释下
先说上面这行命令中的几个参数,--issue
就是要生成证书,--dns dns_ali
就是使用dnsapi的方式完成认证且对应的厂商是阿里云,-d
是--domain
的简写,就是指定对应的域名。注意这里指定了两个域名,且有一个是泛域名,这是因为acme支持生成SAN证书和通配符证书。
除此之外,现在acme设置的默认CA是ZeroSSL,如果不想用这家,比如想换成Let’s Encrypt,那么需要在后面加一个选项--server letsencrypt
。或者为了避免某次忘记加参数,可以运行下面这行命令把自己的默认CA改成Let’s Encrypt
|
|
还有一个参数,可能绝大多数不会用到,就是证书的加密算法。目前默认是ECDSA P-256
,也就是使用ECC加密算法,如果想用RSA加密算法或者想修改加密程度,可以使用keylength
参数,例如--keylength 4096
代表使用RSA加密,密钥长度4096位,真的用到的话可以通过./acme.sh -h
看对应的帮助文档。关于ECC和RSA可以看腾讯云的这个对比表格。
现在可以根据自己需要运行命令生成证书了,当前目录应该会多出一个example.com_ecc
的文件夹,文件夹内有一堆文件,一般只需要其中的两个文件,fullchain.cer
和example.com.key
。前者是包含中间证书的完整的公钥,后者是对应域名的私钥。私钥主要妥善保存和传输,不要泄露了。另外,文件名和格式可以随便改,比如后缀改成.pem
之类的,注意别把内容改了就行。
到这一步,证书的签发就完成了,默认情况下acme会自动添加一个cron job,这会自动续期生成的证书。
原理简述
使用dnsapi这种方式签发证书,其原理就是通过调用相关厂商的API给对应的域名加一条TXT记录,然后再去通过DNS查询查这条记录的值是否匹配,来验证域名的归属是正确的。最后操作完会自动把这条记录删除,所以个人是无感的。实际上acme也支持dns manually的方式,就是不调用API了,手工完成前面的这些工作,不过这个就太麻烦了,一般不推荐。
Webroot
这种方式我极少用,使用场景一般是DNS API没法用,然后恰好有一个web服务在运行,并且这个网站是公网可访问的。
假设已经配置好了一个nginx服务,监听了80端口,其中静态文件的存放目录是/var/www/html
,当前用户对这个目录具备写文件的权限。
然后依然是在~/.acme.sh
目录下,直接运行命令
|
|
注意这里没有--dns
选项,改成了-w
,至于其他的--server letsencrypt
之类的选项则和上面一样,按需添加。
这种方式的原理是,acme会在静态文件夹内生成个文件,然后通过http访问对应的文件,如果文件内容一致那么说明域名归属没问题。同样最后会把文件清理掉。
Standalone
这种方式用的倒是不少,有时候在小众厂商搞了个年抛域名,就用这种方式申请证书。
同样需要在公网服务器操作,不过不需要部署nginx之类的服务,只需要安装socat
这个命令行工具即可。使用的命令是
|
|
默认会占用80端口,也可以通过--httpport
参数来改成其他端口,比如改成88端口就在后面补充--httpport 88
。
这其实就是用socat代替了nginx等web服务,申请的证书用途是非web服务的时候,用这种方式会更方便。
总结
除了上面提到的我会用到的三种方式,官方还支持很多种签发证书的方式,甚至还能混合使用。
申请证书 + 自动续期,一行命令就可以搞定,这确实方便。但是对我而言,还有一些问题没有得到解决,比如我想知道证书续期之后通知我一下,我还想要在证书续期之后自动部署。这些acme都可以做到,不过就要稍微麻烦点了,下一篇文章再来讲。