如何通过加密SSL证书保护Nginx

时间:2020-02-23 14:41:06  来源:igfitidea点击:

Let’s Encrypt是由Internet Security Research Group(ISRG)开创的免费,开源和自动证书颁发机构(CA),并提供SSL/TLS证书来加密涉及两方的通信。

上的SSL证书不仅可以通过加密来提高的安全性,而且可以提高的SEO排名,因为Google强制要求包含SSL证书以提高SEO排名。

在本文中,我们将探讨如何在Ubuntu 18.04中使用Let's Encrypt SSL证书保护NGINX服务器的安全。

前提条件

  • 您有权使用root用户或者使用启用了sudo的用户在Ubuntu 18.04服务器中打开SSH会话。

  • 您已经按照此处的教程安装了NGINX。

  • 注册域名。

  • DNS A记录,它根据您要使用的域名指向服务器的IP地址。

本教程要求使用域名。
每当您看到SUBDOMAIN,DOMAIN或者TLD变量时,请将它们替换为您自己的值。

安装Let's Encrypt客户端库

您需要完成的第一步是安装Let's Encrypt客户端库,该库将用于向LE授权请求证书。
一种方法是从服务器中的官方存储库中克隆Let's Encrypt客户端库。

也可以从Ubuntu的官方存储库安装相同的文件。
在Ubuntu的存储库中,客户端库被称为由Let's Encrypt开发人员提供的certbot。
但是,我们将选择前一种安装方法,即通过克隆Let's Encrypt的Github存储库。

为此,请导航到您选择的安装文件夹并克隆存储库。
我将安装文件夹选择为"/usr/local",您可以根据环境选择其他文件夹。

# apt-get install git
# cd /usr/local
# git clone https://github.com/letsencrypt/letsencrypt

转到letsencrypt文件夹,您会找到所有克隆的文件夹和文件,包括Let’s Encrypt 为您获取证书所需的certbot。

列表允许加密文件夹

配置"Let’s Encrypt "以验证您的域

在获取证书的过程中,"加密"客户端在" .well-known/acme-challenge"文件夹中创建一个临时文件。
该文件包含一个令牌,用于验证您实际拥有要为其获取证书的域的事实。
请记住,上述文件夹位于域的Web根目录下。

因此,"加密"必须可以访问临时文件以验证域。
要授予访问权限,您需要配置NGINX,因为它是域的Web根目录的所有者。
为文件夹" /..well-known/acme-challenge"添加一个专门的位置信息块,这将使"加密"可以放置用于域验证的令牌。
为此,请为您的虚拟主机编辑NGINX配置文件。
不要忘记根据您的环境调整根文件夹。

server {
          listen 80;
          server_name SUBDOMAIN.theitroad.com;
          root /var/www/html/wordpress;
          ...
          ...
          ...
          location /.well-known/acme-challenge {
             allow all; 
             default_type "text/plain";
          }
         ...
         ...
  }

验证配置文件在语法上是否正确,然后重新启动NGINX:

# nginx -t 
# systemctl restart nginx

配置UFW防火墙

Ubuntu 18.04附带了默认的防火墙管理器UFW,如果已启用它并且在服务器中运行,则不允许HTTP或者HTTPS连接访问NGINX服务器。

您也可能尝试在以前配置的服务器上安装证书,并且防火墙规则已经存在。
当然,在继续在Ubuntu 18.04服务器中启用HTTP和HTTPS连接之前,您可以在服务器中使用" ufw status"命令列出防火墙规则。

在终端中运行以下命令集,以允许服务器中的HTTP和HTTPS连接。

# ufw status
# ufw allow http
# ufw allow https
# ufw reload

要求Let’s Encrypt SSL证书

让我们使用之前克隆的"加密"客户端请求所选域的SSL证书。
尽管在请求证书时可以使用"加密"脚本使用很多配置选项,但我们仅使用以下选项。

  • certonly:此选项告诉letencrypt脚本仅获取SSL证书。
    稍后我们将手动进行NGINX的配置。

  • webroot:此选项指定在验证域名的过程中使用的webroot插件。

  • webroot-path:此选项设置域的根,必须指向您在NGINX配置中配置的位置。

  • 同意:表示同意Let's Encrypt的服务条款。

  • 电子邮件:该电子邮件用于接收来自Let's Encrypt的到期通知,但也可以用于恢复丢失的密钥。

  • d:此选项指定要为其请求证书的域名。

现在将上述选项与letencrypt客户端脚本结合在一起,使用以下命令来请求证书:

# cd /usr/local/letsencrypt
# ./letsencrypt-auto certonly --agree-tos --email [email protected] --webroot --webroot-path /var/www/html/wordpress -d SUBDOMAIN.theitroad.com

