如何使用让我们在Ubuntu 16.04加密安全的Nginx

在本教程中,我们将向您展示如何使用让我们加密,以获得一个免费的SSL证书和Nginx的在Ubuntu 16.04使用它。我们还将向您展示如何自动更新您的SSL证书。如果你正在运行一个不同的Web服务器,只需按照您的Web服务器的文档,以了解如何使用证书与您的设置。

介绍

Let's Encrypt是一个新的证书颁发机构(CA),它提供了一种简单的方法来获取和安装免费的TLS / SSL证书,从而在Web服务器上启用加密的HTTPS。 它通过提供一个软件客户端,简化了过程letsencrypt ,试图的所需的步骤大部分(如果不是全部)自动化。 目前,获取和安装证书的整个过程仅在Apache Web服务器上完全自动化。 但是,Let's Encrypt可以用于轻松获取免费的SSL证书,可以手动安装,无论您选择哪种Web服务器软件。

在本教程中,我们将向您展示如何使用Let's Encrypt获取免费的SSL证书,并在Ubuntu 16.04上使用Nginx。 我们还将向您展示如何自动更新您的SSL证书。 如果您运行的是其他网络服务器,只需按照网络服务器的文档来了解如何在设置中使用证书。

Nginx与让我们加密TLS / SSL证书和自动更新

先决条件

在学习本教程之前,您需要了解一些内容。

你应该有一个Ubuntu 16.04服务器谁拥有非root用户sudo权限。 你可以学习如何按照我们建立这样一个用户帐户为Ubuntu 16.04教程初始服务器设置

您必须拥有或控制您希望使用证书的注册域名。 如果您还没有注册域名,您可以向其中一个域名注册商(例如Namecheap,GoDaddy等)注册一个域名。

如果你还没有准备好,一定要创建一条A记录指向你自己的域名服务器的公网IP地址。 这是必需的,因为Let's Encrypt验证您拥有它为其颁发证书的域。 例如,如果你想获得一个证书example.com ,该域必须解析到服务器的验证过程工作。 我们的安装程序将使用example.comwww.example.com作为域名,所以需要两个DNS记录

一旦你拥有所有的先决条件,让我们继续安装Let's Encrypt客户端软件。

第1步:安装让我们加密客户端

第一步用咱们加密获得SSL证书是安装letsencrypt您的服务器上的软件。 虽然咱们加密项目已更名为他们的客户certbot ,包括在Ubuntu 16.04版本库被简单地称为客户端letsencrypt 这个版本完全适合我们的目的。

更新服务器的本地apt包装指标,并通过键入安装客户端:

sudo apt-get update
sudo apt-get install letsencrypt

letsencrypt客户现在应该可以使用了。

第2步:获取SSL证书

Let's Encrypt提供了通过各种插件获取SSL证书的各种方法。 不同的是Apache的插件,它是覆盖在不同的教程 ,大多数的插件只会帮助你得到,你必须手动配置你的Web服务器使用证书。 仅获取证书而不安装证书的插件称为“验证器”,因为它们用于验证服务器是否应颁发证书。

我们会告诉你如何使用Webroot的插件来获取SSL证书。

如何使用Webroot插件

Webroot公司的工作插件放置在一个特殊的文件/.well-known目录文档根目录下,它可以打开(通过Web服务器)内由让我们的加密服务进行验证。 根据配置的不同,你可能需要明确允许访问/.well-known目录。

如果你还没有安装的Nginx的是,按照这样做的这个教程 完成后继续下面。

为了确保该目录可供Let's Encrypt进行验证,让我们快速更改我们的Nginx配置。 默认情况下,它位于/etc/nginx/sites-available/default 我们将用nano来编辑它:

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

在服务器块中,添加此位置块:

添加到SSL服务器块
        location ~ /.well-known {
                allow all;
        }

您还需要仰望你的文档根目录是通过搜索设置为root指令,如路径是需要使用的Webroot的插件。 如果您使用的是默认的配置文件,根会/var/www/html

保存并退出。

