Nginx是一个非常安全和可靠的Web服务器,即使使用默认设置。 然而,有很多方法来进一步保护Nginx。
在本文中,我们将专门使用开源软件,同时尝试遵循一些流行的Web服务器强化方法和安全标准。 也就是说,我们将讨论防止信息泄露,实施加密,执行审计和限制访问。
先决条件
在遵循本教程之前,请确保您满足以下先决条件:
Ubuntu的14.04Droplet(见( 与Ubuntu 14.04初始服务器设置的详细信息)
Nginx的网络服务器安装和配置在解释如何在Ubuntu 14.04 LTS Nginx的安装
注册域或子域指向Droplet的IP。 您将需要此来测试SSL设置。 欲了解更多信息,请阅读这篇文章如何指向DigitalOcean域名服务器从常见的域名注册商 。
非root用户Sudo(查看初始服务器设置与Ubuntu 14.04了解详细信息)
除非另有说明,本教程中需要root权限的所有命令都应以具有sudo权限的非root用户身份运行。
第1步 - 更新所有软件
将软件更新到最新版本是保护整个系统的重要一步,而不仅仅是Nginx。
警告:更新系统上的所有软件包之前,请确保这将导致系统上运行的任何Nginx以外的问题。 在执行影响这么多软件包的操作之前,最好对整个系统进行备份。 如果在更新所有软件包后出现问题,您可以还原到备份。 要更新管理信息库的软件包列表,然后所有已安装的软件包apt-get
你的Ubuntu服务器上运行的命令:
sudo apt-get update && sudo apt-get upgrade
或者,您可以只是升级Nginx到Ubuntu存储库中的最新版本。 这将升级Nginx软件包和任何必要的依赖:
sudo apt-get upgrade nginx
第2步 - 防止信息泄露
要开始强化Nginx Web服务器,让我们开始限制它公开的信息。 从HTTP服务器头到应用程序错误报告的每个级别都会泄露有价值的信息。
因此,让我们从HTTP头开始。 默认情况下,Nginx在HTTP头中显示其名称和版本。 您可以检查这些信息curl
是这样的:
curl -I http://localhost
输出应如下所示:
Output of curl -I http://localhostHTTP/1.1 200 OK
Server: nginx/1.4.6 (Ubuntu)
...
可以看到,Nginx的版本和操作系统的名称可以在上面的输出中看到。 这不一定是一个严重的问题,而是攻击者将尝试解决您的Nginx服务器的困惑的一部分。 这就是为什么我们会隐藏打开的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
您将看到更少的信息:
Output of curl -I http://localhostHTTP/1.1 200 OK
Server: nginx
...
以上输出仅公开这是Nginx服务器的事实。 你可能想知道你是否可以删除这个。 不幸的是,这不容易实现,因为没有配置选项。 相反,你将不得不从源代码重新编译Nginx是不值得的努力。
除了Server
头,没有与敏感信息的另一头- X-Powered-By
。 这个头通常显示PHP,Tomcat或者Nginx后面的任何服务器端引擎的版本。 如果你用PHP运行Nginx的输出curl
将是这样的:
Output of curl -I http://localhost on nginx with phpHTTP/1.1 200 OK
Server: nginx
...
X-Powered-By: PHP/5.5.9-1ubuntu4.14
...
以上X-Powered-By
标题显示该服务器是Ubuntu的14运行PHP版本5.5.9。 它隐藏在这些信息是非常重要X-Powered-By
头。 你不能这样做在Nginx,而是你应该在后端引擎中找到相应的选项。 例如,使用PHP的情况下,你要设置的选项expose_php = Off
主要在php.ini
的配置文件。 默认情况下,该选项设置为On
。
接下来要做的是更改4xx(客户端)错误页面,其中的信息可以被攻击者使用。 通常,这些都是Unauthorized 401
和Forbidden 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
以上提示为您提供了防止信息披露的想法 - 尽可能少地展示非必要的网络内容。 你应该隐藏服务和调试信息,不仅在Nginx,而且在后端引擎(PHP,Tomcat等),当然,在Web应用程序。
第2步 - 配置SSL
在Nginx上运行带有SSL的安全HTTPS协议是任何处理敏感信息(如用户的凭据,私人数据等)的站点必须的.SSL是确保无论你的站点用户在哪里以及什么互联网连接他们使用,他们收到和发送的信息将受到保护。
文章如何为Ubuntu 14.04上的Nginx创建一个SSL证书解释如何轻松地设置免费的电荷SSL与默认的HTTPS配置。 虽然本文是一个好的开始,它不会有效地保护您的数据。 现在,默认的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
此命令会向您询问有关您的网站和业务详情的几个简单问题。 之后,它会创建2048位RSA加密的文件密钥/etc/nginx/ssl/nginx.key
,并在文件中的SHA256证书/etc/nginx/ssl/nginx.crt
。
接下来,你将不得不产生较强,4096位长的DH参数 。 准备自己等待一段时间,根据您的Droplet,它可能需要30分钟。 运行命令:
sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 4096
现在您可以配置服务器块的SSL部分。 作为示例,让我们配置默认服务器块。 打开其配置文件以使用nano进行编辑:
sudo nano /etc/nginx/sites-enabled/default
在这个文件中,编辑服务器配置部分添加后部分SSL server_name
这样的指令:
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实验室 。 您应该忽略SSL不受信任的警告。 这是自然的,因为它是一个自签名证书。 请注意,此网站将只测试具有注册域名的网站。 您无法仅使用Droplet的IP地址测试SSL连接。
总的结果应该是“T”像“测试”,但本质上它是一个A(最高),它应该说"If trust issues are ignored: A"
是这样的:
稍后,您可能希望删除SSL警告,并使SSL测试为干净的“A”。 一种选择是使用咱们加密的文章中介绍如何使用让我们在Ubuntu 14.04加密安全Nginx的 。 它是免费的,允许您指定最大为4096的RSA密钥大小,并且不给出关于自签名的警告。 否则,您可以选择任何商业SSL提供程序。 当您选择一个时,请确保您选择了SHA256证书。
第3步 - 通过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.1
和10.0.0.1
您的IP地址。 同样,您可以通过更改网络掩码(允许其他IP,甚至网络接入/24
)。
要使这些设置生效,您将必须重新加载Nginx与命令:
sudo service nginx reload
现在,如果你尝试访问/wp-admin/
与浏览器允许的IP地址范围之外的网站的一部分,你会得到一个错误。 此错误将为403 Forbidden(除非您已将此错误更改为404未找到,如前所述)。 同时,您将在命令中看到错误日志中的真正错误代码:
sudo tail /var/log/nginx/error.log
在access forbidden
的错误会显示如下:
Output of sudo tail -f /var/log/nginx/error.log...
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的累积效应。 根据示例,而不是通常的WordPress管理页面,攻击者和他们使用的自动化工具将看到一个404未找到的页面。 这是混乱,可能会阻止他们尝试其他方法危及您的WordPress。
第4步 - 执行安全审核
总是一个好主意,安全检查独立于您自己的意见。 为此,您可以使用扫描Web漏洞的安全审核工具。 有很多这样的工具,包括商业的,一开始你可以使用的是自由和开源的wapiti。 Wapiti可能缺少更先进的工具的一些功能,但它会给你的安全审计的想法。
你可以在Ubuntu上通过apt安装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
从您已运行扫描目录内。 为了获得最佳的观看,这个目录下载到本地电脑,然后打开index.html
文件与Web浏览器。
在报告中,您将看到在10个不同类别中排序的漏洞:SQL注入,盲注入,文件处理,跨站点脚本,CRLF,命令执行,资源消耗,Htaccess Bypass,备份文件和潜在危险文件。
理想情况下,您的报告应该看起来像这样没有找到的漏洞:
如果有漏洞,可以展开相应的扫描部分获取更多信息。
确保频繁地运行此类扫描并使用不同的工具,以确保对Nginx和网站进行最完整和彻底的审核。
第5步 - 采取额外的安全措施
关于Nginx安全的一些主题不包括在本文中,因为已经有很好的文章。 请熟悉以下内容:
Naxsi是Nginx的一个Web应用程序防火墙。 它通过使用恶意签名的编译保护您从已知和未知的Web漏洞。
你应该知道Naxsi是一个复杂的软件,它的调整需要一些时间和努力。 幸运的是,对于大多数流行的Web应用程序,有可用的配置,您可以进一步自定义,如果需要。
Fail2ban是一个伟大的工具,将Web安全性提高到一个新的水平,并主动保护您的nginx服务器。 到目前为止,我们已限制用户查找某些信息和访问我们网站的部分。 使用fail2ban,您可以进一步阻止攻击者在某些时间段,当您检测到他们正在执行恶意活动。
监控对于安全是至关重要的,Monit是一个伟大的工具为此目的与良好的支持Nginx。 Web日志不仅会显示恶意活动的痕迹,而且还会显示CPU负载和内存使用量的峰值。
在本文中特别注意第5步 - 监视错误和关键字的日志。 您可以在此处配置自定义警报,以便在安全事件(例如有人访问或尝试访问您网站的敏感部分)时发送。
拥有防火墙对于您的nginx和整个Droplet的安全非常重要。 确保您将https(tcp 443)端口添加到允许的传入连接,除了标准的http(tcp 80)端口。
文件和目录完整性检查程序(如AIDE)会警告文件和目录中的更改。 这对于web文件特别方便,因为你应该注意你的网站的部分更改和添加新文件/目录。 要了解有关AIDE的更多信息,您可以从文章开始。
上面的文章有点过时,不是专门为Ubuntu编写的。 但是,你应该能够轻松地适应它,并应用于Ubuntu 14.04以及。 配置AIDE或其他类似工具时,请确保排除Web日志和临时文件(如Web缓存)不受监视。
结论
阅读这篇文章后,你应该对Nginx的安全感更有信心。 只需确保在功能和安全性之间寻求平衡,以便您放心,您的网络环境按照设计但安全运行。 另外,请记住,保护Nginx是一个持续的任务,需要定期更新,重新配置,扫描等。