title: “Configure Nginx for a Production Environment” source: “https://harshshah8996.medium.com/configure-nginx-for-a-production-environment-be0e02a3d9e8" author:
- “[Harsh Shah](/tags/Harsh Shah/)” published: 2021-05-06 created: 2025-06-02 description: “Nginx is the most versatile web server out there and can beat other servers when configured properly. A web server in a production environment is different from a web server in a test environment…” tags:
- “clippings”

Nginx is the most versatile web server out there and can beat other servers when configured properly. A web server in a production environment is different from a web server in a test environment regarding performance, security, etc.
Nginx 是目前功能最丰富的 Web 服务器,配置得当的话,可以胜过其他服务器。生产环境中的 Web 服务器与测试环境中的 Web 服务器在性能、安全性等方面存在差异。
When we install Nginx, it provides a ready-to-use configuration setting for our application. However, the default configuration is not good enough for a production environment. There are a number of configurations that improve security and enhance the overall performance of our web application. Therefore, we will focus on how to configure it to perform better during heavy traffic spikes and secure it from users who intend to abuse it.
安装 Nginx 后,它会为我们的应用程序提供现成的配置设置。然而,默认配置对于生产环境来说不够好。有一些配置可以提高安全性并增强 Web 应用程序的整体性能。因此,我们将重点介绍如何配置它,使其在高流量高峰期间表现更佳,并防止用户滥用。
- Performance- We can do caching, buffering, data compression, etc to improve server performance.
性能——我们可以进行缓存、缓冲、数据压缩等来提高服务器性能。 - Security- We can make the webserver more secure by rate-limiting, preventing bots / crawlers, enforcing strict header policies and so on.
安全性——我们可以通过速率限制、防止机器人/爬虫、执行严格的标头策略等方式使网络服务器更加安全。
Performance Configuration性能配置
1. Compression 1. 压缩
Compressing the amount of data transferred over the network can speed up our website.gzip is a popular data compression program. When the browser requests a web page, the server doesn’t send it directly byte by byte. Instead, it sends it in a compressed state based on the accepted encodings of the browser.
压缩网络传输的数据量可以加快我们网站的加载速度 gzip 是一种流行的数据压缩程序。当浏览器请求网页时,服务器不会直接逐字节发送,而是根据浏览器接受的编码以压缩状态发送。
Want to read this story later? Save it in Journal.
想稍后阅读这个故事吗? 将其保存在“日记”中。
http {
gzip on;
gzip_static on;
gzip_http_version 1.1;
gzip_comp_level 5;
gzip_min_length 256;
gzip_proxied any;
gzip_vary on; gzip_types
application/atom+xml
application/javascript
application/json
application/rss+xml
application/vnd.ms-fontobject
application/x-font-ttf
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
font/opentype
image/svg+xml
image/x-icon
text/css
text/plain
text/x-component;
}
gzip- Enables or disables gzipping of responsesgzip- 启用或禁用响应的 gzip 压缩gzip_static- To serve pre-compressed gzip files instead of compressing files on the fly.gzip_static- 提供预压缩的 gzip 文件而不是动态压缩文件。gzip_http_version:Sets the minimum HTTP version of a request required to compress a response.. We can make use of the default value, which is1.1.gzip_http_version:设置压缩响应所需的请求的最低 HTTP 版本。我们可以使用默认值,即1.1。gzip_comp_level- We can set a gzip compression level of a response. To avoid wasting CPU resources, we do not need to keep the compression level too high. Acceptable values are in the range from 1 (min) to 9 (max).gzip_comp_level- 我们可以设置响应的 gzip 压缩级别。为了避免浪费 CPU 资源,压缩级别无需设置过高。可接受的值范围为 1(最小)到 9(最大)。gzip_min_length- Tells Nginx to not compress anything smaller than the defined size. We can set it to more than 20 bytes.gzip_min_length- 告诉 Nginx 不压缩任何小于指定大小的文件。我们可以将其设置为 20 字节以上。gzip_proxied- By default, Nginx does not compress responses to proxied requests (requests that come from the proxy server). To configure compression of these responses, we can usegzip_proxieddirective. The directive has a number of parameters specifying which kinds of proxied requests Nginx should compress(here we’re enabling compression if: a response header includes the “expired”, “no-cache”, “no-store”, “private”, and “Authorization” parameters).gzip_proxied- 默认情况下,Nginx 不会压缩代理请求(来自代理服务器的请求)的响应。要配置这些响应的压缩,我们可以使用gzip_proxied指令。该指令包含多个参数,用于指定 Nginx 应该压缩哪些类型的代理请求(此处启用压缩的条件是:响应标头包含“expired”、“no-cache”、“no-store”、“private”和“Authorization”参数)。gzip_vary- If it is on, then it tells proxies to cache both gzipped and regular versions of a resource.gzip_vary- 如果打开,则它会告诉代理缓存资源的 gzip 压缩版本和常规版本。gzip_types- Enables gzipping of responses for the specified MIME types in addition to “text/html”. Responses with the “text/html” type are always compressedgzip_types- 除“text/html”外,还支持对指定 MIME 类型的响应进行 gzip 压缩。“text/html”类型的响应始终会被压缩。
2. Client-side Caching 2.客户端缓存
If a website uses a lot of static content, we can optimize its performance by enabling client-side caching, where the browser stores copies of static content for quick access. In addition, Caching helps to reduce the number of times to load the same data.
如果网站使用大量静态内容,我们可以通过启用客户端缓存来优化其性能。客户端缓存是指浏览器存储静态内容的副本以便快速访问。此外,缓存有助于减少加载相同数据的次数。
We can use regex to identify the type of static content and use it with a location block to cache it. Nginx provides features to cache static content metadata via open_file_cache directive.
我们可以使用正则表达式来识别静态内容的类型,并将其与 location 块一起使用来缓存它。Nginx 提供了通过 open_file_cache 指令缓存静态内容元数据的功能。
location ~* \.
(?:ico|gif|jpe?g|png|htc|xml|otf|ttf|eot|woff|woff2|svg)$ {
expires 1d;
access_log off;
log_not_found off; add_header Cache-Control private; open_file_cache max=3000 inactive=120s;
open_file_cache_valid 120s;
open_file_cache_min_uses 4;
open_file_cache_errors on;
}location ~* \.(css|js|html)$ {
expires 12h;
access_log on;
add_header Cache-Control public;
}
Cache-Control- It is an HTTP cache header comprised of directives that allow you to define when / how a response should be cached and for how long.Cache-Control- 它是一个 HTTP 缓存标头,由指令组成,允许您定义何时/如何缓存响应以及缓存多长时间。Cache-Control: public- A response containing thepublicdirective signifies that it is allowed to be cached by any intermediate cache. This, however, is usually not included in responses as other directives already signify if the response can be cached (e.g.max-age).Cache-Control: public- 包含public指令的响应表示允许任何中间缓存缓存该响应。然而,该指令通常不包含在响应中,因为其他指令已经指明了该响应是否可以缓存(例如max-age)。Cache-Control: private- It signifies that the response can only be cached by the browser that is accessing the file. This disallows any intermediate caches to store the response.Cache-Control: private- 表示响应只能由访问该文件的浏览器缓存。这不允许任何中间缓存存储响应。open_file_cache- This directive stores metadata of files and directories commonly requested by users, not actual content of files. So performance gain by this kind of cache may not be noticeableopen_file_cache- 此指令存储用户常用文件和目录的元数据,而非文件的实际内容。因此,此类缓存带来的性能提升可能并不明显。open_file_cache_valid- This directive contains backup information inside theopen_file_cachedirective. We can use this directive to set a valid period, usually in seconds after which the information related to files and directories is re-validated again.open_file_cache_valid- 此指令包含open_file_cache指令内部的备份信息。我们可以使用此指令设置一个有效期,通常以秒为单位,在此期限之后,与文件和目录相关的信息将再次进行验证。open_file_cache_min_uses- Nginx usually clear information inside theopen_file_cachedirective after a period of inactivity based on theopen_file_cache_min_uses. We can use this directive to set the minimum set access to identify which files and directories are actively accessed.open_file_cache_min_uses- Nginx 通常会根据open_file_cache_min_uses的值,在一段时间不活动后清除open_file_cache指令中的信息。我们可以使用此指令设置最小访问权限,以识别哪些文件和目录正在被主动访问。open_file_cache_errors- To allow Nginx to cache errors such as “permission denied” or “can’t access this file” when files are accessed. So anytime a resource is accessed by a user who does not have the right to do so, Nginx displays the same error report “permission denied”. If we are using nginx as load-balancer, leave this off.open_file_cache_errors- 允许 Nginx 在访问文件时缓存诸如“权限被拒绝”或“无法访问此文件”之类的错误信息。这样,每当无权访问资源的用户访问时,Nginx 都会显示相同的错误报告“权限被拒绝”。如果我们使用 Nginx 作为负载均衡器,请关闭此选项。
3. Buffers 3. 缓冲区
A buffer is a temporary storage where data is stored and processed for a short time. Upon receiving of the request, Nginx writes it on these buffers. The data in these buffers is available as Nginx variables, such as $request_body.
缓冲区是一个临时存储空间,用于存储和短时间处理数据。Nginx 收到请求后,会将其写入这些缓冲区。缓冲区中的数据可以作为 Nginx 变量使用,例如 $request_body 。
server { client_body_buffer_size 16K;
client_header_buffer_size 1k;
client_max_body_size 8m;
large_client_header_buffers 4 8k;
client_body_in_single_buffer on; }
client_body_buffer_size- It sets the buffer size for the request body. If we plan to run the webserver on 64-bit systems, we need to set the value to 16k. If we want to run the webserver on the 32-bit system, set the value to 8k.client_body_buffer_size- 设置请求主体的缓冲区大小。如果我们计划在 64 位系统上运行 Web 服务器,则需要将该值设置为 16k。如果我们想在 32 位系统上运行 Web 服务器,则将该值设置为 8k。client_header_buffer_size- Used to set or allocate a buffer for request headers.client_header_buffer_size- 用于设置或分配请求标头的缓冲区。client_max_body_size- If we intend to handle large file uploads, we need to set this directive to at least2mor more. By default, it is set to1m.client_max_body_size- 如果我们打算处理大文件上传,则需要将此指令设置为至少2m或更大。默认情况下,它设置为1m。large_client_header_buffers- This directive is used to set the maximum number and size of buffers to read large request headers.large_client_header_buffers- 此指令用于设置读取大型请求标头的缓冲区的最大数量和大小。client_body_in_single_buffer- Sometimes, all the request body is not stored in a buffer. The rest of it is saved or written to a temporary file. However, if we intend to save or store the entire request in a single buffer, we need to enable this directive.client_body_in_single_buffer- 有时,请求主体并非全部存储在缓冲区中。其余部分会被保存或写入临时文件。但是,如果我们打算将整个请求保存或存储在单个缓冲区中,则需要启用此指令。
4. Timeout 4. 超时
Configure timeout using directives such as keepalive_timeout and keepalive_requests to prevent long-waiting connections from wasting resources.
使用 keepalive_timeout 和 keepalive_requests 等指令配置超时,以防止长时间等待的连接浪费资源。
http { keepalive_timeout 30s;
keepalive_requests 30;
send_timeout 30s;}
keepalive_timeout- Limits the maximum time during which requests can be processed through one keep-alive connection. After this time is reached, the connection is closed following the subsequent request processing.keepalive_timeout- 限制通过一个保持连接处理请求的最大时间。达到此时间后,连接将在后续请求处理完成后关闭。keepalive_requests- Sets the maximum number of requests that can be served through one keep-alive connection. After the maximum number of requests are made, the connection is closed.keepalive_requests- 设置一个保持连接所能处理的最大请求数。达到最大请求数后,连接将被关闭。send_timeout- Sets a timeout for transmitting a response to the client. The timeout is set only between two successive write operations, not for the transmission of the whole response. If the client does not receive anything within this time, the connection is closed.send_timeout- 设置向客户端发送响应的超时时间。该超时时间仅在两次连续的写入操作之间设置,而不是在整个响应传输过程中设置。如果客户端在此时间内未收到任何消息,则连接将被关闭。
Security Configuration 安全配置
1. Disable server_tokens 1. 禁用 server_tokens
The server_tokens directive tells Nginx to display its current version on error pages. This is not desirable since we do not want to share that information with the world to prevent attacks at our web server caused by known vulnerabilities in that specific version.server_tokens 指令告诉 Nginx 在错误页面上显示其当前版本。这并非我们所期望的,因为我们不想与外界共享这些信息,以防止该特定版本中已知的漏洞对我们的 Web 服务器造成攻击。
To disable the server_tokens directive, set if to off inside a server block.
要禁用 server_tokens 指令,请在服务器块内将 if 设置为 off。
server
{
server_tokens off;
}
2. Limiting the Rate of Requests (Reduce Scrapping / Attacks)2.限制请求率(减少报废/攻击)
We can limit the rate at which Nginx accepts incoming requests at a value for actual users.
我们可以将 Nginx 接受传入请求的速率限制为实际用户的某个值。
The limit_req_zone directive defines the parameters for rate-limiting while limit_req enables rate limiting within the context where it appears (in below example, for all requests to /sign-up/).limit_req_zone 指令定义了速率限制的参数,而 limit_req 在其出现的上下文中启用速率限制(在下面的示例中,针对所有对 /sign-up/ 的 请求)。
From the code below, we can say that each unique IP address is limited to 10 requests per second with 5 requests bursting.
从下面的代码中,我们可以说每个唯一的 IP 地址每秒限制为 10 个请求,突发 5 个请求。
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;server {
location /sign-up/ {
limit_req zone=one burst=5;
}
}
- The
limit_req_zonedirective is commonly defined in thehttpblock, making it available for use in multiple contexts.limit_req_zone指令通常在http块中定义,使其可以在多种上下文中使用。 - The
limit_req_zonedirective sets the parameters for rate-limiting and the shared memory zone, but it does not limit the request rate. For that, we need to apply the limit to a specificlocationorserverblock by including alimit_reqdirective there.limit_req_zone指令设置了速率限制和共享内存区域的参数,但它并不限制请求速率。为此,我们需要在特定location或服务器块中添加limit_req指令,以将限制应用于该位置或server块。 burst- It defines how many requests a client can make in excess of the rate specified by the zone.burst它定义了客户端可以发出超出区域指定速率的请求数量。
3. Limiting the Number of Connections (Reduce Scrapping / Attacks)3.限制连接数(减少报废/攻击)
We can limit the number of connections that can be opened by a unique IP address.
我们可以限制一个唯一 IP 地址可以打开的连接数。
limit_conn_zone $binary_remote_addr zone=addr:10m;server {
location /something/ {
limit_conn addr 10;
}
}
Below example allows a maximum of 10 connections to be opened for a unique IP address.
下面的示例允许为一个唯一的 IP 地址打开最多 10 个连接。
4. Terminate slow connections4. 终止慢速连接
We can make use of timeouts directives such as the client_body_timeout and client_header_timeout to control how long Nginx will wait for writes from the client body and client header.
我们可以利用超时指令(例如 client_body_timeout 和 client_header_timeout 来控制 Nginx 等待 client body 和 client header 写入的时间。
Add the following inside the server section.
在 server 部分添加以下内容。
server {
client_body_timeout 12s;
client_header_timeout 12s;
}
client_body_timeoutandclient_header_timeout- They are responsible for the time, a server will wait for a client body or client header to be sent after request. If neither a body or header is sent, the server will issue a 408 error or Request time out.client_body_timeout和client_header_timeout- 它们负责设置服务器在请求后等待客户端主体或客户端标头发送的时间。如果主体或标头均未发送,服务器将发出 408 错误或 请求超时 。
5. Deny Connections From Bots/Attackers5. 拒绝来自机器人/攻击者的连接
Sometimes, if we are experiencing poor performance, it is because we are being attacked by Internet bots. The reason for these attacks is that they are trying to find a security bug in our application code or in the software itself.
有时,如果我们遇到性能不佳的情况,那是因为我们受到了网络机器人的攻击。这些攻击的原因是,它们试图在我们的应用程序代码或软件本身中寻找安全漏洞。
We can stop this by the following code.
我们可以通过以下代码来停止此操作。
map $http_user_agent $limit_bots {
default 0;
~*(google|bing|yandex|msnbot) 1;
~*(AltaVista|Googlebot|Slurp|BlackWidow|Bot|ChinaClaw|Custo|DISCo|Download|Demon|eCatch|EirGrabber|EmailSiphon|EmailWolf|SuperHTTP|Surfbot|WebWhacker) 1;
~*(Express|WebPictures|ExtractorPro|EyeNetIE|FlashGet|GetRight|GetWeb!|Go!Zilla|Go-Ahead-Got-It|GrabNet|Grafula|HMView|Go!Zilla|Go-Ahead-Got-It) 1;
~*(rafula|HMView|HTTrack|Stripper|Sucker|Indy|InterGET|Ninja|JetCar|Spider|larbin|LeechFTP|Downloader|tool|Navroad|NearSite|NetAnts|tAkeOut|WWWOFFLE) 1;
~*(GrabNet|NetSpider|Vampire|NetZIP|Octopus|Offline|PageGrabber|Foto|pavuk|pcBrowser|RealDownload|ReGet|SiteSnagger|SmartDownload|SuperBot|WebSpider) 1;
~*(Teleport|VoidEYE|Collector|WebAuto|WebCopier|WebFetch|WebGo|WebLeacher|WebReaper|WebSauger|eXtractor|Quester|WebStripper|WebZIP|Wget|Widow|Zeus) 1;
~*(Twengabot|htmlparser|libwww|Python|perl|urllib|scan|Curl|email|PycURL|Pyth|PyQ|WebCollector|WebCopy|webcraw) 1;
}server {
location / {
if ($limit_bots = 1) {
return 403;
}
}
The default value of limit_bots is 0. If any request is coming from above bots, then we set its value to 1 and Nginx will return 403 to that request.limit_bots 的默认值为 0。如果有任何请求来自上述机器人,那么我们将其值设置为 1,Nginx 将向该请求返回 403。
6. Secure HTTP header 6. 安全 HTTP 标头
By default, Nginx does not necessarily have all the important security headers that are actually very straightforward. Security vulnerabilities such as clickjacking attacks, cross-site scripting attacks, code injection attacks, etc. can be fixed by implementing necessary headers.
默认情况下,Nginx 并不一定具备所有重要的安全标头,这些标头实际上非常简单。诸如点击劫持攻击、跨站点脚本攻击、代码注入攻击等安全漏洞可以通过实现必要的标头来修复。
server { add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header Content-Security-Policy "default-src 'self';";
add_header X-Permitted-Cross-Domain-Policies master-only;
add_header Referrer-Policy same-origin;
add_header Strict-Transport-Security 'max-age=31536000;
includeSubDomains; preload';}
X-Frame-Options- To indicate whether or not a browser should be allowed to open a page in frame or iframe. This will prevent site content embedded into other sites. If it has theSAMEORIGINvalue, then it will allow the page to be displayed in a frame on the same origin as the page itself.X-Frame-Options- 指示是否允许浏览器在框架 (frame) 或 iframe 中打开页面。这将阻止网站内容嵌入到其他网站。如果值为SAMEORIGIN,则允许页面显示在与页面本身同源的框架中。X-Content-Type-Options- Thex-content-typeheader also called “Browser Sniffing Protection” to tell the browser to follow the MIME types indicated in the header. It is used to prevents web browsers from sniffing a response away from the declared Content-Type. There is only one parameter we got to addnosniff.X-Content-Type-Options-x-content-type标头也称为“浏览器嗅探保护”,用于指示浏览器遵循标头中指定的 MIME 类型。它用于防止 Web 浏览器嗅探与声明的 Content-Type 不符的响应。我们只需要添加一个参数nosniff。Content-Security-Policy- By implementing the Content Security Policy (CSP) header, we can Prevent XSS, clickjacking, code injection attacks. CSP instruct browser to load allowed content to load on the website.default-srcandselfindicate loading everything from the same origin in various web servers. If it hasscript-srcvalue, then it loads the only script from the same origin.Content-Security-Policy- 通过实现内容安全策略 (CSP) 标头,我们可以防止 XSS、点击劫持和代码注入攻击。CSP 指示浏览器加载网站上允许加载的内容。defaultdefault-src和self指示加载来自不同 Web 服务器的同源所有内容。如果存在script-src值,则仅加载来自同源的脚本。X-Permitted-Cross-Domain-Policies- We can implement this header to instruct the browser on how to handle the requests over a cross-domain. By implementing this header, we restrict loading our site’s assets from other domains to avoid resource abuse.X-Permitted-Cross-Domain-Policies- 我们可以实现此标头来指示浏览器如何处理跨域请求。通过实现此标头,我们可以限制从其他域加载我们网站的资源,从而避免资源滥用。Referrer-Policy- It is used to identifies the address of the webpage that requested the current webpage. By checking the referrer, the new webpage can see where the request originated. The Referrer-Policy can be configured to cause the browser to not inform the destination site any URL information. When it hassame-originvalue, it means to send the origin, path, and query string for same-origin requests. Don’t send theRefererheader for cross-origin requests.Referrer-Policy- 用于识别请求当前网页的网页地址。通过检查 referrer,新网页可以查看请求的来源。Referrer-Policy 可以配置为使浏览器不向目标网站提供任何 URL 信息。当其值为same-origin时,表示对于同源请求,发送来源、路径和查询字符串。对于跨源请求,则不发送Referer标头。Strict-Transport-Security- HSTS (HTTP Strict Transport Security) header to ensure all communication from a browser is sent over HTTPS (HTTP Secure). This prevents HTTPS click-through prompts and redirects HTTP requests to HTTPS. Before implementing this header, we must ensure all our website page is accessible over HTTPS else they will be blocked. In our example, it has‘max-age=31536000; includeSubDomains; preload’having HSTS configured for one year, including preload for domain and sub-domains.Strict-Transport-Security- HSTS(HTTP 严格传输安全)标头,用于确保所有来自浏览器的通信均通过 HTTPS(HTTP 安全)发送。这可以防止 HTTPS 点击提示,并将 HTTP 请求重定向到 HTTPS。在实施此标头之前,我们必须确保所有网站页面都可以通过 HTTPS 访问,否则将被阻止。在我们的示例中,‘max-age=31536000; includeSubDomains; preload’已配置 HSTS 一年,包括域名和子域名的预加载。
In this article, I have explained some configurations to improve security and increase the performance of the Nginx web server. Do you already use something like this or have a different opinion altogether? Let me know in the response section.
在本文中,我讲解了一些提升 Nginx Web 服务器安全性和性能的配置。您是否已经使用过类似的配置,或者有其他不同的看法?请在回复区留言告诉我。
📝 Save this story in Journal.
📝 将这个故事保存在 日记 中。
A passionate Software Engineer having experience of building Web and Mobile applications with Django,Laravel,Nodejs and some other cool libraries and frameworks
一位充满热情的软件工程师,具有使用 Django、Laravel、Nodejs 和其他一些很酷的库和框架构建 Web 和移动应用程序的经验
Write a responseWhat are your thoughts?
Hi Harsh Shah, 你好,Harsh Shah,
As a beginner may I know is this configuration enough for production environment of node.js where I use nginx as reverse proxy and load balancing . And would you help me if failover haappens and when request send to backup server the…
作为一名初学者,请问这个配置是否足以应付 Node.js 的生产环境,我在其中使用 nginx 作为反向代理和负载均衡。如果发生故障转移,请求发送到备份服务器时……
More from Harsh Shah 哈什·沙阿的更多作品
Recommended from Medium Medium 推荐
[
See more recommendations