检查您的配置是否有语法错误:

sudo nginx -t

如果没有找到错误,请使用此命令重新启动Nginx:

sudo systemctl restart nginx

现在我们知道我们的webroot-path ,我们可以使用Webroot公司的插件要求使用这些命令的SSL证书。 在这里,我们也与我们的指定域名-d选项。 如果你想有一个单一的证书与多个域名的工作(如example.comwww.example.com ),一定要包括所有的人。 此外,请确保使用适当的webroot路径和域名替换突出显示的部分:

sudo letsencrypt certonly -a webroot --webroot-path=/var/www/html -d example.com -d www.example.com

之后letsencrypt初始化,系统将提示您一些信息。 确切的提示可能会有所不同,具体取决于您以前是否使用过Let's Encrypt,但我们会第一时间介绍您。

在提示时,输入将用于通知和丢失的密钥恢复的电子邮件地址:

电子邮件提示

那么你必须同意让我们加密订阅协议。 选择同意:

让我们加密用户协议

如果一切顺利,你应该看到一个类似下面的输出消息:

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 ,您的服务器的防火墙可能需要配置以允许端口TCP流量80443

注意:如果您的域名是通过像CloudFlare的一个DNS服务路由,则需要暂时禁用它,直到你获得的证书。

证书文件

获得证书后,您将拥有以下PEM编码的文件:

  • cert.pem:域的证书
  • chain.pem:该让我们的加密证书链
  • fullchain.pem: cert.pemchain.pem结合
  • privkey.pem:您证书的私钥

重要的是,您知道刚刚创建的证书文件的位置,因此您可以在Web服务器配置中使用它们。 这些文件本身被放置在一个子目录中/etc/letsencrypt/archive 然而,让我们加密创建符号链接在最新的证书文件/etc/letsencrypt/live/ your_domain_name目录。 因为链接将始终指向最新的证书文件,这是您应该用来引用您的证书文件的路径。

您可以通过运行此命令(在您的域名中替换)检查文件是否存在:

sudo ls -l /etc/letsencrypt/live/your_domain_name

输出应该是前面提到的四个证书文件。 在那一刻,你会配置Web服务器使用fullchain.pem的证书文件, privkey.pem为证书密钥文件。

生成强Diffie-Hellman组

为了进一步提高安全性,您还应该生成一个强的Diffie-Hellman组。 要生成2048位组,请使用以下命令:

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

这可能需要几分钟的时间,但是当它这样做,你将有一个强大的DH组/etc/ssl/certs/dhparam.pem

第3步:在Web服务器(Nginx)上配置TLS / SSL

现在您有一个SSL证书,您需要配置您的Nginx Web服务器使用它。

我们将对我们的配置进行一些调整:

  1. 我们将创建一个包含我们的SSL密钥和证书文件位置的配置片段。
  2. 我们将创建一个配置代码段,其中包含可用于将来的任何证书的强SSL设置。
  3. 我们将调整Nginx服务器块来处理SSL请求,并使用上面的两个片段。

这种配置Nginx的方法将允许我们保持干净的服务器块,并将公共配置段放入可重用的模块。

创建指向SSL密钥和证书的配置片段

首先,让我们创建了一个新的Nginx的配置片段/etc/nginx/snippets目录。

要正确区分这个文件的目的,我们将其命名为ssl-后跟我们的域名,随后.conf的结尾:

sudo nano /etc/nginx/snippets/ssl-example.com.conf

在这个文件中,我们只需要在设置ssl_certificate指令对我们的证书文件和ssl_certificate_key到相关的关键。 在我们的例子中,这将是这样的:

/etc/nginx/snippets/ssl-example.com.conf
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

添加这些行后,保存并关闭文件。

创建具有强加密设置的配置代码段

接下来,我们将创建另一个代码段,定义一些SSL设置。 这将设置Nginx与一个强大的SSL加密套件,并启用一些高级功能,将有助于保持我们的服务器安全。

我们将设置的参数可以在将来的Nginx配置中重用,因此我们将给文件一个通用名称:

