通过Certbot配置Let’s Encrypt的SSL(Apache)

最近重新配置了一下ssl,发现wosign的免费ssl已经不再提供,startssl和wosign的证书都已经不再被谷歌信任[1],具体故事可以看这个文章。所以决定再找一家比较适合的ssl供应商,最后发现了Let’s Encrypt的SSL,不仅免费而且使用起来远比一般的ssl简单,所以单独写一篇文章讲一讲这个ssl怎么使用。

官网链接:https://letsencrypt.org/

简单介绍

Let’s Encrypt 是一个于2015年三季度推出的数字证书认证机构,将通过旨在消除当前手动创建和安装证书的复杂过程的自动化流程,为安全网站提供免费的SSL/TLS证书。[2]虽然其颁发的证书有效期仅仅有3个月,但是因为整个证书的申请过程都是脚本实现,所以可以将该证书的重新申请过程添加到任务计划中自动执行,并不需要很多精力进行管理。本文将要主要讲通过Certbot自动生成证书并自动更新证书的过程。

软件安装

对于一般的ssl而言,我们需要先安装openssl之后用它生成密钥和证书申请CSR文件,或者通过响应证书供应商的网站生成这两个文件。而Let’s Encrypt将这一切都自动化执行了,而自动执行的程序就是Certbot。因此我们需要先安装Certbot,其安装方法在其官网有极其详细的描述,我下面只包含了Apache+CentOS下的安装方法:

$ sudo yum install python-certbot-apache

配置Hosts

这个不同的服务器软件不同,对于Apache,找到其设置配置文件夹(通常为/etc/httpd/conf.d或者/etc/httpd/conf)添加新的SSLhost配置,请注意因为Certbot目前不支持一个配置文件中有多个vhosts,请针对每个vhost单独配置一个.conf文件,文件内容如下:

<VirtualHost *:443>
    DocumentRoot "/var/www/wordpress/"
    ServerName stringblog.com
    ServerAlias wordpress
    ErrorLog "/var/log/httpd/wordpress-error.log"
    TransferLog "/var/log/httpd/access_wordpress_log"
    CustomLog "/var/log/httpd/wordpress.log" \
    "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
    SSLEngine on
</VirtualHost>

请注意这个vhost配置不需要填写相关的证书文件,之后Certbot会自动填写。

设置域名解析

因为Certbot通过域名解析结果判断域名的归属,所以在安装证书前,请确保所有使用SSL的域名都已经正确解析到该服务器上,不同的域名供应商的域名解析时间不同,有的长达24小时,建议通过自己的计算机ping一下网址,确保解析已经生效,再进行下一步。

通过Certbot自动安装

如果上述文件都已经配置好并保存,现在就可以自动化的生成证书了,运行命令

$ certbot --apache

安装脚本会提示需要填写的内容,一般只需要填写一个电子邮箱地址,并需要接受几个许可协议,然后系统会提示你已经配置了的几个vhosts,就像下面这样:

Which names would you like to activate HTTPS for?
-------------------------------------------------------------------------------
1: stringblog.com
2: www.stringblog.com
-------------------------------------------------------------------------------
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel):

直接回车,这样就可以选择所有域名。之后Certbot会开始联网检查域名并直接颁发证书。证书安装完成后会提示:

Please choose whether HTTPS access is required or optional.
-------------------------------------------------------------------------------
1: Easy - Allow both HTTP and HTTPS access to these sites
2: Secure - Make all requests redirect to secure HTTPS access
-------------------------------------------------------------------------------
Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

在此处建议直接回复c,自行配置强制SSL,参考我的这篇文章。本人并没有尝试这两个选项,具体是什么效果也不清楚。

回复之后就看到Congratulations啦,已经成功安装了ssl。

这时需要重启Apache:

$ service httpd restart

再前往自己的网址查看,应该就能看到新的来自Let’s Encrypt的证书啦。

自动更新证书

考虑到证书的有效期只有三个月,不能自动更新的话就会相当麻烦。实现自动更新的方法是通过crontab添加定时任务。首先,需要安装Crontab,并启动服务:

$ yum install crontabs
$ service crond start
$ chkconfig crond start

然后通过下面命令添加新的任务:

$ crontab [-u user] -e

其中:-u user:用来设定某个用户的crontab服务,例如,“-u ixdba”表示设定ixdba用户的crontab服务,此参数一般有root用户来运行。

在打开的文件中参考下面的格式说明,填写任务计划

# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * command to be executed

# 这个样例表示每周一凌晨3点执行一次
0 3 * * 1 certbot renew --post-hook "service httpd restart"

其中“–post-hook”是指在certbot重新申请证书之后执行的代码,这里让httpd重启。

总结

考虑到Let’s Encrypt证书使用的便捷性还有同时支持100个域名,目前这个免费证书好于市面上可用的大部分免费证书甚至部分付费证书。虽然其证书每次只有三个月的有效期,但是通过自动化设置反而比一年或者两年的证书更加方便使用,所以强烈推荐内容展示型的网站使用其证书。

兼容性方面,目前本人尝试Opera、Edge、IE 11、Chrome和360浏览器都没有任何问题,似乎目前只有XP和安卓2下有不被信任的情况[3]


参考

[1] Google, Google Blog, Distrusting WoSign and StartCom Certificates, 10/2016, https://security.googleblog.com/2016/10/distrusting-wosign-and-startcom.html

[2] Wikipedia, Let’s Encrypt, 07/2016, https://zh.wikipedia.org/wiki/Let%27s_Encrypt

[3] Jerry Qu, imququ.com, Let’s Encrypt,免费好用的 HTTPS 证书, 12/2015, https://imququ.com/post/letsencrypt-certificate.html

[4] peida, 竹子-博客, 每天一个linux命令(50):crontab命令, 01/2013, http://www.cnblogs.com/peida/archive/2013/01/08/2850483.html

[5] Certbot, User Guide, https://certbot.eff.org/docs/using.html#renewing-certificates