如何在Ubuntu 14.04上保护Nginx

即使使用默认设置,Nginx也是一个非常安全可靠的Web服务器。但是,有很多方法可以进一步保护Nginx。

在本文中,我们将专门使用开源软件,同时尝试遵循一些流行的Web服务器强化方法和安全标准。也就是说,我们将讨论防止信息泄露,实施加密,执行审计和限制访问。

准备

在学习本教程之前,请确保完成以下内容:

除非另有说明,否则本教程中需要root权限的所有命令都应作为具有sudo权限的非root用户运行。

第一步 - 更新所有软件

将软件更新到最新版本是保护整个系统的第一步,而不仅仅是Nginx。

警告:在更新系统上的所有软件包之前,请务必确定这是否会导致除Nginx之外的系统上运行的任何问题。在执行一次影响这么多包的操作之前,最好先备份整个系统。如果在更新所有软件包后出现问题,您可以恢复备份。要更新存储库软件包列表,然后用apt-get更新在Ubuntu服务器上管理的所有当前安装的软件包,请运行以下命令:

sudo apt-get update && sudo apt-get upgrade

或者,您可以将Nginx升级到Ubuntu存储库中的最新版本。这将升级Nginx包和任何必要的依赖项:

sudo apt-get upgrade nginx

第二步 - 防止信息泄露

要开始强化您的Nginx Web服务器,我们首先要限制它公开的信息。从HTTP服务器标头到应用程序错误报告的每个级别都泄露了有价值的信息。

所以让我们从HTTP标头开始。默认情况下,Nginx在HTTP标头中显示其名称和版本。你可以这样检查这些信息curl

curl -I http://localhost

输出应如下所示:

HTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
...

如您所见,在上面的输出中可以看到Nginx的版本和操作系统的名称。这不一定是一个严重的问题,而是攻击者试图解决以破坏您的Nginx服务器的难题的一部分。这就是为什么我们通过像这样用nano 打开Nginx的主配置文件/etc/nginx/nginx.conf来隐藏这些信息的原因:

sudo nano /etc/nginx/nginx.conf

然后,在http配置部分内添加server_tokens off;行:

