如何在Debian 8上配置Nginx安全加密

Let\'s Encrypt是一个新的证书颁发机构(CA),它提供了一种简单的方法来获取和安装免费的TLS / SSL证书,从而在Web服务器上启用加密的HTTPS。它通过提供软件客户端certbot(以前称为letsencrypt)简化了过程,...

介绍

Let's Encrypt是一个新的证书颁发机构(CA),它提供了一种简单的方法来获取和安装免费的TLS / SSL证书,从而在Web服务器上启用加密的HTTPS。 它通过提供一个软件客户端,简化了工艺certbot (先前称为letsencrypt ),试图的所需的步骤大部分(如果不是全部)自动化。目前,获取和安装证书的整个过程仅在Apache Web服务器上完全自动化。但是,Let's Encrypt可以用于轻松获取免费的SSL证书,可以手动安装,无论您选择哪种Web服务器软件。 在本教程中,我们将向您展示如何使用Let's Encrypt获取一个免费的SSL证书,并在Debian 8上使用Nginx。我们还将向您展示如何自动更新您的SSL证书。如果您运行的是其他网络服务器,只需按照网络服务器的文档来了解如何在设置中使用证书。 Nginx与让我们加密TLS / SSL证书和自动更新

先决条件

在学习本教程之前,您需要一些东西。 你应该有谁拥有非root用户在Debian 8服务器sudo权限。 你可以学习如何按照我们建立这样一个用户帐户为Debian 8教程初始服务器设置 。 如果你还没有在服务器上安装的Nginx然而,按照这样做本指南 。 您必须拥有或控制您希望使用证书的注册域名。如果您还没有注册域名,您可以向其中一个域名注册商注册一个域名(例如Namecheap,GoDaddy等)。 如果你还没有准备好,一定要创建一条A记录指向你自己的域名服务器的公网IP地址(如果您使用的是DigitalOcean的DNS,你可以按照本指南 )。 这是必需的,因为Let's Encrypt验证您拥有它为其颁发证书的域。 例如,如果你想获得一个证书example.com ,该域必须解析到服务器的验证过程工作。 我们的安装程序将使用example.comwww.example.com作为域名,所以需要两个DNS记录 。 一旦你拥有所有的先决条件,让我们继续安装Let's Encrypt客户端软件。

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

第一步用咱们加密获得SSL证书是安装certbot您的服务器上让我们的加密客户端。 该certbot Debian 8 发布时包不可用。 要访问certbot包,我们必须使我们的服务器上的反向移植杰西库。此存储库可用于安装比稳定存储库中包含的更新版本的软件。 键入以下命令将backports存储库添加到服务器:
echo 'deb http://ftp.debian.org/debian jessie-backports main' | sudo tee /etc/apt/sources.list.d/backports.list
添加新的存储库后,更新apt包指数下载有关新包的信息:
sudo apt-get update
一旦存储的更新,您可以安装certbot通过针对backports中的库包: 注意:当使用反向移植,建议只安装您需要的特定的软件包,而不是使用存储库一般更新。与主存储库相比,Backport软件包的兼容性保证较少。 为了避免意外安装或使用该资料库的更新包,你必须明确地传递-t标志和存储库名称从backports中安装软件包。
sudo apt-get install certbot -t jessie-backports
certbot客户现在应该可以使用了。

第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: 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
现在我们知道我们的webroot-path ,我们可以使用Webroot公司的插件要求使用这些命令的SSL证书。 在这里,我们也与我们的指定域名-d选项。 如果你想有一个单一的证书与多个域名的工作(如example.comwww.example.com ),一定要包括所有的人。此外,请确保使用适当的webroot路径和域名替换突出显示的部分:
sudo certbot certonly -a webroot --webroot-path=/var/www/html -d example.com -d www.example.com
之后certbot初始化,将提示您输入一些信息。确切的提示可能会有所不同,具体取决于您以前是否使用过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 2017-03-14. 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安全,我们将利用这些建议Remi面包车埃尔斯特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之后,我们只需要包含我们设置了两个代码片段文件指令: 注意:您可能只有一个 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 default_server;
    listen [::]:443 ssl 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 default_server;
    listen [::]:443 ssl default_server;

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

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

第4步:调整防火墙

如果您启用了防火墙,则需要调整设置以允许SSL流量。所需的过程取决于您使用的防火墙软件。如果您当前没有配置防火墙,请随时跳过。

UFW

如果你正在使用UFW,可以看到通过键入当前设置:
sudo ufw status
它可能看起来像这样,这意味着只允许HTTP流量到Web服务器:
Status: active

To                         Action      From
--                         ------      ----
SSH                        ALLOW       Anywhere
WWW                        ALLOW       Anywhere
SSH (v6)                   ALLOW       Anywhere (v6)
WWW (v6)                   ALLOW       Anywhere (v6)
为了额外允许HTTPS流量,我们可以允许“WWW Full”配置文件,然后删除冗余的“WWW”配置文件容限:
sudo ufw allow 'WWW Full'
sudo ufw delete allow 'WWW'
您的状态现在应该如下所示:
sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
SSH                        ALLOW       Anywhere
WWW Full                   ALLOW       Anywhere
SSH (v6)                   ALLOW       Anywhere (v6)
WWW Full (v6)              ALLOW       Anywhere (v6)
您的服务器现在应该接受HTTPS请求。

IPTables

如果您在使用iptables ,你可以看到通过键入当前的规则:
sudo iptables -S
如果您启用了任何规则,则会显示它们。示例配置可能如下所示:
-P INPUT DROP
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
打开SSL流量所需的命令将取决于您当前的规则。对于像上面的基本规则集,您可以通过键入以下内容添加SSL访问权限:
sudo iptables -I INPUT -p tcp -m tcp --dport 443 -j ACCEPT
如果我们再次查看防火墙规则,我们应该看到新规则:
sudo iptables -S
-P INPUT DROP
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
如果您正在使用一个程序来自动应用iptables在开机的规则,你将要确保你的新规则更新配置。

第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 certbot renew
因为我们最近安装了证书,所以命令将只检查到期日期,并打印一条消息通知证书不是由于更新。输出应该类似于:
Saving debug log to /var/log/letsencrypt/example.com.log

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/example.com.conf
-------------------------------------------------------------------------------
Cert not yet due for renewal

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
如果这是使用你第一次crontab ,您可能会被要求选择您喜欢的文本编辑器。 如果你没有强烈的偏好, 纳米是一个容易的选择。 添加以下行:
30 2 * * 1 /usr/bin/certbot renew >> /var/log/le-renew.log
35 2 * * 1 /bin/systemctl reload nginx
保存并退出。这将创建一个新的cron作业将执行certbot renew凌晨2:30命令每星期一,在上午02点35分重装Nginx的(所以续订的证书将被使用)。 由命令生成的输出将通过管道输送到位于日志文件/var/log/le-renewal.log注意:有关如何创建和调度cron作业的更多信息,你可以检查我们如何使用cron来自动执行任务VPS引导。

结论

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