如何在 Ubuntu 14.04 上为 Nginx 添加 Let's Encrypt

本篇过旧,推荐这一篇文章:How To Secure Nginx with Let's Encrypt on Ubuntu 14.04

介绍

Let's Encrypt 是一个新的 CA,他能够提供一种非常容易的方式来获取和安装免费的 TLS/SSL 证书,从而在 web 服务器上启用 HTTPS 加密。他通过提供软件客户端 letsencrypt 来简化这个过程,它企图自动完成大部分所需的必要步骤。当前,Let's Encrypt 仍然处在公开测试阶段,他整个获取和安装证书的流程只在 Apache 服务器上实现了全部自动化。然而 Let's Encrypt 也可以很容易的在其他不同的服务器上获取和安装免费的 SSL 证书。

在本片教程里,我将向你展示如何使用 Let's Encrypt 来获取一个免费的 SSL 证书并与 Nginx 和 Ubuntu 相搭配。我也同时会向你展示如何自动刷新你的 SSL 证书。

步骤 1 — 安装 Let's Encrypt 客户端

安装 Git 和 bc

使用 apt-get 安装 gitbc

sudo apt-get -y install git bc

Clone Let's Encrypt

现在就可以使用下面的命令把 Let's Encrypt 版本库克隆到 /opt 目录下了:

sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt

现在在 /opt/letsencrypt 目录下有了一个 letsencrypt 项目的副本。

步骤 2 — 获取一个证书

Let's Encrypt 提供了多种方式来获取 SSL 证书。不像 Apache 插件那样,大多数插件只能帮你获取一个证书,但后续你还是得手动配置服务器来使用这个证书。这种只提供证书并不负责安装证书的插件被归类于『认证者』,因为它们只用于验证是否应该给一个服务器发布一个证书。

我等下就会演示如何使用 Standalone 插件来获取一个 SSL 证书。

核实 80 端口已打开

Standalone 插件提供一个非常简单的方式来获取 SSL 证书。它通过在你当前服务器的 80 端口上临时运行一个小型服务器来与 Let's Encrypt CA 连接并在颁发证书之前来验证你的服务器标识。同样的,这种方法需要保证 80 端口没有被占用。正因为这样,确保你已经停掉了 80 端口上正在使用的服务器。

如果你是用 Nginx,那么可以这样做:

sudo service nginx stop

如果不确定 80 端口是否被使用,可以使用这个命令:

netstat -na | grep ':80.*LISTEN'

如果命令没有输出结果,那么就可以放心的使用 Standalone 插件了。

运行 Let's Encrypt

在运行 Let's Encrypt 之前请切换到 letsencrypt 目录:

cd /opt/letsencrypt

现在就可以通过下面的命令使用 Standalone 插件了:

./letsencrypt-auto certonly --standalone

letsencrypt 初始化之后,你将会看到一些提示信息。实际的提示取决于你之前是否用过 Let's Encrypt,但我们这次展示第一次使用时的情况。

这个提示可以输入邮箱来接受通知和恢复忘记的 key:

然后你必须同意 Let's Encrypt Subscribe Agreement. 选择同意:

然后输入你的域名。注意,如果你想针对多个域名只使用一个证书,确保包含下面所有的域名:

如果所有的都成功了将会看到下面的信息:

Output:
IMPORTANT NOTES:
 - If you lose your account credentials, you can recover through
   e-mails sent to sammy@digitalocean.com
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/example.com/fullchain.pem. Your
   cert will expire on 2016-03-15. To obtain a new version of the
   certificate in the future, simply run Let's Encrypt again.
 - Your account credentials have been saved in your Let's Encrypt
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Let's
   Encrypt so making regular backups of this folder is ideal.
 - If like Let's Encrypt, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

防火墙提示:如果你收到一个像 Failed to connect to host for DVSNI challenge 这样的错误,那你的服务器防火墙可能需要设置成在 443 端口下允许 TCP 传输。

提示:如果你的域名使用了 CloudFlare 之类的 DNS 服务,那你需要临时禁用它们直到你获取到了证书。

证书文件列表

在获取到证书后,你会得到下面几个 PEM-编码的文件:

cert.pem: 你域名的证书。
chain.pem: Let's Encrypt chain 证书。
fullchain.pem: cert.pem 和 chain.pem 联合。
privkey.pem: 你证书的私有 key。

留意刚才创建的几个文件的路径这很重要,因为等下在配置服务器的时候会用到。这些文件在 /etc/letsencrypt/archive 路径下。然而 Let's Encrypt 在 /etc/letsencrypt/live/your_domain_name 目录下创建了相应证书的符号链接。因为这些链接总是指向最近的证书文件,所以你应该用这些路径来表示你的证书文件。

你可以用下面的命令查看已存在的证书文件(用你自己的域名替换下面的):

sudo ls /etc/letsencrypt/live/your_domain_name

它的输出应该就是之前提到的那四个证书文件。你等下可能会使用 fullchain.pem 来配置你的服务器作为证书,privkey.pem 文件作为证书的 key 文件。

步骤 3 — 配置服务器(Nginx)上的 TLS/SSL

现在你有了一个 SSL 证书,你需要配置服务器才能使用它。

现在你需要编辑包含你服务器块的 Nginx 文件。默认的位置在 /etc/nginx/sites-available/default

sudo vim /etc/nginx/sites-available/default

找到 server 代码块:

server {
        listen 80 default_server;
        listen [::]:80 default_server ipv6only=on;

        root /usr/share/nginx/html;
        index index.html index.htm;

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

注释或删掉跟 80 端口相关的监听代码,在这里的话应该是这两行:

 listen 80 default_server;
 listen [::]:80 default_server ipv6only=on;

我们将配置服务器块来使用 SSL 监听 443 端口。

server { 代码块中,添加下面的几行但要用你自己的域名替换所有的 example.com:

        listen 443 ssl;

        server_name example.com www.example.com;

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

这些代码能让你的服务器启用 SSL,并告诉它使用 Let's Encrypt SSL 证书。

如果只允许最安全的 SSL 协议和密码,那继续添加下面的几行代码:

 ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
 ssl_prefer_server_ciphers on;
 ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

Lastly, outside of the original server block (that is listening on HTTPS, port 443), add this server block to redirect HTTP (port 80) to HTTPS. Be sure to replace the highlighted part with your own domain name:
最后,在原始 server block 的外面,添加下面这个 server block 来重定向 HTTP(80端口)到 HTTPS。

server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}

保存并退出。

使用下面的命令重启 Nginx:

sudo service nginx restart

现在你就可以测试 HTTPS 是否已在你的域名下启用了。