Nginx 是一个非常安全和可靠的 Web 服务器,即使是默认设置,但还有很多方法可以进一步保护 Nginx。
在本文中,我们将专门使用开源软件,同时尝试遵循一些流行的Web服务器硬化方法和安全标准,即,我们将讨论防止信息披露,执行加密,执行审计和限制访问。
前提条件
在遵循本教程之前,请确保您完成以下先决条件:
- Ubuntu 14.04 Droplet (参见初始服务器设置与 Ubuntu 14.04详细信息)
- Nginx Web 服务器已安装和配置,如在 如何在 Ubuntu 14.04 LTS 上安装 Nginx所解释的那样)
- 注册的域名或子域名指向 Droplet 的 IP。 您将需要这个来测试 SSL 设置。 有关更多信息,请阅读本文在 如何从常用域名注册器中点击 DigitalOcean Nameservers。
- 非根源的 sudo 用户(详细信息请参阅 初始服务器设置与 Ubuntu 14.04 ])
除非另有说明,本教程中需要 root 特权的所有命令都应该作为具有 sudo 特权的非 root 用户运行。
步骤 1 - 更新所有软件
将软件更新到最新版本是确保整个系统安全的第一步,不仅仅是 Nginx。
警告:在更新您的系统上的所有软件包之前,请确保确定是否会导致在您的系统上运行的 Nginx 以外的任何东西出现问题。在执行一次影响这么多软件包的操作之前,最好先备份整个系统。如果在更新所有软件包后出现问题,您可以重返备份。
1sudo apt-get update && sudo apt-get upgrade
或者,您可以将 Nginx 升级到 Ubuntu 存储库中的最新版本,这将升级 Nginx 包和任何必要的依赖:
1sudo apt-get upgrade nginx
第2步:防止信息泄露
要开始硬化您的 Nginx 网页服务器,让我们开始限制它披露的信息,从 HTTP 服务器头到应用程序错误报告的每个级别都泄露有价值的信息。
因此,让我们从 HTTP 标题开始吧. 默认情况下, Nginx 在 HTTP 标题中显示其名称和版本。
1curl -I http://localhost
产量应该看起来像:
1[secondary_label Output of curl -I http://localhost]
2HTTP/1.1 200 OK
3Server: nginx/1.4.6 (Ubuntu)
4...
正如你所看到的, Nginx 版本和操作系统的名称可以在上面的输出中看到. 这不一定是一个严重的问题,而是攻击者将试图解决的难题的一部分,以破坏您的 Nginx 服务器。
1sudo nano /etc/nginx/nginx.conf
然后,在http
配置部分中,像这样添加server_tokens off
;
1[label /etc/nginx/nginx.conf]
2http {
3
4 ##
5 # Basic Settings
6 ##
7 server_tokens off;
8...
之后,保存并退出文件,并重新加载 Nginx,以便更改生效:
1sudo service nginx reload
现在,如果您再次尝试相同的 curl 命令:
1curl -I http://localhost
你会看到更少的信息:
1[secondary_label Output of curl -I http://localhost]
2HTTP/1.1 200 OK
3Server: nginx
4...
上面的输出只揭示了这是一个 Nginx 服务器的事实。你可能会想知道你是否可以删除这个。不幸的是,这并不容易实现,因为没有任何配置选项。
除了服务器
标题,还有另一个具有敏感信息的标题,即X-Powered-By
。这个标题通常显示 PHP、Tomcat 或 Nginx 背后的任何服务器端引擎版本。
1[secondary_label Output of curl -I http://localhost on nginx with php]
2HTTP/1.1 200 OK
3Server: nginx
4...
5X-Powered-By: PHP/5.5.9-1ubuntu4.14
6...
上面的X-Powered-By
标题表明服务器是Ubuntu 14运行PHP版本 5.5.9 非常重要的是要从X-Powered-By
标题中隐藏这些信息。你不能在 Nginx 中做到这一点,但应该在后端引擎中找到相应的选项。例如,在PHP的情况下,你必须在主要的php.ini
配置文件中设置expose_php = Off
选项。默认情况下,此选项设置为On
。
接下来要做的是更改4xx(客户端)错误页面,这些错误页面可以被攻击者使用。 通常,这些是未经授权的401
和禁止的403
错误页面。 除非您正在纠正问题,通常不需要向常客显示这些错误。 如果您需要了解这些错误,您仍然可以在Nginx错误日志中找到它们(`/var/log/nginx/error.log)。
若要更改这两个错误页面,请打开服务器块的配置文件,例如默认文件:
1sudo nano /etc/nginx/sites-enabled/default
在主服务器服务器
配置部分中,指定:
1[label /etc/nginx/sites-enabled/default]
2server {
3...
4 error_page 401 403 404 /404.html;
5...
保存文件的更改后,请确保重新加载 Nginx,以便它与命令生效:
1sudo service nginx reload
上面的提示给了你防止信息披露的想法 - 显示尽可能少的非必不可少的网页内容. 你应该隐藏服务和调试信息,不仅在 Nginx,而且在后端引擎(PHP,Tomcat等)和,当然,在Web应用程序。
第2步:配置SSL
在 Nginx 上运行安全的 HTTPS 协议与 SSL 是处理用户身份证、私人数据等敏感信息的任何网站的必需品 SSL 是确保无论您的网站用户在哪里以及他们使用的互联网连接,他们接收和发送的信息都将受到保护的唯一手段。
文章 How To Create an SSL Certificate on Nginx for Ubuntu 14.04解释了如何轻松地设置免费的 SSL 与默认 HTTPS 配置. 虽然本文是一个很好的开始,但它不会有效地保护您的数据。
这就是为什么我们将为 Nginx 配置一个具有更强的加密算法和设置的 SSL 证书,这将确保您的数据更高水平的保护,您的 HTTPS 服务将符合最高的安全标准和实践。
让我们开始使用命令创建我们的SSL证书目录:
1sudo mkdir /etc/nginx/ssl/
对于我们的SSL,我们需要一个具有强大的签名算法的证书,SHA256. 对于测试或非生产环境,您可以使用自签证并忽略SSL警告。
1sudo openssl req -x509 -nodes -sha256 -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt
此命令会问你几个简单的问题,有关你的网站和业务的细节,然后它将创建一个 2048 位 RSA 加密密钥在文件 /etc/nginx/ssl/nginx.key
和一个 SHA256 证书在文件 /etc/nginx/ssl/nginx.crt
。
接下来,您将需要生成更强大的,4096位长的DH参数(https://wiki.openssl.org/index.php/Diffie-Hellman_parameters)。准备好等待一段时间,取决于您的Droplet,可能需要长达30分钟。
1sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 4096
现在你可以配置你的服务器块的SSL部分。作为一个例子,让我们配置默认的服务器块。
1sudo nano /etc/nginx/sites-enabled/default
在此文件中,编辑服务器配置部分,在server_name
指令后添加SSL部分,如下:
1[label /etc/nginx/sites-enabled/default]
2server {
3...
4 server_name localhost;
5
6 ### SSL Part
7 listen 443 ssl;
8 ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
9 ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
10 ssl_prefer_server_ciphers on;
11 ssl_dhparam /etc/nginx/ssl/dhparam.pem;
12 ssl_certificate /etc/nginx/ssl/nginx.crt;
13 ssl_certificate_key /etc/nginx/ssl/nginx.key;
14
15...
以下是我们与上述指令所规定的指令:
只启用以下三种被认为是安全的协议:TLSv1 TLSv1.1 TLSv1.2
- ssl_ciphers - 确保客户端尊重服务器的加密偏好:EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
- ssl_prefer_server_ciphers - 确保客户端尊重服务器的加密偏好。
要使上述设置生效,您需要用命令重新加载 nginx:
1sudo service nginx reload
要测试你的新的SSL配置,最好使用外部工具,例如由SSL Labs提供的工具(https://www.ssllabs.com/ssltest/analyze.html)。在那里,你应该忽视警告,SSL不值得信任。这很自然,因为它是一个自签证书。 请注意,这个网站只会测试具有注册域名的网站。 您不能只使用您的Droplet的IP地址来测试SSL连接。
总体结果应该是T
,就像测试
一样,但基本上它是一个A(最高的可能),它应该说如果信任问题被忽视:A
如下:
後來,你可能想刪除SSL警告,並使SSL測試清潔A
。 一個選項是使用 Let's Encrypt,如在文章中所描述的 How To Secure Nginx with Let's Encrypt on Ubuntu 14.04)。 它是免費的,允許你指定RSA鑰匙大小高達4096,並且不會發出警告關於自我簽署。 否則,你可以選擇任何商業SSL提供商在那裡。
步骤 3 – 限制 IP 访问
密码验证并不总是足以确保您网站的敏感区域的安全性,如网站控制面板,phpmyadmin等有时攻击者会利用这些区域的弱密码或软件漏洞,以获得未经授权的访问。
例如,如果您有一个WordPress网站,其管理区域在/wp-admin/
,您应该将访问权限限制在您的IP或所有管理员的IP上。 为此,打开相应的服务器块 - Nginx的默认服务器块为/etc/nginx/sites-enabled/default
:
1sudo nano /etc/nginx/sites-enabled/default
在服务器
配置部分中添加:
1[label /etc/nginx/sites-enabled/default]
2server {
3...
4 location /wp-admin/ {
5 allow 192.168.1.1/24;
6 allow 10.0.0.1/24;
7 deny all;
8}
9...
10...
在上述情况下,请确保用您的IP代替192.168.1.1
和10.0.0.1
。
要使此类设置生效,您需要使用以下命令重新加载 Nginx:
1sudo service nginx reload
现在,如果您尝试使用在允许的 IP 地址范围之外的浏览器访问网站的 /wp-admin/
部分,您将收到错误. 此错误将是 403 禁止(除非您已将此错误更改为 404 未找到,如前所述)。
1sudo tail /var/log/nginx/error.log
禁用
错误将显示如下:
1[secondary_label Output of sudo tail -f /var/log/nginx/error.log]
2...
32016/01/02 04:16:12 [error] 4767#0: *13 access forbidden by rule, client: X.X.X.X, server: localhost, request: "GET /wp-admin/ HTTP/1.1", host: "Y.Y.Y.Y"
4...
应用多个安全方法的组合,例如更改错误页面和限制IP访问,显示了硬化Nginx的累积效应. 例如,而不是通常的WordPress管理页面,攻击者和他们使用的自动工具将看到一个404未找到的页面。
步骤4:进行安全审计
它总是是一个好主意,有一个安全检查独立于自己的意见. 为此,你可以使用一个安全审计工具,该工具扫描网络漏洞. 有许多这样的工具,包括商业工具,并开始,你可以使用wapiti,这是免费的和开源的。
您可以通过 apt 在 Ubuntu 上安装 wapiti:
1sudo apt-get install wapiti
然后开始用 wapiti 扫描您的网站,使用命令:
1wapiti http://example.org -n 10 -b folder
请确保将example.org
替换为您的网站名称,我们已为该命令添加了两个额外的参数。第一个-n 10
限制了具有相同模式的 URL 的数量为 10,以防止无尽的循环。
扫描完成后,你将有结果在名为generated_report
的目录中,在你运行扫描的目录中。
在报告中,您将看到分为 10 个不同的类别的漏洞:SQL Injection、Blind SQL Injection、File Handling、Cross Site Scripting、CRLF、命令执行、资源消耗、Htaccess Bypass、备份文件和潜在危险文件。
理想情况下,你的报告应该是这样的,没有发现任何漏洞:
如果存在漏洞,您可以扩展扫描的相应部分以获取更多信息。
请确保频繁运行此类扫描,并使用不同的工具,以确保对您的 Nginx 和网站进行最完整和彻底的审计。
步骤5:采取额外的安全措施
关于 Nginx 安全的一些话题在本文中没有涵盖,因为已经有很好的文章。
- [如何在Ubuntu 14.04上安装和配置Naxsi(https://andsky.com/tech/tutorials/how-to-install-and-configure-naxsi-on-ubuntu-14-04)
Naxsi 是 Nginx 的 Web 应用程序防火墙,它通过使用一组恶意签名来保护您免受已知和未知的 Web 漏洞。
你应该知道Naxsi是一个复杂的软件,它的调整需要一些时间和精力,幸运的是,对于大多数流行的Web应用程序,您可以在需要时进一步定制。
[如何在 Ubuntu 14.04 上使用 Fail2Ban 保护 Nginx 服务器]
Fail2ban 是一个很好的工具,可以将网络安全提升到一个新的水平,并主动保护您的 nginx 服务器. 到目前为止,我们已经限制用户找到某些信息并访问我们的网站部分。
监控对安全至关重要,而Monit是为此目的的一个很好的工具,对Nginx的支持很好,Web日志不仅显示了恶意活动的痕迹,而且还显示了CPU负载和内存使用的峰值。
在本文中,特别注意步骤5 - 监控错误和关键字日志. 在那里,您可以配置自定义警报,以便在安全事件时发送,例如当有人访问或尝试访问您的网站(s)的敏感部分。
- [如何在Ubuntu 14.04上使用Iptables设置防火墙(LINK0)
拥有防火墙对于您的 nginx 和整个 droplet 的安全性非常重要,请确保您除了标准 http (tcp 80) 端口之外,还将 https (tcp 443) 端口添加到允许的入口连接中。
文件和目录完整性检查器,如AIDE,通知文件和目录的更改. 这对于Web文件尤其有用,因为您应该知道网站的部分更改和新文件 / 目录被添加时。
上面的文章有点过时,并非专门为Ubuntu撰写。然而,你应该能够轻松地适应它并应用于Ubuntu 14.04。当你配置AIDE或其他类似的工具时,请确保你的Web日志和临时文件(如Web缓存)不受监控。
结论
阅读本文后,您应该对 Nginx 安全性感到更有信心. 只要确保在功能和安全性之间找到平衡,这样您就可以放心,您的 Web 环境是设计而安全的。