我有一个设想,在一台服务器 A 上用 DNS 验证方式申请了 LE 的证书,并做了自动更新,然后在另一台服务器 B 上用 rsync 之类的方式把证书同步到本地使用,即完成了 LE 证书在多台服务器间不同网站的使用。但是有一个问题,如果用 crontab + rsync 建立同步任务,在刷新证书到同步新证书之间有最少 1 分钟的时间差,那么这一分钟内访问服务器 B 上网站的用户会不会见到证书无效的提示?
首先需要解决的是证书会不会失效的问题。这件事情我简单问了一些人,得到的答复是没有问题,旧证书都是 90 天后才失效,不会自动吊销。所以在 A 更新证书到同步完成之间,访问服务器 B 是不会出现证书过期的,而且 rsync 的同步机制不会影响文件完整性,因此不用担心证书错误。所以接下来最重要的就是部署 Let's Encrypt 证书签署/续签以及同步任务的问题。
我自己的环境:DO SFO 服务器一台(Server A),Vultr TK 服务器一台(Server B),域名 DNS 托管在 CloudFlare 上,服务器系统都是 Ubuntu Server 14.04 LTS。
获取证书很方便,任何支持 ACME 的客户端都可以用来申请 LE 证书。这里是完整支持列表:
https://community.letsencrypt.org/t/list-of-client-implementations/2103
鉴于我本人的坑爹属性,最后我选择了这个脚本:
https://github.com/Neilpang/le
这个脚本的好处在于,它不需要额外的依赖,安装后即可自动申请证书,并支持多种验证方式,不依赖 root 权限。如果 acme-tiny 能用也不失为一个不错的选择。但考虑到跨服务器签署证书,所以验证网站文件就有点困难了,而 le 支持使用 DNS 记录验证域名所有权,对于跨服务器架设的多个网站很有帮助。这也是我选择它的重要原因。
下面是部署流程。首先搭建服务器环境,基础的 web 服务肯定要配置好,然后安装基本软件:
sudo apt-get install git vim
Git 配置这里就不讲了,我们直接把东西搞下来。
git clone https://github.com/Neilpang/le.git
从本地下好传上去或者 wget 一下都行,然后安装:
./le.sh install
可能会报错,一般都是没能自动配置计划任务。我们先不管他,关掉 shell 重新打开使设置生效。如果是 ssh 远程上去的话重开一个就行。我们在 shell 输入命令看看:
user@ershiwo-do0:~# le https://github.com/Neilpang/le v1.1.9 Usage: le.sh [command] ...[args].... Avalible commands: install: Install le.sh to your system. issue: Issue a cert. installcert: Install the issued cert to apache/nginx or any other server. renew: Renew a cert. renewAll: Renew all the certs. uninstall: Uninstall le.sh, and uninstall the cron job. version: Show version info. installcronjob: Install the cron job to renew certs, you don't need to call this. The 'install' command can automatically install the cron job. uninstallcronjob: Uninstall the cron job. The 'uninstall' command can do this automatically. createAccountKey: Create an account private key, professional use. createDomainKey: Create an domain private key, professional use. createCSR: Create CSR , professional use. user@ershiwo-do0:~# le issue Usage: le issue webroot|no|apache|dns a.com [www.a.com,b.com,c.com]|no [key-length]|no
按照说明配置。因为使用 DNS 验证,所以首先要能修改自己的域名记录,le 同时支持 CloudFlare,DNSPod,CloudXNS,Route53 等的 api,所以利用脚本就可以自动完成域名记录更新。
首先去你的服务商拿 api key,cf 的在 My settings 里。页面往下滚动,Global API Key 就是我们需要的东西。记好这串字符,回到 shell,使用这两行命令添加你的账户:
export CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" export CF_Email="xxxx@sss.com"
然后对应申请证书就好了。
le.sh issue dns-cf aa.com www.aa.com,b.aa.com
脚本会帮你自动更新解析记录,需要几个域名就增加几条 TXT 记录。然后 LE 会进行检查,颁发证书。至此申请证书的流程就完成了。如果之前自动安装计划任务失败,可以手动添加:
le installcronjob
le 的默认设置是 80 天 renew 一次证书,时间是 0 点。同步端要考虑到这点。开始配置,先确定服务器 B 上安没安装 rsync,没有就装一下:
sudo apt-get install rsync
我们的核心思想就是利用 rsync 获取服务器 A 上得到的证书,并应用在 B 的网站上。建立同步任务,可以考虑 ssh 私钥登陆或者设置密码完成同步。这里因为我的服务器上有私钥,所以选择 ssh 方式。
rsync -avtp -e "ssh -p 22" user@ershiwo-do0:/home/user/.le/aa.com /home/user/.le
建议用绝对路径,免得以后维护/跨服务器部署麻烦。同步成功之后在本地/home/user/.le/
下面就会出现证书文件夹,然后我们修改一下 webserver 的配置启用 https,工作就完成了。
我偷个懒,写了个 shell 脚本:
#!/bin/bash rsync -avtp -e "ssh -p 22" user@ershiwo-do0:/home/user/.le/aa.com /home/user/.le service apache2 reload exit 0
保存后直接运行就行,省得还得手动刷新一次 apache/ngnix。
然后记得添加计划任务,我选择每天凌晨 0:10 同步一次,如果一切正常服务器 A 应该在 10 分钟内完成了 renew 任务,然后自动同步到 B。脚本就这么写:
user@ershiwo-vt1:~#crontab -e 10 0 * * * (sh /home/user/sh/letb.sh) > /dev/null
加到最后一行,需要记日志就删掉最后一句。建议记录一下,有问题也好查。
然后就完工了,记得到时检查一下脚本工作是否正常,我写的东西一般都不怎么靠谱的。
update:le 更名为 acme.sh 了,但是使用方法都一样。之后找机会再更新一下。
参考资料:
LE签证书是否同步签发OCSP?不同步的话至少一天之内是不能用的,StartSSL就这德性
支持 OSCP,证书即签即用。如果不关心 TCP 连接流量增加的话可以考虑在服务器端做 OCSP 验证并加缓存。
你的意思是说新证书签发后,旧证书即使未过期也会因为 OCSP 验证失败而不被某些浏览器信任?
新证书可能会因为没有同步在证书生成时签出OCSP,导致在一两天内某些浏览器无法访问
那个不会,生成证书时包含 OCSP,所以即签即用。
crontab里“0 10 * * *” 这么写好像是10点整刷新呀
就说我写的东西不靠谱谢谢指出错误。