Nginx证书自动颁发部署教程一条龙
背景:
最近业务需求搞HTTPS,本着想这就是个证书然后研究了下记录下,网上先查了下,本着能白嫖就白嫖的思路,我们肯定不搞付费SSL证书,但是貌似腾讯云,和阿里云这些都可以申请免费证书,但是都需要备案,于是乎我就查到了 Let’s Encrypt证书
Let’s Encrypt 是一个免费、自动化和开放的证书颁发机构,由非营利性互联网安全研究小组 (ISRG) 提供
嚯,免费的东西我喜欢,但是仔细看了下,申请的证书只有三个月期限,到期后需要重新申请,这就不友好了,当时第一个念头是应该有自动管理的东西,
果然有通过Certbot来管理Let’s Encrypt的证书,使用前需要安装一堆库,觉得不太友好。想找个简单的来使用
acme.sh
一个纯 Shell(Unix shell)语言编写的 ACME 协议客户端。
完整的 ACME 协议实现。
支持 ECDSA 证书
支持 SAN 和通配符证书
简单、强大且非常易于使用。你只需要3分钟就可以学会。
Bash、dash 和 sh 兼容。
完全用 Shell 编写,不依赖 python。
只需一个脚本即可自动颁发、更新和安装您的证书。
不需要root/sudoer访问权限。
Docker 就绪
IPv6 就绪
更新或错误等的 Cron 作业通知。
非常符合我的需求,于是研究了下记录下来.
安装
curl https://get.acme.sh | sh -s email=my@example.com
或
wget -O - https://get.acme.sh | sh
执行上面的命令,它会:
从 GitHub 上下载 sh 脚本并执行
把文件解压到用户的 ~/.acme.sh目录下
给命令行设置一个acme.sh的 alias
别名 最后注册一个 cron 定时任务来自动更新证书。
验证是否安装成功
acme.sh -h
证明协议
acme.sh提供了acme协议支持的所有试验证明协议。一般有两种方式验证:http和dns验证。
- http方式需要在你的网站根目录下放一个文件,来验证你的域名所有权利,完成验证。然后就可以生成证书了。
acme.sh --issue -d mydomain.com -d www.mydomain.com --webroot /home/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
注意,不管是apache还是nginx模式,acme.sh在完成验证之后,都会恢复到之前的状态,都不会私自更改你自身的配置。好的地方是你不用担心配置被搞坏,还有一个不足,你需要自己配置ssl的配置,否则只能成功生成证书,你的网站还是无访问https。但是为了安全,你还是自己手动修改配置吧。
如果你还没有运行任何web服务,80端口是空旷的,那么acme.sh还能假装自己是一个webserver,临时听在80端口,完成试验证明:
acme.sh --issue -d mydomain.com --standalone
更高级别的使用方法请参考: https: //github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
- 手动 dns 方式, 手动在域上添加一条 txt 解析记录, 验证域名所有权限.
这种方式的好处是,你不需要任何服务器,不需要任何公网ip,只需要dns的解析记录即可完成验证。问题是,如果不同时配置Automatic DNS API,使用这种方式acme.sh 将无法自动更新证书,每次都需要手动重新解析试验域名所有权利。
acme.sh --issue --dns -d mydomain.com \
--yes-I-know-dns-manual-mode-enough-go-ahead-please
然后,acme.sh会生成相关的解析记录显示出来,你只需要在你的域管理面板中添加这条txt记录即可。
等候解析完成之后, 重新生成证书:
acme.sh --renew -d mydomain.com \
--yes-I-know-dns-manual-mode-enough-go-ahead-please
注意第二次这里用的是 --renew
dns 方式的真正强大之处在于可以使用域解析商提供的 api 自动添加 txt 记录完成验证。
acme.sh目前支持 cloudflare, dnspod, cloudxns, godaddy
以及 ovh
等十种解析商的自主集成。
在这查看DNS解析商的支持
以Cloudflare
为例,你需要先登录到Cloudflare账号,
我的个人资料》API令牌获取
获取全局密钥
然后命令行导入
export CF_Key="<key>"
export CF_Email="example@gmail.com"
创建APItoken
export CF_Token="<token>"
export CF_Account_ID="<id>"
然后生成证书
./acme.sh --issue --dns dns_cf -d *.example.com
证明书就会自动生成了。这里给出的 api id
和 api key
这些配置信息会保存到 ~/.acme.sh/account.conf
这个文件里,在证书续期或者其他利用 CF 进行验证的时候会自动调用。以后你在使用 Cloudflare api 的时候,就不需要再指定了。直接生成就好了:
acme.sh --issue -d *.example.com --dns dns_cf
签发证书成功后,需要把证书安装或者复制到真正需要的地方,如 nginx / apache 的目录下。
官方说必须用下面的命令来安装证书,不能直接用 ~/.acme.sh/目录下的证书文件,因为那只能内部使用,且未来目录结构可能会更改。
我们只需要使用 --installcert 命令,指定目标位置,然后证书文件就会被 copy 到相应的位置了。
其中域名是必须的,其他参数是可选的。
有必要的话,可能需要对证书文件的所属权限进行一些设置。
Nginx:
acme.sh --installcert -d example.com \
--key-file /path/to/keyfile/in/nginx/key.pem \
--fullchain-file /path/to/fullchain/nginx/cert.pem \
--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/.cer
,否则 SSL Labs 的测试会报 Chain issues Incomplete 错误
acme.sh 自动生成的定时任务
43 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
acme.sh 会帮我们每隔60天(会变) 更新一次证书 更新证书的安装目录和上次一致 reloadcmd
用来指定下次更新时 重新加载证书的命令,亲测Docker容器也可以使用 比如重启Docker容器 Docker restart nginx
这样证书就安装完成了,并且后续的重新申请部署完全不需要我们去管