取得让我们成功加密证书

成功获取SSL证书后,Let’s Encrypt脚本将为您显示一条小提示,并且证书将存储在/etc/letsencrypt/live文件夹中。

配置NGINX以Let’s Encrypt SSL证书

目前,"加密"证书链已成功保存在您的服务器中。
现在继续为启用SSL的NGINX Web服务器配置虚拟主机文件。

生成Diffie-Hellman密钥

虽然在使用NGINX配置Let's Encrypt证书时可以选择使用Diffie-Hellman密钥,但是它主要用作安全地交换加密密钥以供Let's加密证书使用的方法。

# mkdir -p /etc/nginx/ssl
# cd /etc/nginx/ssl
# openssl dhparam -out /etc/nginx/ssl/dhparam.pem 4096

为了方便起见,我将DH参数文件放在了/etc/nginx/ssl目录中。
您可以将文件放置在其他位置。

配置SSL参数

接下来,在单独的文件中添加SSL连接的参数,例如协议版本,密码套件,会话,服务器应支持的标头。

这将建立一个强大的密码套件,并在可能的情况下启用正向保密。
此外,我们还将使HSTS和HPKP能够加强NGINX服务器的SSL连接。
这将使功能强大且具有前瞻性的SSL配置能够在Qualys Labs SSL测试中获得A +等级。

# vi /etc/nginx/conf.d/ssl.conf
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
server_tokens off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
#Online Certificate Status Protocol Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_session_tickets off;
#HTTP Strict Transport Security
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
ssl_trusted_certificate /etc/letsencrypt/live/SUBDOMAIN.theitroad.com/chain.pem;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
add_header X-Frame-Options DENY;
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options nosniff;
add_header X-Robots-Tag none;

编辑NGINX虚拟主机

最后,为您选择的域编辑NGINX服务器块。
导航到NGINX服务器块的默认位置/etc/nginx/sites-available并编辑NGINX虚拟主机文件。

# vi /etc/nginx/sites-available/your_nginx_file.conf

server {
       listen 80;
       listen [::]:80;
       server_name SUBDOMAIN.theitroad.com;
       return 301 https://$host$request_uri;
}
...
...

上面的服务器块指示NGINX侦听端口80中域" SUBDOMAIN.theitroad.com"的任何传入请求,并将其重定向到https部分,其配置如下。

...
...
server {
      listen 443 ssl http2;
      listen [::]:443 ssl http2;

      root   /var/www/html/wordpress;
      index index.html index.php index.htm;

      server_name  SUBDOMAIN.theitroad.com;
      error_log /var/log/nginx/SUBDOMAIN.theitroad.com-error.log debug;
      access_log /var/log/nginx/SUBDOMAIN.theitroad.com-access.log;

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

      include /etc/nginx/conf.d/ssl.conf;

      location /.well-known/acme-challenge {
             allow all;
             default_type "text/plain";
      }

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

      location = /favicon.ico {
              log_not_found off;
              access_log off;
      }

      location = /robots.txt {
              allow all;
              log_not_found off;
              access_log off;
      }

      location ~* \.(js|css|png|jpg|jpeg|gif|ico)${
              expires max;
              log_not_found off;
      }
}

检查配置文件中是否存在语法错误:

# nginx -t

要激活服务器块,请在"/etc/nginx/sites-enabled"文件夹中创建上述虚拟主机配置文件的符号链接。

# cd /etc/nginx/sites-enabled
# ln -s ../sites-available/your_nginx_file.conf .

重新加载NGINX以应用新设置:

# systemctl reload nginx

要分析上述SSL设置的配置,请将您的浏览器指向SSL Labs Test,然后输入您的域名,然后点击"提交"。
等待一分钟以查看测试摘要。
A +评级意味着,在保护NGINX服务器安全的过程中,我们包括了大多数SSL选项。

自动更新Let's Encrypt证书

Let's Encrypt证书的有效期为90天。
这样做的理由是为了限制关键妥协所造成的损害并鼓励自动化。

要自动执行证书更新过程,请使用crontab创建cronjob并添加一行脚本,该脚本每周执行一次,以在证书即将到期时进行更新。

# crontab -e
45 4 * * 6 cd /usr/local/letsencrypt/&& ./certbot-auto renew && systemctl restart nginx

上面的单行脚本将在每个星期六运行,以检查是否可以更新证书,如果可以,它将更新证书,然后重新启动NGINX服务器。

请注意,它尚未完全优化,因为即使证书没有续签,NGINX服务器也会重新启动。
最好的选择是编写一个自定义脚本来续订SSL证书,如果实际续订了证书,则重新启动NGINX服务器。