2017年02月20日更新:第4节

Let’s Encrypt是电子前哨基金会(EFF)发布的免费SSL证书服务,受到微软、谷歌等大佬的支持,但是配置比较复杂(主要是证书有效事件较短,需要重新签发,虽然签发的过程都是在自己的机器上通过命令行实现),之前研究过一下,最终还是放弃了。

但最最近由消息称沃通的CA将有可能被Mozilla拒绝,所以还是重新弄起来吧。下面说一下步骤。

安装Certbot

Certbot是EFF开发的一个简单的工具,比起我之前研究的时候弄的ACME要简单得多,访问https://certbot.eff.org/ 之后,选择你的服务器(webserver)和操作系统(Operating System),就会给出简单的步骤了,我们还是一步一步来吧。

我的服务器是Nginx,操作系统是Ubuntu 16.04。由于自带了软件包,安装只需要一行命令即可:

sudo apt-get install letsencrypt

如果是其他版本的Ubuntu,只需要下载一个脚本就行了(下面的命令在需要下载到的目录里执行):

wget https://dl.eff.org/certbot-auto
chmod a+x certbot-auto
./certbot-auto

签发证书

很简单,直接运行letsencrypt命令即可(使用其他版本的Ubuntu的把letsencrypt换成上面下载的certbot-auto,注意执行脚本需要完整路径/path/to/certbot-auto,在脚本所在目录下是就是./certbot-auto)。

sudo letsencrypt certonly --webroot -w /var/www -d example.com -d www.example.com -w /var/www/sub -d sub.example.com

第一次运行时会问你一些你的信息,以后就不会再询问了。

解释一下,certonly是它的子命令,表示只颁发证书。--webroot是它的插件,用于自动验证域名。-w是指定网站的目录,-d是指定目录对应的域名。一个-w后可以跟着多个-d就对应多个域名。可以用多个-w设置多个目录对应不同的域名。这些域名都在一个证书里。

需要注意的是,域名下的\.well-know\acme-challenge\目录下的文件必须要可以访问。这个是Let’s Encrypt用于验证域名所有权的。它会在上面-w参数设置的目录下建立临时文件,然后通过HTTP访问,比如上面的设置就会新建诸如/var/www/.well-known/acme-chanllenge/xxxxxxx(xxxxxxx是随机字符),然后通过http://example.com/.well-known/acme-chanllenge/xxxxxxx来验证。如果你的网站是纯HTTPS的,你可以用把这个地址重定向到https://example.com/.well-known/acme-chanllenge/xxxxxxx,可以成功通过验证。

看到Congratulations!就代表成功了,下面我们就可以配置Nginx了。

配置HTTP服务器

证书所在的地方是/etc/letsencrypt/下,archive里面是所有证书的存档,keys里面是所有证书,不过我们不用管,我们需要的证书在live下面,对应网站域名的目录下面就是了。一共有四个文件。

  • privkey.pem 这是私匙,对应Nginx的ssl_certificate_key选项,或者Apache2的SSLCertificateKeyFile选项。

     

  • cert.pem 服务器证书,这个只有Apache2低于2.4.8版本需要,对应SSLCertificateFile选项。

  • chain.pem 除服务器证书之外的所有证书,对于1.3.7版以上的Nginx对应ssl_trusted_certificate选项,对于低于2.4.8的Apache2对应SSLCertificateChainFile选项。

  • fullchain.pem 包括上面的服务器证书和其他证书,Nginx对应ssl_certificate选项,2.4.8版以上的Apache2对应SSLCertificateFile。

所以对于我用的Nginx来说,只需要privkey.pem和fullchain.pem这两个就够了。Apache2的话参考设置HTTPS的文章,对应设置上面提到的文件和选项就行了。

在Nginx的server下设置如下响应的ssl选项就行了,如:

server {
    listen 443 ssl;
    server_name example.com www.example.com;

    root /var/www;
    index index.html;

    ssl on;
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    location / {
        try_files $uri $uri/ =404;
    }
}

如果你是第一次设置HTTPS,记得在listen选项那里要监听443端口,并在后面加上ssl。如果要启用HTTP/2,请参考这篇文章

最好在原来的80端口上设置好跳转:

server {
    listen 80;
    server_name example.com www.example.com;
    rewrite ^(.*)$ https://example.com$1 permanent;
}

设置好了别忘了重启Nginx。

自动更新证书

更新证书很简单,直接如下命令就可以了:

sudo letsencrypt renew

可以用--dry-run选项来模拟更新证书,看看会不会出错。由于Ubuntu自带的版本有点旧,所以会出错……(certbot-auto的是最新的所以不会有问题)。这时候就需要加上--force-renew选项来强制更新。第一次运行可能还要你同意服务条款,所以根据提示加上--agree-tos(以后就不需要了)。

在正式更新的时候,要使证书生效还需要重启Nginx。如果是certbot-auto我们可以用--pre-hook和--post-hook来设置更新前后的命令,用来停止和启动Nginx。

sudo /path/to/certbot-auto renew --pre-hook "systemctl stop nginx" --post-hook "systemctl start nginx"

但是Ubuntu自带的版本有点旧,所以就只好自己写脚本了。

#!/bin/sh
systemctl stop nginx
letsencrypt renew --force-renew
systemctl start nginx

2017年2月20日更新

上述命令中不能使用systemctl stop nginx来停止nginx,因为更新证书时同样需要验证,如果停止了服务就无法验证了。我们只需要在更新后重启nginx就行了。所以:

如果使用新版certbot-auto我们只需要:

sudo /path/to/certbot-auto renew --post-hook "systemctl start nginx"

自己编写脚本的话改成这样:

#!/bin/sh
letsencrypt renew
systemctl restart nginx

我们还可以在这个脚本中将输出重定向来生成日志文件,以便以后检查。

保存文件,这里我们保存到/opt/scripts/letsencrypt_renew。

我们可以用crond或者systemd来自动更新证书,这里就简单点,用crond吧。用sudo crontab -e命令编辑root用户的crontab。在最后面新插入行并添加如下内容:

0 */12 * * * sh /opt/scripts/letsencrypt_renew

上面的意思是,每12小时的第0分执行脚本一次。因为Let’s Encrypt的推荐每12小时更新一次。更新操作并不一定会真的更新证书,只有在快到期的时候才会更新。

如果不想修改root的crontab,可以在/etc/cron.d下新建文件写入如下内容:

0 */12 * * * root sh /opt/scripts/letsencrypt_renew

比起crontab,就是在要执行的命令前面多了一个表示用户的root。

更新证书是检测/etc/letsencrypt/renewal下的配置文件进行的,所以即使不管颁发多少个证书,上面的更新脚本都不用修改。

最后

如果要删除证书的话,把/etc/letsencrypt/下的archive、live和renewal中对应域名的文件或目录删除就可以了。

此外,还可以用-m选项来设置Email地址。还有更多的功能就去看看官方的文档吧:https://certbot.eff.org/docs/ 。

via。https://tsukkomi.org/post/get-the-lets-encrypt-certificate-on-ubuntu

最后修改:2017 年 09 月 06 日 01 : 35 AM