本文概述
在本教程中, 我们将研究如何为生产环境配置Nginx Web服务器。
生产环境中的Web服务器在性能, 安全性等方面与测试环境中的Web服务器不同。
默认情况下, 成功安装Nginx Web服务器后, 始终会有一个随时可用的配置设置。但是, 默认配置对于生产环境而言还不够好。因此, 我们将专注于如何配置Nginx在繁忙和正常的流量高峰期间表现更好, 以及如何防止打算滥用它的用户对其进行保护。
如果尚未在计算机上安装Nginx, 则可以在此处检查如何安装。它显示了如何在Unix平台上安装Nginx。选择通过源文件安装Nginx, 因为预构建的Nginx并未随附本教程中使用的某些模块。
要求
你需要在计算机上安装以下组件, 并确保在任何基于Debian的平台(如Ubuntu)上运行本教程。
- Ubuntu或任何其他基于Debian的平台
- get
- Vim(文本编辑器)
另外, 你需要通过sudo命令以root用户身份运行或执行本教程中的某些命令。
了解Nginx配置结构
在本节中, 我们将研究以下内容:
- Nginx的结构
- 事件, HTTP和邮件等部分
- Nginx的有效语法
在本节的最后, 你将了解Nginx配置的结构, 各节的目的或作用以及如何在各节中定义有效的指令。
完整的Nginx配置文件具有逻辑结构, 该逻辑结构由伪指令组成, 这些伪指令分为多个部分, 例如事件部分, http部分, 邮件部分等。
主要配置文件位于/etc/nginx/nginx.conf, 而其他配置文件位于/ etc / nginx。
主要背景
该部分或上下文包含特定部分(例如邮件部分)之外的指令。
任何其他指令, 例如用户nginx; , worker_processes 1; , error_log /var/log/nginx/error.log警告;和pid /var/run/nginx.pid可以放在主要部分或上下文中。
但是其中一些指令(例如worker_processes)也可以存在于事件部分中。
栏目
Nginx中的各节定义了Nginx模块的配置。
例如, http部分定义了ngx_http_core模块的配置, event部分定义了ngx_event_module的配置, 而mail部分定义了ngx_mail_module的配置。
你可以在此处查看Nginx中各节的完整列表。
指令
Nginx中的指令由变量名和许多参数组成, 例如:
worker_processes是变量名, 而auto用作参数。
worker_processes auto;
指令以分号结尾, 如上所示。
最后, Nginx配置文件必须遵守一组特定的规则。以下是Nginx配置的有效语法:
- 有效指令以变量名开头, 然后是一个或多个参数
- 所有有效的指令以分号结尾;
- 节用花括号{}定义
- 一个部分可以嵌入另一个部分
- 任何部分之外的配置都是Nginx全局配置的一部分。
- 以井号#开头的行是注释。
调整Nginx的性能
在本节中, 我们将配置Nginx在交通繁忙和交通高峰期间表现更好。
我们将研究如何配置:
- 工人
- 磁盘I / O活动
- 网络活动
- 缓冲液
- 压缩
- 快取
- 暂停
仍然在激活的虚拟环境中, 键入以下命令以切换到Nginx目录并列出其内容。
cd nginx && ls
搜索文件夹conf。在此文件夹中是nginx.conf文件。
我们将利用此文件来配置Nginx
现在执行以下命令导航到conf文件夹, 并使用vim编辑器打开文件nginx.conf。
cd conf
sudo vim nginx.conf
以下是默认情况下nginx.conf文件外观的屏幕截图。
工人
为了使Nginx更好地执行, 我们需要在事件部分中配置worker。通过配置Nginx worker, 你可以有效地处理来自客户端的连接。
假设你尚未关闭vim编辑器, 请按键盘上的i按钮以编辑nginx.conf文件。
将以下内容复制并粘贴到事件部分中, 如下所示:
events {
worker_processes auto;
worker_connections 1024;
worker_rlimit_nofile 20960;
multi_accept on;
mutex_accept on;
mutex_accept_delay 500ms;
use epoll;
epoll_events 512;
}
worker_processes:此指令控制Nginx中的worker数量。该指令的值设置为auto, 以允许Nginx确定可用的内核数量, 磁盘, 服务器负载和网络子系统。但是, 你可以通过在终端上执行命令lscpu来发现内核数。
worker_connections:此伪指令设置工作程序可以打开的同时连接数的值。默认值为512, 但我们将其设置为1, 024, 以允许一个工作人员接受来自客户端的大量同时连接。
worker_rlimit_nofile:此伪指令某种程度上与worker_connections有关。为了处理大型同时连接, 我们将其设置为较大的值。
multi_accept:此伪指令允许工作程序一次接受队列中的许多连接。在这种情况下, 队列只是意味着等待处理的一系列数据对象。
Mutex_Accept:默认情况下关闭此伪指令。但是, 因为我们在Nginx中配置了许多工作程序, 所以我们需要如上面的代码所示将其打开, 以允许工作程序一个接一个地接受新连接。
Mutex_accept_delay:此伪指令确定工作程序在接受新连接之前应等待多长时间。一旦accept_mutex打开, 便会在accept_mutex_delay指定的时间范围内为工作线程分配互斥锁。时间到了, 排队的下一个工作人员就准备接受新的连接。
使用:该伪指令指定处理来自客户端的连接的方法。在本教程中, 我们决定将值设置为epoll, 因为我们正在Ubuntu平台上工作。 epoll方法是Linux平台上最有效的处理方法。
epoll_events:此伪指令的值指定Nginx将转移到内核的事件数。
磁盘I / O
在本节中, 我们将在Nginx中配置异步I / O活动, 以使其能够执行有效的数据传输并提高缓存效率。
磁盘I / O只是指硬盘和RAM之间的写入和读取操作。我们将利用内核内部的sendfile()函数发送小文件。
你可以在此区域中使用http部分, location部分和server部分中的指令。
位置部分, 服务器部分可以嵌入或放置在http部分中, 以使配置可读。
将以下代码复制并粘贴到HTTP部分中嵌入的location部分中。
location /pdf/ {
sendfile on;
aio on;
}
location /audio/ {
directio 4m
directio_alignment 512
}
sendfile:要利用操作系统资源, 请将此伪指令的值设置为on。 sendfile在OS内核空间内的文件描述符之间传输数据, 而无需将其发送到应用程序缓冲区。该指令将用于提供小文件。
directio:该指令通过允许将读取和写入直接发送到应用程序来提高缓存效率。 directio是每个现代操作系统的文件系统功能。该指令将用于提供较大的文件, 例如视频。
aio:将此指令设置为on进行写和读操作时启用多线程。多线程是一种执行模型, 该模型允许多个线程彼此共享托管进程资源的同时相互执行。
directio_alignment:此伪指令将块大小值分配给数据传输。它与directio指令有关。
网络层
在本节中, 我们将使用诸如tcp_nodelay和tcp_nopush之类的指令来防止小数据包在立即发送之前等待约200毫秒的指定时间。
通常, 当数据包以”分段”形式传输时, 它们往往会使高负载的网络饱和。因此, John Nagle构建了一种缓冲算法来解决此问题。 Nagle的缓冲算法的目的是防止小数据包使高负载的网络饱和。
将以下代码复制并粘贴到HTTP部分中。
http {
tcp_nopush on;
tcp_nodelay on;
}
tcp_nodelay:默认情况下, 禁用此指令以允许小数据包等待指定的时间后才立即发送。要允许一次发送所有数据, 请启用此伪指令。
tcp_nopush:由于已启用tcp_nodelay指令, 因此会立即发送小数据包。但是, 如果你仍然想利用John Nagle的缓冲算法, 我们还可以启用tcp_nopush来将数据包彼此添加并立即全部发送。
缓冲液
让我们看一下如何在Nginx中配置请求缓冲区以有效处理请求。缓冲区是一种临时存储, 其中的数据会保留一段时间并进行处理。
你可以在服务器部分复制以下内容。
server {
client_body_buffer_size 8k;
client_max_body_size 2m;
client_body_in_single_buffer on;
client_body_temp_pathtemp_files 1 2;
client_header_buffer_size 1m;
large_client_header_buffers 4 8k;
}
重要的是要了解这些缓冲线的作用。
client_body_buffer_size:此伪指令设置请求正文的缓冲区大小。如果计划在64位系统上运行Web服务器, 则需要将该值设置为16k。如果要在32位系统上运行Web服务器, 请将值设置为8k。
client_max_body_size:如果要处理大文件上载, 则需要将此指令设置为至少2m或更大。默认情况下, 它设置为1m。
client_body_in_file_only:如果已禁用带有井号标记符号#的client_body_buffer_size指令, 并且设置了该client_body_in_file_only指令, 则Nginx会将请求缓冲区保存到一个临时文件中。不建议在生产环境中使用。
client_body_in_single_buffer:有时并非所有请求主体都存储在缓冲区中。其余部分将保存或写入临时文件。但是, 如果打算将完整的请求缓冲区保存或存储在单个缓冲区中, 则需要启用此指令。
client_header_buffer_size:你可以使用此伪指令为请求标头设置或分配缓冲区。你可以将此值设置为1m。
large_client_header_buffers:此伪指令用于设置读取大型请求标头的最大数量和最大大小。你可以将最大数量和缓冲区大小精确设置为4和8k。
压缩
压缩通过网络传输的数据量是确保Web服务器性能更好的另一种方法。在本节中, 我们将使用gzip, gzip_comp_level和gzip_min_length等指令来压缩数据。
将以下代码粘贴到http部分中, 如下所示:
http {
gzip on;
gzip_comp_level 2;
gzip_min_length 1000;
gzip_types text/xml text/css;
gzip_http_version 1.1;
gzip_vary on;
gzip_disable "MSIE [4-6] \.";
}
gzip:如果要启用压缩, 请将此伪指令的值设置为on。默认情况下, 它是禁用的。
gzip_comp_level:你可以使用此伪指令来设置压缩级别。为了不浪费CPU资源, 你不必将压缩级别设置得太高。在1到9之间, 你可以将压缩级别设置为2或3。
gzip_min_length:通过content-length响应头字段设置压缩的最小响应长度。你可以将其设置为超过20个字节。
gzip_types:此伪指令允许你选择要压缩的响应类型。默认情况下, 响应类型text / html总是压缩的。你可以添加其他响应类型, 例如上面的代码中所示的text / css。
gzip_http_version:此伪指令允许你选择压缩响应的请求的最低HTTP版本。你可以使用默认值1.1。
gzip_vary:启用gzip伪指令后, 此伪指令将标头字段Vary:Accept Encoding添加到响应中。
gzip_disabled:某些浏览器(例如Internet Explorer 6)不支持gzip压缩。该指令使用User-Agent请求标头字段来禁用某些浏览器的压缩。
快取
利用缓存功能来减少多次加载相同数据的次数。 Nginx提供了通过open_file_cache指令缓存静态内容元数据的功能。
你可以将此指令放置在服务器, 位置和http部分中。
http {
open_file_cache max=1, 000 inactive=30s;
open_file_cache_valid 30s;
open_file_cache_min_uses 4;
open_file_cache_errors on;
}
open_file_cache:默认情况下禁用此伪指令。如果要在Nginx中实现缓存, 请启用它。该指令存储用户通常请求的文件和目录的元数据。
open_file_cache_valid:此伪指令包含open_file_cache伪指令内的备份信息。你可以使用此伪指令来设置有效期限, 通常以秒为单位, 然后在该期限之后再次重新验证与文件和目录有关的信息。
open_file_cache_min_uses:Nginx通常会在一段时间后根据open_file_cache_min_uses清除open_file_cache指令中的信息。你可以使用此伪指令设置最小访问次数, 以标识正在主动访问的文件和目录。
open_file_cache_errors:你可以利用此指令允许Nginx在访问文件时缓存诸如”权限被拒绝”或”无法访问该文件”之类的错误。因此, 每当无权访问资源的用户访问Nginx时, Nginx都会显示相同的错误报告”权限被拒绝”。
暂停
使用keepalive_timeout和keepalive_requests等指令配置超时, 以防止长时间等待的连接浪费资源。
在HTTP部分中, 复制并粘贴以下代码:
http {
keepalive_timeout 30s;
keepalive_requests 30;
send_timeout 30s;
}
keepalive_timeout:使连接保持活动状态约30秒钟。默认值为75秒。
keepalive_requests:配置一定数量的请求以在特定时间段内保持活动。你可以将请求数设置为20或30。
keepalive_disable:如果要禁用特定浏览器组的keepalive连接, 请使用此指令。
send_timeout:设置将数据传输到客户端的超时时间。
Nginx的安全性配置
以下仅关注如何安全地配置Nginx而不是Web应用程序。因此, 我们不会研究基于Web的攻击, 例如SQL注入等。
在本节中, 我们将研究如何配置以下内容:
- 限制对文件和目录的访问
- 配置日志以监视恶意活动
- 防止DDoS
- 禁用目录列表
限制对文件和目录的访问
让我们看看如何通过以下方法限制对敏感文件和目录的访问。
通过使用HTTP身份验证
我们可以通过提示用户甚至管理员进行身份验证来限制对敏感文件或不适合公众查看的区域的访问。如果尚未安装密码文件创建实用程序, 请运行以下命令。
apt-get install -y apache-utils
接下来, 使用htpasswd工具创建一个密码文件和一个用户, 如下所示。 htpasswd工具由apache2-utils实用程序提供。
sudo htpasswd -c /etc/apache2/ .htpasswd mike
你可以通过以下命令确认是否已成功创建用户名和随机密码
cat etc/apache2/ .htpasswd
在location部分中, 你可以粘贴以下代码, 以使用auth_basic指令提示用户进行身份验证。
location /admin {
basic_auth "Admin Area";
auth_basic_user_file /etc/apache2/ .htpasswd;
}
通过使用Allow指令
除了basic_auth指令外, 我们还可以使用allow指令来限制访问。
在位置部分内, 你可以使用以下代码来允许指定的IP地址访问敏感区域。
location /admin {
allow 192.168.34.12;
allow 192.168.12.34;
}
配置日志以监视恶意活动
在本节中, 我们将配置错误和访问日志以专门监视有效和无效请求。你可以检查这些日志, 以找出谁在特定时间登录, 或者哪个用户访问了特定文件等等。
error_log:允许你设置到特定文件的日志记录, 例如syslog或stderr。你还可以指定要记录的错误消息的级别。
access_log:允许将用户请求写入文件access.log
在HTTP部分中, 你可以使用以下内容。
http {
access_log logs/access.log combined;
error_log logs/warn.log warn;
}
防止DDOS
你可以通过以下方法保护Nginx免受DDOS攻击:
限制用户请求
你可以使用limit_req_zone和limit_req指令来限制用户在几分钟内发送请求的速率。
在服务器部分中嵌入的位置部分中添加以下代码。
limit_req_zone $binary_remote_addr zone=one:10m rate=30r/m;
server {
location /admin.html {
limit_req zone=one;
}
}
限制连接数
你可以使用limit_conn和limit_conn_zone指令将连接限制为某些位置或区域。例如, 以下代码在特定时期内从客户端接收15个连接。
以下代码将转到位置部分。
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
location /products/ {
limit_conn addr 10;
}
}
终止慢速连接
你可以使用诸如client_body_timeout和client_header_timeout之类的超时指令来控制Nginx等待来自客户端主体和客户端头的写入的时间。
在服务器部分中添加以下内容。
server {
client_body_timeout 5s;
client_header_timeout 5s;
}
如此处所述, 通过利用基于云的解决方案在边缘阻止DDoS攻击也是一个好主意。
禁用目录列表
你可以使用auto_index指令阻止目录列表, 如下面的代码所示。你需要将其设置为off值以禁用目录列表。
location / {
auto_index off;
}
总结
我们已经配置了Nginx Web服务器, 以使其有效运行并保护其免受生产环境中的过度滥用。如果你将Nginx用于面向Internet的Web应用程序, 那么你还应该考虑使用CDN和基于云的安全性以获得更好的性能和安全性。