NGINX基准-基础配置
目录
1基本配置... 3
1.1最小化NGINX模块... 3
1.1.1确保仅安装必需的模块... 3
1.1.2确保未安装HTTP WebDAV模块... 3
1.1.3确保禁用具有gzip功能的模块... 4
1.1.4确保自动索引模块已禁用... 5
1.2账号安全... 6
1.2.1确保使用非特权专用服务帐户运行NGINX. 6
1.2.2确保NGINX服务帐户被锁定... 7
1.2.3确保NGINX服务帐户有一个无效的shell. 8
1.3权限和所有权... 8
1.3.1确保NGINX目录和文件归root用户所有... 8
1.3.2确保对NGINX目录和文件的访问受到限制... 9
1.3.3确保NGINX进程ID (PID)文件是安全的... 9
1.3.4确保核心转储目录是安全的... 10
1.4网络配置... 11
1.4.1确保NGINX只监听授权端口上的网络连接... 11
1.4.2确保拒绝未知主机名的请求... 12
1.4.3确保keepalive_timeout为10秒或更少,但不是0. 13
1.4.4确保send_timeout设置为10秒或更少,但不是0. 13
1.5信息泄露... 14
1.5.1确保server_token指令设置为' off '. 14
1.5.2确保默认错误和index.html页面不涉及NGINX. 15
1.5.3确保隐藏文件服务被禁用... 15
1.5.4确保NGINX反向代理不允许信息泄露... 16
1基本配置
1.1最小化NGINX模块
1.1.1确保仅安装必需的模块
描述:
NGINX安装带有几个现成的模块。 这些模块不是所有总是需要的,应确保NGINX安装的是必要的模块。
理由:
最小化NGINX内置的功能可以帮助减少服务器中的漏洞数量,从而减少攻击者成功入侵的可能性。
审计:
使用nginx验证命令审核当前NGINX构建中使用的模块:
nginx –V
修复:
请查阅NGINX模块文档,以确定特定安装所需的模块。
可以使用configure命令删除模块。
参考文献:
1. http://nginx.org/en/docs/configure.html
笔记:
NGINX不支持使用yum安装方法删除模块。 为了从NGINX中删除模块,您需要从源代码编译它。
1.1.2确保未安装HTTP WebDAV模块
描述:
http_dav_module启用RFC 4918定义的用于Web分布式创作和版本控制(WebDAV)的HTTP扩展。这可以在Web服务器上启用基于文件的操作,例如在服务器上创建,删除,更改和移动文件的功能。大多数现代体系结构已将这种功能替换为基于云的对象存储,在这种情况下,不应安装该模块。
理由:
WebDAV功能为利用Web服务器开辟了一条不必要的途径。通过WebDAV操作的错误配置,攻击者可能能够访问和操纵服务器上的文件。
审计:
运行以下命令以确保未安装http_dav_module:
nginx -V 2>&1 | grep http_dav_module
确保命令输出为空。
修复:
要删除http_dav_module,请从源代码重新编译nginx而不使用--withhttp_dav_module标志。
默认值:
从源代码安装时,默认情况下未安装HTTP WebDAV模块。 使用yum安装时,默认情况下它确实存在。
参考文献:
1. http://nginx.org/en/docs/configure.html
2. https://tools.ietf.org/html/rfc4918
笔记:
NGINX不支持使用yum安装方法删除模块。 为了从NGINX中删除模块,您需要从源代码进行编译。
1.1.3确保禁用具有gzip功能的模块
描述:
gzip用于压缩。 应该禁用压缩功能,以防止成功执行某些类型的攻击。
理由:
压缩与Breach攻击和其他攻击有关。虽然已经通过HTTP协议的现代用法减轻了Breach攻击,但是禁用压缩的使用被认为是减轻其他攻击的深度防御策略。
审计:
运行以下命令以确保未安装gzip模块:
nginx -V | grep 'http_gzip_module\|http_gzip_static_module'
确保命令输出为空。
修复:
为了禁用http_gzip_module,必须从源代码重新编译nginx。 可以在原始编译过程中使用的文件夹中使用以下命令来完成此操作。 必须在没有--with-http_gzip_static_module配置指令的情况下完成此操作。
./configure --without-http_gzip_module
默认值:
默认情况下,源版本中已启用http_gzip_module,而未启用http_gzip_static_module。 两者在yum包中默认启用。
参考文献:
1. http://nginx.org/en/docs/configure.html
2. http://nginx.org/en/docs/configure.html
1.1.4确保自动索引模块已禁用
描述:
自动索引模块处理以斜杠字符结尾的请求。 此功能启用目录列表,这在攻击者侦察中可能很有用,因此应禁用它。
理由:
自动化的目录列表可能会泄露有助于攻击者的信息,例如命名约定和目录路径。 目录列表也可能会泄露不希望泄露的文件。
审计:
要确定是否禁用了自动索引模块,请在NGINX配置文件(nginx.conf和任何包含的配置文件)中搜索自动索引指令:
egrep -i '^\s*autoindex\s+' /etc/nginx/nginx.conf
egrep -i '^\s*autoindex\s+' /etc/nginx/conf.d/*
确保在指令上不存在自动索引。
修复:
执行以下操作禁用自动索引模块:
搜索NGINX配置文件(nginx.conf和任何包含的配置文件)以查找自动索引指令。
egrep -i '^\s*autoindex\s+' /etc/nginx/nginx.conf
egrep -i '^\s*autoindex\s+' /etc/nginx/conf.d/*
将所有自动索引指令的值设置为off,或删除这些指令。
默认值:
默认情况下不启用此模块。
参考文献:
http://nginx.org/en/docs/http/ngx_http_autoindex_module.html
1.2账号安全
1.2.1确保使用非特权专用服务帐户运行NGINX
描述:
nginx用户指令指定nginx工作进程在哪个用户帐户下运行。确保使用无特权的专用服务帐户是一种深度防御措施,以限制对帐户进行破坏的攻击者所能做的事情。
理由:
在非特权专用服务帐户下运行web服务器有助于在运行web服务的用户帐户受到损害时,降低向其他服务或流程横向移动的风险。缺省用户nobody通常用于多个进程,如果这一点被破坏,则可能允许攻击者访问作为该用户运行的所有进程。
审计:
运行以下程序来验证nginx是否由一个专用的非特权用户帐户运行:
步骤1:验证nginx正在作为一个专用用户运行:
grep "user[^;]*;" /etc/nginx/nginx.conf
如果没有找到类似于下面的用户指令,这不是一个专用用户。如果发现用户与下面显示的输出相似,请继续执行步骤2。如果用户不存在,则需要添加一个用户。
user nginx;
步骤2:验证nginx专用用户没有特权:
运行以下命令,将nginx替换为您可能分配的任何指定用户:
sudo -l -U nginx
如果这个用户没有特权,输出应该如下面所示:
sudo -l -U nginx
User nginx is not allowed to run sudo
步骤3:验证nginx专用用户不属于任何意外组:运行以下命令,将nginx替换为您可能已分配的任何指定用户:
groups nginx
如果该用户不属于除主组之外的任何其他组,则输出应该类似于下面的内容:
nginx : nginx
修复:
为nginx用户添加一个系统帐户,主目录为/var/cache/nginx,shell为/sbin/nologin,这样nginx就不能登录了,然后添加nginx用户,由nginx使用:
user add nginx -r -g nginx -d /var/cache/nginx -s /sbin/nologin
然后通过添加user指令将nginx用户添加到/etc/nginx/nginx.conf中,如下所示:
user nginx;
默认值:
默认情况下,如果nginx是从源代码编译的,那么用户和组都是nobody。如果从yum下载,用户和组nginx以及帐户都没有特权。
参考:
http://nginx.org/en/docs/ngx_core_module.html#user
1.2.2确保NGINX服务帐户被锁定
描述:
nginx用户帐户应该有一个有效的密码,但是该帐户应该被锁定。注意:如果使用不同的帐户运行nginx,在审计和补救过程中,该帐户的名称应该替换为nginx。
理由:
作为深入防御措施,nginx用户帐户应该被锁定,以防止登录,并防止有人使用密码将用户切换到nginx。一般来说,任何人都不需要使用su作为nginx,当需要时,应该使用sudo,不需要nginx账户密码。
审计:
验证nginx服务帐户是锁定运行这个命令:
passwd -S nginx
结果应类似于以下其中之一:
nginx LK 2010-01-28 0 99999 7 -1 (Password locked.)
或者
nginx L 07/02/2012 -1 -1 -1 -1
修复:
使用passwd命令锁定nginx服务帐户:
passwd -l nginx
影响:
这将确保nginx用户帐户不会被人类用户使用。
默认值:
nginx用户在默认情况下是锁定的。
1.2.3确保NGINX服务帐户有一个无效的shell
描述:
nginx帐户不应该用来登录,所以应该为该帐户设置/sbin/nologin shell。
理由:
用于nginx的帐户应该只用于nginx服务,不需要有登录的能力。这可以防止攻击者破坏帐户来登录。
审计:
使用以下命令验证/etc/passwd文件中的nginx登录帐户shell:
grep nginx /etc/passwd
shell必须是/sbin/nologin,类似于下面显示的示例输出:
nginx:x:997:994:nginx user:/var/cache/nginx:/sbin/nologin
修复:
使用以下命令将nginx帐户的登录shell更改为/sbin/nologin:
chsh -s /sbin/nologin nginx
默认值:
nginx用户的默认shell是/sbin/nologin。
1.3权限和所有权
1.3.1确保NGINX目录和文件归root用户所有
描述:
/etc/nginx目录及其文件的所有者和组应该是根目录。
理由:
仅将所有权设置为根组中的那些用户和root用户将减少对nginx配置文件进行未经授权的修改的可能性。
审计:
运行以下命令来验证nginx配置文件的所有权:
stat /etc/nginx
输出应该显示所有权和组作为root,类似于下面的输出:
Access: (0755/drwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
修复:
运行以下命令以确保所有权和组所有权设置为root:
chown -R root:root /etc/nginx
默认值:
nginx的默认所有权和组是root。
1.3.2确保对NGINX目录和文件的访问受到限制
描述:
/etc/nginx目录上的权限应该执行最小权限原则。
理由:
这确保只有需要访问配置文件的用户才能查看配置文件,从而防止未经授权的访问。其他用户需要使用sudo来访问这些文件。
审计:
要验证nginx目录已撤销了其他读和执行权限,请运行以下命令查看权限:
find /etc/nginx -type d | xargs ls –ld
输出应显示与以下输出类似的权限:
drwxr-x---. 4 root root 188 Nov 28 23:22 /etc/nginx
要验证nginx配置文件是否有其他已撤销的读取和执行权限,请运行以下命令查看权限:
find /etc/nginx -type f | xargs ls –l
输出应该显示类似于下面的输出权限:
-rw-r-----. 1 root root 2192 Nov 11 2017 /etc/nginx/nginx.conf
修复:
要将权限设置为nginx配置文件的最低权限,请发出以下命令:
find /etc/nginx -type d | xargs chmod 750
find /etc/nginx -type f | xargs chmod 640
默认值:
权限被设置为默认的读取方式:- rwr –r—r—
参考:
https://dev-sec.io/baselines/nginx/
1.3.3确保NGINX进程ID (PID)文件是安全的
描述:
PID文件存储nginx进程的主进程ID。这个文件应该受到保护,以防未经授权的修改。
理由:
PID文件应该由根和组根拥有。它也应该对每个人都是可读的,但只能由根用户写(权限644)。这将防止未经授权的修改PID文件,这可能导致拒绝服务。
审计:
运行这个命令来验证nginx PID文件的所有权和权限:
ls -l /var/run/nginx.pid
输出应该显示PID文件属于根用户,并且具有组根用户,如下所示。
-rw-r--r--. 1 root root 6 Nov 12 01:06 /var/run/nginx.pid
如果这不是PID文件的位置,可以使用以下命令的输出找到PID文件的位置:
nginx –V
修复:
如果PID文件不属于root用户,则发出以下命令:
chown root:root /var/run/nginx.pid
如果PID文件的权限大于644,则发出以下命令:
chown 644 /var/run/nginx.pid
默认值:
默认情况下,PID文件归根用户所有。
1.3.4确保核心转储目录是安全的
描述:
核心转储是内存的快照。working_directorydirective用于指定NGINX试图在其中创建核心转储的目录。如果NGINX用户无法写入目录,则禁用核心转储。建议将working_directory指令设置为根用户拥有的目录和NGINX进程执行的组,其他用户不能访问该目录。通常,生产系统不应该启用此功能。
理由:
核心转储可能包含系统上的其他帐户不能访问的敏感信息。
审计:
运行以下步骤来验证核心转储配置是否安全:
步骤1:检查working_directory指令是否已配置:
grep working_directory /etc/nginx/nginx.conf
步骤2:如果激活了working_directory指令,则需要满足以下要求:
1. 它不在NGINX web文档根目录中。
2. 它由root拥有,并且拥有NGINX组的组所有权。
3.它没有其他用户的读写搜索访问权限(例如o=rwx)。
修复:
从NGINX配置文件中删除working_directory指令,或者确保配置的目录满足以下要求:
它不在NGINX web文档根目录中。
它由根用户所有,并拥有NGINX组的组所有权:
chown root:nginx /var/log/nginx
其他用户没有读写搜索访问权限:
chmod o-rwx /var/log/nginx
默认值:
默认情况下不设置working_directory值。
1.4网络配置
1.4.1确保NGINX只监听授权端口上的网络连接
描述:
可以将NGINX配置为监听任何端口,但是应该只监听授权端口。
理由:
将监听端口限制为只有那些经过授权的端口有助于确保在使用nginx时不会运行任何未经授权的服务。
审计:
使用此命令审计服务器上的所有监听端口:
grep -ir listen /etc/nginx
所使用的端口应该立即遵循输出中的listen指令。确保所有正在积极监听而没有注释掉的端口都被授权在服务器上使用。输出应该类似于这个例子:
/etc/nginx/conf.d/default.conf: listen 80 default_server;
/etc/nginx/conf.d/default.conf: listen 443 ssl http2;
/etc/nginx/conf.d/default.conf: listen [::]:443 ssl http2;
修复:
如果正在侦听未授权的任何端口,请注释掉或删除该侦听器的相关配置。
默认值:
默认情况下只有端口80在监听。
1.4.2确保拒绝未知主机名的请求
描述:
您的主机标头应该是已知良好主机的预定义白名单的一部分,这样可以阻止对其他主机的访问。 您应将主机头视为由用户代理定义的另一个要验证的输入。
理由:
将特定主机列入白名单并阻止对所有其他主机的访问,有助于减轻主机头注入对服务器的攻击。攻击者可以使用这种攻击将您重定向到一个流氓主机并执行脚本或让您输入凭据。
审计:
运行下面的命令,以验证这是配置:
curl -k -v https://127.0.0.1 -H 'Host: invalid.host.com'
如果没有收到404错误或任何200个响应,则不执行此建议。
修复:
确保你的第一个服务器块在/etc/nginx/nginx.conf或者nginx配置中:
server { return 404; }
然后研究每个服务器块,确保显式定义了server_name指令。在server_name指令中定义了关联服务器块的主机名,每个服务器块看起来应该与下面类似。例如,如果你的服务器是cisecurity.org,配置应该如下例所示:
server { listen 443; server_name cisecurity.org; ..... }
影响:
如果您处于云之类的环境中,则不应将IP地址或默认主机名作为server_name,因为这些地址通常是临时的。另外,如果您使用的访问方法没有直接引用server_name指令中的名称,那么您将被阻止访问您的站点。您应该保留一个DNS名称来实现此建议。
默认值:
这不是默认设置。
参考:
1.https://www.acunetix.com/blog/articles/automated-detection-of-host-headerattacks/
2.https://hackerone.com/reports/94637
3.https://stackoverflow.com/questions/9824328/why-is-nginx-responding-to-anydomain-name
1.4.3确保keepalive_timeout为10秒或更少,但不是0
描述:
所有现代浏览器都利用持久连接来提高web性能。keep-alive超时限制了持久连接可能保持打开状态的时间。设置keep-alive超时允许在服务器端控制此超时。
理由:
在服务器端设置keep-alive超时可以帮助减少拒绝服务攻击,这些攻击建立了太多的持久连接,耗尽了服务器资源。
审计:
要检查keepalive_timeout指令的当前设置,请发出以下命令。您还应该手动检查nginx配置中可能位于/etc/nginx目录之外的include语句。如果这些都不存在,则将值设置为默认值。
grep -ir keepalive_timeout /etc/nginx
该命令的输出应该包含类似以下内容:
keepalive_timeout 10;
修复:
找到nginx配置的HTTP或服务器块,并添加keepalive_timeout指令。设置为10秒或更少,但不是0。这个示例命令将它设置为10秒:
keepalive_timeout 10;
默认值:
默认情况下,此超时由用户代理指定,并随时间变化。默认情况下,它不是在服务器端设置的。
1.4.4确保send_timeout设置为10秒或更少,但不是0
描述:
send_timeout指令设置了一个超时,用于在两个连续的写操作之间向客户机传输响应。
理由:
在服务器端设置send_timeout指令可以确保关闭占用大量时间的写操作,从而帮助降低HTTP拒绝服务攻击的速度。
审计:
要检查send_timeout指令的当前设置,请发出以下命令。您还应该手动检查nginx配置中可能位于/etc/nginx目录之外的include语句。如果这些都不存在,则将值设置为默认值。
grep -ir send_timeout /etc/nginx
该命令的输出应该类似于以下内容:
send_timeout 10;
修复:
找到nginx配置的HTTP或服务器块,并添加send_timeout指令。设置为10秒或更少,但不是0。
send_timeout 10;
默认值:
send_timeout 60s。
1.5信息泄露
1.5.1确保server_token指令设置为' off '
描述:
server_token指令负责在错误页面和ServerHTTP响应头字段中显示NGINX版本号和操作系统版本。不应显示此信息。
理由:
攻击者可以使用这些响应标头对网站进行侦察,然后针对与底层技术相关的特定已知漏洞进行攻击。隐藏该版本将会降低速度并阻止一些潜在的攻击者。
审计:
在NGINX配置文件NGINX。conf,验证server_token指令是否设置为off。要做到这一点,通过发出以下命令来检查服务器报头的响应头:
curl -I 127.0.0.1 | grep -i server
输出不应该包含服务器头提供您的服务器版本,如以下:
Server: nginx/1.14.0
修复:
要禁用server_token指令,请在nginx.conf的一个服务器块中将其设置为off:
server { ... server_tokens off; ... }
默认值:
server_token的默认值为on。
1.5.2确保默认错误和index.html页面不涉及NGINX
描述:
NGINX的默认错误和index.html页面显示服务器是NGINX。应该删除或修改这些默认页面,这样它们就不会显示服务器的底层基础结构。
理由:
通过收集有关服务器的信息,攻击者可以针对其已知的漏洞发起攻击。删除显示服务器运行NGINX的页面有助于减少对服务器的针对性攻击。
审计:
在服务器配置的location块中找到错误页面和索引指令。nginx中的默认索引和错误页面位于/usr/share/nginx/html/。打开这些文件并确认没有对NGINX的引用。使用以下命令检查默认页面并验证没有返回结果:
grep -i nginx /usr/share/nginx/html/index.html
grep -i nginx /usr/share/nginx/html/50x.html
修复:
编辑/usr/share/nginx/html/index.html和usr/share/nginx/html/50x.html,并且移除任何引用NGINX的行。
1.5.3确保隐藏文件服务被禁用
描述:
禁用隐藏文件是一种深度防御机制,有助于防止意外暴露敏感信息。
理由:
禁用隐藏文件可以防止攻击者引用可能位于您的位置并具有敏感信息的隐藏文件,比如.git文件。
审计:
要验证隐藏文件是否被禁用,请打开nginx配置文件并搜索下面的字符串或另一个regex模式,该模式拒绝以点作为文件路径中的第一个字符访问文件。
运行以下命令:
grep location /etc/nginx/nginx.conf
验证输出为:
location ~ /\. { deny all; return 404; }
修复:
编辑nginx.conf文件并添加以下行:
location ~ /\. { deny all; return 404; }
影响:
这可能会破坏功能所需的众所周知的隐藏文件。例如,它可能阻止LetsEncrypt使用的功能。要启用,请配置如下所示的位置异常:
location ~ /\.well-known\/acme-challenge { allow all; }
默认值:
这不是默认设置。
1.5.4确保NGINX反向代理不允许信息泄露
描述:
服务器和x- power-by头可以指定应用程序使用的底层技术。NGINX反向代理可以传递这些标头,如果没有显式地直接删除它们。
理由:
攻击者可以使用这些响应标头对网站进行侦察,然后针对与底层技术相关的特定已知漏洞进行攻击。删除这些标头将减少目标攻击的可能性。
审计:
确认头文件被拒绝作为nginx配置的位置块的一部分。作为配置的一部分,您必须检查包含的文件。
运行这个命令:
grep proxy_hide_header /etc/nginx/nginx.conf
输出应该是:
proxy_hide_header X-Powered-By;
运行这个命令:
grep proxy_hide_header
输出应该为:
proxy_hide_header Server;
修复:
实现以下指令作为定位块的一部分。编辑/etc/nginx/nginx.conf并添加以下内容:
location /docs { .... proxy_hide_header X-Powered-By; proxy_hide_header Server; .... }
默认值:
默认情况下未实现。