导航菜单

Nginx配置优化及安全加固

陆兴东 2026-04-14 31 浏览 中间件

nginx.conf 配置

# 配置worker进程数量,为避免cpu切换损耗,配置和系统内核数一样即可,或auto

worker_processes auto;

# 配置cpu绑定的进程,auto代表自动绑定 

worker_cpu_affinity auto;

# nginx 进程打开文件描述符数目,此值覆盖 ulimit -n 的值。

# 若未设置的话,此值为操作系统的限制;设置后操作系统和Nginx可以处理比更多的文件,把这个值设高,nginx就不会有“too many open files”问题了

worker_rlimit_nofile 65535;

events {

    # 单个进程的最大连接籹

    worker_connections 2048;

}

http {

    # 隐藏nginx版本号

    server_tokens off;

    # 1.0 定义限制并发连接数所使用的缓存区大小

    # 限制是以客户端IP为单位进行的

    # zone=one1:10m:创建一个大小为10M的IP存储区,用来存储访问频率;

    # 其中one1是一个自定义变量,它代表着一个存储区为10M的并发限制,之后在使用one1变量时只需指定具体的并发数量即可

    limit_conn_zone $binary_remote_addr zone=one1:10m;

    # 1.1 定义限制请求频率所使用的缓存区大小,以及具体的请求频率

    # rate=10r/s:表示客户端的访问频率最多为每秒10次,超过此频率的请求会被延迟排队处理

    # one2是一个自定义变量,此处one2代表着一个存储区大小为10M、请求频率为每秒10次的限制

    limit_req_zone $binary_remote_addr zone=one2:10m rate=10r/s;

    # 2.0 此处为全局限制配置,以下配置均可在http、server、location中进行局部配置(局部配置会覆盖全局配置)

    # 2.0 启用并发限制:引用变量one1所定义的并发缓存区大小,并设置限制并发数为10

    limit_conn one1 10; 

    # 2.1 启用速率限制:限制单个请求的连接速度

    limit_rate 300k; 

    # 2.2 启用频率限制:引用变量one2所定义的缓存区大小和请求频率来限制客户端请求;超出频率限制的请求会被迟延和排队处理;

    # 参数burst定义一个频率阈值,参数nodelay声明了超过阈值burst的请求应该被直接终止处理,并返回503;

    # 如下,引用one2定义的每秒10次的频率限制,超出此频率的请求会被延迟;直到请求频率超过阈值burst所定义的15,nodelay声明就会生效,即直接将请求终止,并返回503;

    limit_req zone=one2 burst=15 nodelay;  

    server {

       # 限制并发数10

       limit_conn one1 10; 

       # 限制请求频率 

       # burst:如果请求的频率超过了限制域配置的值,请求处理会被延迟

       # nodelay:超过频率限制的请求会被延迟,直到被延迟的请求数超过了定义的阈值,这个请求会被终止,并返回503     

       limit_req zone=one2 burst=10 nodelay;

    }    

    # 其它...

}

Web前端项目配置示例

server {

  listen 80;

  server_name test.com;

  # 限制并发数10

  limit_conn one1 10; 

  # 限制请求频率(对于某些项目,例如vue、GeoServer等,因为页面打开时要加载非常多的.js、.css、地图切片等小文件,因此每秒的请求数量不能过低)

  # burst:如果请求的频率超过了限制域配置的值,请求处理会被延迟

  # nodelay:超过频率限制的请求会被延迟,直到被延迟的请求数超过了定义的阈值,这个请求会被终止,并返回503   

  limit_req zone=one2 burst=20 nodelay;

  charset utf-8;

  location / {

    # 安全相关 header

    # 禁止网站被嵌入到其它网页中,如:iframe、embed等,SAMEORIGIN表示该页面仅能在相同域名页面的iframe中展示

    add_header X-Frame-Options "SAMEORIGIN" always; 

    # 当检测到XSS攻击时阻止页面加载

    add_header X-XSS-Protection "1; mode=block" always;

    # 禁止请求类型为style和script时,但MIME类型却不为text/css和JavaScript的请求

    add_header X-Content-Type-Options "nosniff" always;

    # 设置主机头和客户端真实地址,以便服务器获取客户端真实IP

    proxy_set_header Host $host;

    proxy_set_header X-Real-IP $remote_addr;

  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    # 转发请求协议,如:http或https

    proxy_set_header X-Forwarded-Proto $scheme;

    # 禁用缓存

    # proxy_buffering off;

    root /var/www/html/sidoc-admin/dist;

    try_files $uri $uri/ /index.html;

    index index.html;

   }

   # 防止爬虫抓取 

if($http_user_agent~*"360Spider|JikeSpider|Spider|spider|bot|Bot|2345Explorer|curl|wget|webZIP|qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Feedfetcher-Google|Yahoo! Slurp|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot|ia_archiver|Tomato Bot|NSPlayer|bingbot") { 

     return 403; 

   }

}