sudo nano /etc/nginx/snippets/ssl-params.conf

要设置Nginx的SSL安全,我们将利用这些建议雷米面包车埃尔斯特Cipherli.st网站。 此网站旨在为流行软件提供易于使用的加密设置。 你可以阅读更多关于他对Nginx的选择,决定在这里

注意:默认建议在设置Cipherli.st提供强有力的安全保障。 有时,这是以增加客户端兼容性为代价的。 如果您需要支持较旧的客户端,还有一个备用列表,可以通过单击链接上的链接标记为“是的,给我一个密码套件,与旧的/旧的软件配合使用。

可以使用兼容性列表,而不是下面配置中的默认建议。 选择使用哪个配置很大程度上取决于您需要支持哪些配置。

为了我们的目的,我们可以全部复制提供的设置。 我们只需要做一些小的修改。

首先,我们将为上游请求添加我们首选的DNS解析器。 我们将使用Google的本指南。 我们也将继续,并设置ssl_dhparam设置为指向我们先前所产生的的Diffie-Hellman文件。

最后,你应该花点时间读上了HTTP严格传输安全,或HSTS ,特别是有关“预紧力”的功能 预加载HSTS提供了更高的安全性,但如果意外启用或启用不正确,可能会产生深远的影响。 在本指南中,我们不会预加载设置,但如果您确定您了解其含义,则可以修改此设置:

/etc/nginx/snippets/ssl-params.conf
# from https://cipherli.st/
# and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# Disable preloading HSTS for now.  You can use the commented out header line that includes
# the "preload" directive if you understand the implications.
#add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;

ssl_dhparam /etc/ssl/certs/dhparam.pem;

保存并在完成后关闭文件。

将Nginx配置调整为使用SSL

现在我们有了我们的代码片段,我们可以调整我们的Nginx配置以启用SSL。

我们将本指南所使用的假设中default服务器模块文件中/etc/nginx/sites-available目录。 如果使用不同的服务器块文件,请在以下命令中替换它的名称。

在我们继续进行之前,让我们备份我们当前的服务器块文件:

sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bak

现在,打开服务器块文件进行调整:

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

在里面,你的服务器块可能开始像这样:

/ etc / nginx / sites-available / default
server {
    listen 80 default_server;
    listen [::]:80 default_server;

    # SSL configuration

    # listen 443 ssl default_server;
    # listen [::]:443 ssl default_server;

    . . .

我们将修改此配置,以便未加密的HTTP请求自动重定向到加密的HTTPS。 这为我们的网站提供最好的安全。 如果要允许HTTP和HTTPS流量,请使用以下备用配置。

我们将把配置分成两个独立的块。 两人第一次后listen指令,我们将添加一个server_name指令,设置为您的服务器的域名。 然后我们将设置一个重定向到我们将要创建的第二个服务器块。 之后,我们将关闭这个短块:

/ etc / nginx / sites-available / default
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name example.com www.example.com;
    return 301 https://$server_name$request_uri;
}

    # SSL configuration

    # listen 443 ssl default_server;
    # listen [::]:443 ssl default_server;

    . . .

接下来,我们需要在下面直接启动一个新的服务器块来包含剩余的配置。 我们可以取消这两个listen使用端口443的指令,我们可以添加http2以启用HTTP / 2这个区块内这些行。 之后,我们只需要包含我们设置的两个代码段文件:

注意:您可能只有一个 listen指令,其中包括default_server每个IP的版本和端口组合修改。 如果您对具有这些端口上启用其他的服务器块default_server设置,必须从块之一删除修改。

/ etc / nginx / sites-available / default
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name example.com www.example.com;
    return 301 https://$server_name$request_uri;
}