http {
​
        ##
        # Basic Settings
        ##
        server_tokens off;
...

之后,保存并退出该文件,然后重新加载Nginx以使更改生效:

sudo service nginx reload

现在,如果再次尝试相同的curl命令:

curl -I http://localhost

您将看到更少的信息:

HTTP/1.1 200 OK
Server: nginx
...

以上输出仅公开了这是Nginx服务器的事实。你可能想知道你是否也可以删除它。不幸的是,这并不容易实现,因为它没有配置选项。相反,你将不得不从源代码重新编译Nginx,这是值得的。

除了Server标题之外,还有另一个包含敏感信息的标题 - X-Powered-By。此标头通常显示PHP,Tomcat或Nginx背后的任何服务器端引擎的版本。如果你用PHP运行Nginx,输出curl将如下所示:

HTTP/1.1 200 OK
Server: nginx
...
X-Powered-By: PHP/5.5.9-1ubuntu4.14
...

上面的X-Powered-By标题显示服务器是运行PHP版本5.5.9的Ubuntu 14。从X-Powered-By标题中隐藏此信息非常重要。你不能在Nginx中这样做,但你应该在后端引擎中找到相应的选项。例如,对于PHP的情况,您必须在主php.ini配置文件中设置该expose_php = Off选项。默认情况下,此选项设置为On

接下来要做的是更改4xx(客户端)错误页面,攻击者可以使用这些错误页面。通常,这些是Unauthorized 401Forbidden 403错误页面。除非您正在调试问题,否则通常不需要向常规访问者显示这些错误。如果您需要了解这些错误,您仍然可以在Nginx错误日志(/var/log/nginx/error.log)中找到它们。

要更改这两个错误页面,请打开服务器块的配置文件,例如默认值:

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

在主服务器server配置部分内指定:

server {
...
        error_page 401 403 404 /404.html;
...

将更改保存到文件后,请确保重新加载Nginx,以使其对命令生效:

sudo service nginx reload

以上提示为您提供了防止信息泄露的想法 - 尽可能少地显示非必要的Web内容。您不仅应该在Nginx中隐藏服务和调试信息,还应该在后端引擎(PHP,Tomcat等)中隐藏服务和调试信息,当然还应该隐藏在Web应用程序中。

第二步 - 配置SSL

在Nginx上运行带有SSL的安全HTTPS协议是处理敏感信息(如用户凭据,私人数据等)的任何站点必须的。SSL是确保无论您的站点用户位于何处以及Internet连接的唯一方法,他们使用,他们收到和发送的信息将受到保护。

虽然本文是一个良好的开端,但它无法有效保护您的数据。如今,默认的SSL设置和算法不够强大,无法阻止攻击者解密您的流量。

这就是为什么我们将使用更强大的加密算法和设置为Nginx配置SSL证书。这将确保为您的数据提供更高级别的保护,您的HTTPS服务将符合最高安全标准和实践。

让我们从使用以下命令为SSL证书创建目录开始:

sudo mkdir /etc/nginx/ssl/

对于我们的SSL,我们需要一个带有强签名算法SHA256的证书。出于测试目的或非生产环境,您可以使用自签名证书并忽略SSL警告。让我们用命令创建一个:

sudo openssl req -x509 -nodes -sha256 -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt

此命令将向您询问有关您的站点和业务详细信息的一些简单问题。之后,它将在/etc/nginx/ssl/nginx.key文件中创建一个2048位RSA加密密钥,并在该/etc/nginx/ssl/nginx.crt文件中创建一个SHA256证书。

接下来,您将必须生成更强,4096位长的DH参数。准备好等待一段时间,取决于你的CVM,它可能需要长达30分钟。运行命令:

sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 4096

现在,您可以配置服务器块的SSL部分。例如,让我们配置默认服务器块。使用nano进行编辑配置文件:

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

在此文件中,编辑服务器配置部分,在server_name指令之后添加SSL部分,如下所示:

server {
...
       server_name localhost;
​
        ### SSL Part
        listen 443 ssl;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
        ssl_prefer_server_ciphers on;
        ssl_dhparam /etc/nginx/ssl/dhparam.pem;
        ssl_certificate /etc/nginx/ssl/nginx.crt;
        ssl_certificate_key /etc/nginx/ssl/nginx.key;
​
...

以下是我们使用上述指令指定的指令:

  • listen - 在端口443上启用SSL侦听器,即HTTPS端口。
  • ssl_protocols- 仅启用这三个被认为是当前安全的协议 - TLSv1 TLSv1.1 TLSv1.2
  • ssl_ciphers - 仅启用这些安全SSL密码: EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
  • ssl_prefer_server_ciphers - 确保客户端尊重服务器的密码首选项。
  • ssl_dhparam - 使用我们之前生成的自定义强DH参数。
  • ssl_certificate - 使用我们的自签名SSL证书。如果您使用其他证书,请务必更改它。
  • ssl_certificate_key - 使用我们之前生成的SSL私钥。

要使上述设置生效,您必须使用以下命令重新加载nginx:

sudo service nginx reload

要测试新的SSL配置,最好使用外部工具,例如SSL Labs提供的工具。在那里你应该忽略SSL不受信任的警告。这很自然,因为它是一个自签名证书。请注意,此站点仅测试具有注册域名的站点。您无法仅使用CVM的IP地址测试SSL连接。

整体结果应该是“T”,就像“测试”一样,但基本上它是A(最高可能),它应该这样说"If trust issues are ignored: A"

稍后,您可能希望删除SSL警告并使SSL测试成为“A”。一种选择是使用** Let's Encrypt **,如在Ubuntu 14.04上如何使用Let's Encrypt来保护Nginx一文中所述。它是免费的,允许您指定最多4096的RSA密钥大小,并且不会发出有关自签名的警告。否则,您可以选择任何商业SSL提供商。当您选择一个时,请确保您选择SHA256证书。

第三步 - 通过IP限制访问

密码身份验证并不总是足以确保站点敏感区域的安全性,例如站点控制面板,phpmyadmin等。有时,攻击者利用这些区域中的弱密码或软件漏洞来获取未经授权的访问。这就是为什么强烈建议您添加额外的IP限制,前提是您可以确定合法用户的IP。

例如,如果您有一个WordPress站点并且其管理区域位于/wp-admin/,则应将其访问权限仅限于您的IP或所有管理员的IP。为此,打开相应的服务器块 - Nginx的默认服务器块是/etc/nginx/sites-enabled/default

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

server配置部分内添加:

server {
...
    location /wp-admin/ {
        allow 192.168.1.1/24;
     allow 10.0.0.1/24;
        deny  all;
}
...
...

在上面请确保更换192.168.1.110.0.0.1您的IP。同样,您可以通过更改网络掩码(/24)来允许访问其他IP甚至网络。

要使这些设置生效,您必须使用以下命令重新加载Nginx:

sudo service nginx reload

现在,如果您尝试使用/wp-admin/允许的IP地址范围之外的浏览器访问站点的某个部分,则会出现错误。此错误将为403 禁止页(除非您已将此错误更改为404未找到,如前所述)。同时,您将使用以下命令在错误日志中看到真正的错误代码:

sudo tail /var/log/nginx/error.log

access forbidden错误将表明这样的:

...
2016/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"
...

应用多种安全方法(例如更改错误页面和限制IP访问)的组合显示了强化Nginx的累积效果。根据示例,攻击者和他们使用的自动化工具将会看到404找不到的页面,而不是通常的WordPress管理页面。这很令人困惑,可能会阻止他们尝试其他方法来破坏你的WordPress。

第四步 - 执行安全审计

独立于您自己的意见进行安全检查始终是个好主意。为此,您可以使用安全审核工具来扫描Web漏洞。有许多这样的工具,包括商业工具,一开始你可以使用免费和开源的wapiti。Wapiti可能缺乏更高级工具的一些功能,但它会让您了解安全审核的内容。

你可以通过apt在Ubuntu上安装wapiti:

sudo apt-get install wapiti

然后使用以下命令开始使用wapiti扫描您的站点:

wapiti http://example.org -n 10 -b folder

请务必替换example.org为您网站的名称。我们给了命令两个额外的参数。第一个-n 10将具有相同模式的URL数限制为10,以防止无限循环。第二个参数-b folder仅将扫描范围设置为给定域。

扫描完成后,您将在您运行扫描的目录中调用的目录中generated_report结果。要获得最佳查看效果,请将此目录下载到本地计算机,然后使用Web浏览器打开该index.html文件。

在报告中,您将看到以10个不同类别排序的漏洞:SQL注入,盲SQL注入,文件处理,跨站点脚本,CRLF,命令执行,资源消耗,Htaccess绕过,备份文件和潜在危险文件。

理想情况下,您的报告应该如下所示,没有发现漏洞:

如果存在漏洞,则可以展开扫描的相应部分以获取更多信息。

确保经常使用不同的工具运行此类扫描,以确保对您的Nginx和网站进行最全面和最彻底的审核。

第五步 - 采取额外的安全措施

有关Nginx安全性的一些主题未在本文中介绍,因为已有关于它们的优秀文章。请熟悉以下内容:

Naxsi是Nginx的Web应用程序防火墙。它通过使用恶意签名的汇编来保护您免受已知和未知的Web漏洞的攻击。

您应该知道Naxsi是一个复杂的软件,它的调整需要一些时间和精力。幸运的是,大多数流行的Web应用程序都有现成的配置,您可以根据需要进一步自定义。

Fail2ban是一个很好的工具,可以将Web安全性提升到一个新的水平,并主动保护您的nginx服务器。到目前为止,我们限制用户查找某些信息并访问我们网站的部分内容。使用fail2ban,当您检测到攻击者正在执行恶意活动时,您可以进一步阻止攻击者。

监控对于安全至关重要,Monit是一个很好的工具,可以为Nginx提供良好的支持。Web日志不仅显示恶意活动的痕迹,而且还显示CPU负载和内存使用量的峰值。

在本文中,要特别注意第五步 - 监视错误和关键字的日志。在那里,您可以配置自定义警报,以便在安全事件发送时发送,例如当有人访问或尝试访问您站点的敏感部分时。

拥有防火墙对于nginx和整个CVM的安全性非常重要。确保将https(tcp 443)端口添加到标准http(tcp 80)端口之外的允许传入连接。

上面的文章有点过时,不是专门为Ubuntu编写的。但是,您应该能够轻松地对其进行调整并将其应用于Ubuntu 14.04。配置AIDE或其他类似工具时,请确保排除Web日志和临时文件(如Web缓存)的监视。

结论

阅读本文后,您应该对Nginx安全性更有信心。只需确保在功能和安全性之间寻求平衡,这样您就可以放心,您的Web环境按设计运行且安全可靠。另外,请记住,保护Nginx是一项持续性任务,需要定期更新,重新配置,扫描等。

想要了解更多关于Ubuntu的开源信息教程,请前往腾讯云+社区学习更多知识。

参考文献:《How To Secure Nginx on Ubuntu 14.04》

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏云计算教程系列

如何在Ubuntu 16.04上为用户目录设置vsftpd

FTP是文件传输协议的缩写,是一种曾经广泛用于在客户端和服务器之间移动文件的网络协议。它已被更快,更安全,更方便的文件传输方式所取代。许多休闲网民希望直接用ht...

2450
来自专栏西安-晁州

TortoiseGit记住用户名&密码

配置并安装好git之后鼠标右键: ? ? 在全局配置文件末尾添加一行: [credential]       helper = store *主意保存时以utf...

2370
来自专栏网络

一步步带你了解前后端分离利器之JWT

一、HTTP的无状态性 HTTP 是无状态协议,它不对之前发送过的请求和响应的状态进行管理。也就是说,无法根据之前的状态进行本次的请求处理。假设要求登录认证的 ...

3285
来自专栏云计算

Kubernetes的服务网格(第3部分):对通信进行加密

在本文中,我们将展示如何在不修改当前应用代码的前提下来为所有的服务到服务的(service-to-service) HTTP 调用提供 TLS 支持。

4038
来自专栏Kirito的技术分享

八幅漫画理解使用JSON Web Token设计单点登录系统

博主前言 这篇转载的文章和上一篇《JSON Web Token - 在Web应用间安全地传递信息》文章均为转载,是我个人在研究 jwt 时浏览下来发现的两篇质...

3585
来自专栏云知识学习

如何让服务端同时支持WebSocket和SSL加密的WebSocket

要服务端同时支持ws与wss并不容易,其难点主要在于:wss通道必须在TCP连接刚建立时(收发消息前)就要先进行SSL加密,否则,后续的通信将无法正常进行。如此...

50318
来自专栏云计算教程系列

使用Debian 8进行初始服务器设置

当您第一次创建新的Debian 8服务器时,您应该尽早采取一些配置步骤作为基本设置的一部分。这将提高服务器的安全性和可用性,并为后续操作奠定坚实的基础。

2411
来自专栏优启梦

emlog后台登录失败邮件通知

前面说到emlog后台登录参数加密,下面我们说说如何给emlog添加后台登录失败邮件通知的功能,本次我们需要用到mail函数,当然也就是需要25端口发信,如果是...

64812
来自专栏编程

App与后台通信:从文本协议到二进制协议

本文主要总结了心悦俱乐部 App 的接入层从文本协议到二进制 jce 协议迭代过程中的技术方案。

1.6K10
来自专栏康怀帅的专栏

Let's Encrypt SSL 证书配置详解

首先确保你的网站是可以访问的( nginx 配置好 80 端口),申请证书时 let's Encrypt 会访问网站上的某一文件来确认网站归属(当然也可以通过 ...

4994

扫码关注云+社区

领取腾讯云代金券