反向代理配置示例

注意:跨域请求反向代理服务时,如果被代理的服务发生异常,Nginx可能并不会将异常转至前端显示,而会使浏览器直接报出跨域错误,此错误非常容易误导开发者。

server {

 listen 80;

 server_name test.com;

 # 限制并发数10

 limit_conn one1 10; 

 # 限制请求频率(对于某些项目,例如vue、GeoServer等,因为页面打开时要加载非常多的.js、.css、地图切片等小文件,因此每秒的请求数量不能过低)

 # burst:如果请求的频率超过了限制域配置的值,请求处理会被延迟

 # nodelay:超过频率限制的请求会被延迟,直到被延迟的请求数超过了定义的阈值,这个请求会被终止,并返回503   

 limit_req zone=one2 burst=10 nodelay;

 location / {

   # 跨域设置,

   add_header Access-Control-Allow-Origin 'test1.com,test2.com'; #(允许多个时,以英文逗号分隔)

   add_header Access-Control-Allow-Methods 'GET, POST';

   add_header Access-Control-Allow-Headers *; # 允许所有请求头

   add_header Access-Control-Max-Age 3600;    # 预检命令的缓存,如果不缓存每次会发送两次请求

   # 请求为OPTIONS预检时,直接返回

   if ($request_method = OPTIONS ) {

      return 204;

   }

   # 安全相关 header

   # 禁止网站被嵌入到其它网页中,如:iframe、embed等,SAMEORIGIN表示该页面仅能在相同域名页面的iframe中展示

   add_header X-Frame-Options "SAMEORIGIN" always; 

   # 当检测到XSS攻击时阻止页面加载

   add_header X-XSS-Protection "1; mode=block" always;

   # 禁止请求类型为style和script时,但MIME类型却不为text/css和JavaScript的请求

   add_header X-Content-Type-Options "nosniff" always;

   proxy_pass http://127.0.0.1:8080;

# 重新定义请求头,详见:https://www.cnblogs.com/kevingrace/p/8269955.html

   proxy_set_header Host $host; 

   proxy_set_header X-Real-IP $remote_addr;

  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

   # 转发请求协议,如:http或https

   # proxy_set_header X-Forwarded-Proto $scheme;

 }

 # 防止爬虫抓取 

if($http_user_agent~*"360Spider|JikeSpider|Spider|spider|bot|Bot|2345Explorer|curl|wget|webZIP|qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Feedfetcher-Google|Yahoo! Slurp|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot|ia_archiver|Tomato Bot|NSPlayer|bingbot") { 

  return 403; 

 }

}

#   指定允许跨域的方法,*代表所有

add_header Access-Control-Allow-Methods *;

#   预检命令的缓存,如果不缓存每次会发送两次请求

add_header Access-Control-Max-Age 3600;

#   带cookie请求需要加上这个字段,并设置为true

add_header Access-Control-Allow-Credentials true;

#   表示请求头的字段 动态获取

add_header Access-Control-Allow-Headers $http_access_control_request_headers;

#   OPTIONS预检命令,预检命令通过时才发送请求

#   检查请求的类型是不是预检命令

if ($request_method = OPTIONS){

    return 204;

}