server {

    # SSL configuration

    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;
    include snippets/ssl-example.com.conf;
    include snippets/ssl-params.conf;

    . . .

保存并在完成后关闭文件。

(备用配置)允许HTTP和HTTPS流量

如果你想要或需要允许加密和未加密的内容,你将不得不配置Nginx一点不同。 这通常不推荐,如果它可以避免,但在某些情况下可能是必要的。 基本上,我们只是将两个独立的服务器块压缩成一个块,并删除重定向:

/ etc / nginx / sites-available / default
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;

    server_name example.com www.example.com;
    include snippets/ssl-example.com.conf;
    include snippets/ssl-params.conf;

    . . .

保存并在完成后关闭文件。

第4步:调整防火墙

如果你有ufw启用防火墙,所推荐的先决条件指南,你需要调整设置以允许SSL流量。 幸运的是,Nginx的注册与几个配置文件ufw安装时。

您可以通过键入以下内容查看当前设置:

sudo ufw status

它可能看起来像这样,这意味着只允许HTTP流量到Web服务器:

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
Nginx HTTP                 ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
Nginx HTTP (v6)            ALLOW       Anywhere (v6)

要额外允许HTTPS流量,我们可以允许“Nginx完全”配置文件,然后删除冗余的“Nginx HTTP”配置文件限额:

sudo ufw allow 'Nginx Full'
sudo ufw delete allow 'Nginx HTTP'

您的状态现在应该如下所示:

sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
Nginx Full                 ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
Nginx Full (v6)            ALLOW       Anywhere (v6)

第5步:启用Nginx中的更改

现在我们已经进行了更改并调整了防火墙,我们可以重新启动Nginx来实现我们的新更改。

首先,我们应该检查以确保我们的文件中没有语法错误。 我们可以通过键入:

sudo nginx -t

如果一切都成功,你会得到一个如下所示的结果:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

如果您的输出与上述匹配,则您的配置文件没有语法错误。 我们可以安全地重新启动Nginx来实现我们的更改:

sudo systemctl restart nginx

现在,我们的加密TLS / SSL证书就位,防火墙现在允许流量到端口80和443.此时,您应该通过在网络浏览器中通过HTTPS访问您的域来测试TLS / SSL证书的工作原理。

您可以使用Qualys SSL实验室报告查看您的服务器配置分数:

https://www.ssllabs.com/ssltest/analyze.html?d=example.com

此SSL设置应报告的A +评级。

第6步:设置自动续订

让我们加密证书有效期为90天,但建议您每60天更新证书以允许有误差。 在写这篇文章的时候,自动续期还没有上市,作为客户端本身的功能,但您可以手动与运行咱们加密客户端更新您的证书renew选项。

要为所有已安装的域触发更新过程,请运行以下命令:

sudo letsencrypt renew

因为我们最近安装了证书,所以命令将只检查到期日期,并打印一条消息通知证书不是由于更新。 输出应该类似于:

Processing /etc/letsencrypt/renewal/example.com.conf

The following certs are not due for renewal yet:
  /etc/letsencrypt/live/example.com/fullchain.pem (skipped)
No renewals were attempted.

请注意,如果您创建了具有多个域的捆绑证书,则只有基本域名将显示在输出中,但续订应对此证书中包含的所有域有效。

确保您的证书不会过时的一个实用方法是创建一个定期执行自动更新命令的cron作业。 由于更新首先检查到期日期,并且仅当证书距离到期少于30天时才执行更新,因此可以安全地创建每周或甚至每天运行的cron作业。

让我们编辑crontab来创建一个新作业,它将每周运行续订命令。 要为root用户编辑crontab,请运行:

sudo crontab -e

添加以下行:

30 2 * * 1 /usr/bin/letsencrypt renew >> /var/log/le-renew.log
35 2 * * 1 /bin/systemctl reload nginx

保存并退出。 这将创建一个新的cron作业将执行letsencrypt-auto renew凌晨2:30命令每星期一,在上午02点35重装Nginx的(所以续订的证书将被使用)。 由命令生成的输出将通过管道输送到位于日志文件/var/log/le-renewal.log

有关如何创建和调度cron作业的更多信息,你可以检查我们如何使用cron来自动执行任务的VPS引导。

结论

而已! 您的网络服务器现在使用免费的Let's Encrypt TLS / SSL证书来安全地提供HTTPS内容。