有趣生活

当前位置:首页>科技>nginx 代理服务器原理安全开发运维必备的Nginx代理Web服务器性能优化与安全加固配置

nginx 代理服务器原理安全开发运维必备的Nginx代理Web服务器性能优化与安全加固配置

发布时间:2026-07-21阅读(1)

导读1.引言#1.1目的为了更好的指导部署与测试艺术升系统nginx网站服务器高性能同时下安全稳定运行,需要对nginx服务进行调优与加固;本次进行Nginx服....1.引言#1.1 目的

为了更好的指导部署与测试艺术升系统nginx网站服务器高性能同时下安全稳定运行,需要对nginx服务进行调优与加固;

本次进行Nginx服务调优加固主要从以下几个部分:

  • 模块性能优化
  • 系统内核优化
  • 编译安装优化
  • 性能参数优化
  • 安全加固配置
1.2 目标范围

本文档仅供内部使用,禁止外传,帮助研发人员,运维人员对系统长期稳定的运行提供技术文档参考。

1.3 读者对象
  1. 项目经理
  2. 开发人员
  3. 测试人员
  4. 运维人员
  5. 相关领导

2.参考说明#2.1 帮助参考

Nginx是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器。Nginx作为负载均衡服务器, Nginx 既可以在内部直接支持 Rails 和 PHP 程序对外进行服务,也可以支持作为 HTTP代理服务器对外进行服务。

Nginx版本选择:

  • Mainline version 最新版本,推荐测试的业务项目的时候使用
  • Stable version 稳定版本,推荐项目上线实际使用
  • Legacy versions 历史版本,不推荐选择可能存在脆弱性漏洞

项目结构:

#编译后的nginx项目结结构/etc/nginx/├── client_body_temp #客户端上面的临时文件存放目录├── conf #nginx的配置文件存放目录├── fastcgi_temp #fastcgi的临时文件存放目录├── html #存放静态资源或者脚本文件的地方├── logs #nginx日志文件├── proxy_temp #nginx正向/反向代理缓存文件存放目录├── sbin #nginx可执行文件├── scgi_temp #scgi临时文件目录└── uwsgi_temp #uwsgi临时文件存放目录

Nginx文档帮助: http://nginx.org/en/docs/Nginx首页地址目录: /usr/share/nginx/htmlNginx配置文件:

  • /etc/nginx/nginx.conf
  • /usr/local/nginx/conf/nginx.conf
  • /usr/local/etc/nginx/nginx.conf

2.2 参数说明

localtion 请求匹配的url实是一个正则表达式:

# 语法规则: location [=|~|~*|^~] /uri/ { ... }# 参数解析: = 表示精确匹配,这个优先级也是最高的/ 通用匹配,任何请求都会匹配到,默认匹配.~ 表示区分大小写的正则匹配~* 表示不区分大小写的正则匹配(和上面的唯一区别就是大小写) !~和!~*分别为区分大小写不匹配及不区分大小写不匹配的正则!~,!~* : 分别标识为区分大小写不匹配及不区分大小写不匹配的正则^~ 表示 uri 以某个常规字符串开头,理解为匹配 url 路径即可。nginx 不对 url 做编码,因此请求为/static/20%/aa,可以被规则^~ /static/ /aa 匹配到(注意是空格)

Nginx 匹配判断表达式:

-f 和 !-f: 用来判断是否存在文件-d 和 !-d: 用来判断是否存在目录-e 和 !-e: 用来判断是否存在文件或目录-x 和 !-x: 用来判断文件是否可执行

例如,匹配末尾为如下后缀的静态并判断是否存在该文件, 如不存在则404。

location ~* \.(js|css|jpg|jpeg|gif|png|swf)$ { if (-f $request_filename) { return 403; break; }}

3.3 模块说明

查看可用模块编译参数:http://nginx.org/en/docs/configure.html

#可以通过运行 "./configure --help" 查看编译帮助,决定是否需要安装哪些模块,比如下面的ssi模块能够实现访问shtml页面./configure -help

http_gzip模块开启gzip压缩输出(常常是大于1kb的静态文件),减少网络传输;

gzip_min_length 1k #设置允许压缩的页面最小字节数页面字节数从content-length中进行获取,默认值是20gzip_buffers 4 16k #设置系统获取几个单位的缓存用于存储gzip的压缩结果数据流。4 16k代表以16k为单位,安装原始数据大小以16k为单位的4倍申请内存。gzip_comp_level 2 #gzip压缩比,其值从1到9数字越大压缩率越高,越消耗CPU负载也越高gzip_types #匹配mime类型进行压缩,无论是否指定”text/html”类型总是会被压缩的,推荐配置:`gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml rss text/javascript。`gzip_http_version 1.0 #用于识别 http 协议的版本早期的浏览器不支持 Gzip 压缩,用户就会看到乱码,所以为了支持前期版本加上了这个选项;如果你用了 Nginx 的反向代理并期望也启用 Gzip 压缩的话,由于末端通信是 http/1.0,故请设置为 1.0。gzip_proxied any #Nginx作为反向代理的时候启用,决定开启或者关闭后端服务器返回的结果是否压缩,匹配的前提是后端服务器必须要返回包含”Via”的 header头。gzip_vary on #和http头有关系会在响应头加个 Vary: Accept-Encoding ,可以让前端的缓存服务器缓存经过gzip压缩的页面,例如用Squid缓存经过Nginx压缩的数据。

http_fastcgi_module模块nginx可以用来请求路由到FastCGI服务器运行应用程序由各种框架和PHP编程语言等。可以开启FastCGI的缓存功能以及将静态资源进行剥离,从而提高性能。

指令:fastcgi_temp_path #定义FastCGI缓存文件保存临时路径。指令:fastcgi_cache_path #定义FastCGI缓存文件保存路径和缓存的其它参数。缓存数据以二进制数据文件形式存储,缓存文件名和key都是通过对访问URL使用MD5计算获得的结果。缓存文件先保存至fastcgi_temp_path指定的临时目录下,然后通过重命名操作移至fastcgi_cache_path指定的缓存目录。建议fastcgi_temp_path和fastcgi_cache_path设为同一分区,同分区移动操作效率更高。示例:fastcgi_temp_path /tmp/fastcgi_temp;fastcgi_cache_path /tmp/fastcgi_cache levels=1:2 keys_zone=cache_fastcgi:16m inactive=30m max_size=1g;# levels指定了目录结构,子目录数以16为基数;# keys_zone指定了共享内存区名和大小,用于保存缓存key和数据信息;# inactive指定了缓存数据保存的时间,当这段时间内未被访问将被移出;# max_size指定了缓存使用的最大磁盘空间,超过容量时将最近最少使用数据删除。#示例中使用/tmp/fastcgi_temp作为FastCGI缓存的临时目录;/tmp/fastcgi_cache作为FastCGI缓存保存的最终目录;一级子目录为16的一次方16个,二级子目录为16的2次方256个;共享内存区名为cache_fastcgi,占用内存128MB;缓存过期时间为30分钟;缓存数据保存于磁盘的最大空间大小为1GB。指令:fastcgi_cache_key # 定义FastCGI缓存关键字。启用FastCGI缓存必须加上这个配置,不然访问所有PHP的请求都为访问第一个PHP文件URL的结果。指令:fastcgi_cache_valid # 为指定的Http状态码指定缓存时间。指令:fastcgi_cache_min_uses # 指定经过多少次请求相同的URL将被缓存。指令:fastcgi_cache_use_stale # 指定当连接FastCGI服务器发生错误时,哪些情况使用过期数据回应。指令:fastcgi_cache # 缓存使用哪个共享内存区

keepalive模块长连接对性能有很大的影响,通过减少CPU和网络开销需要开启或关闭连接;

  • keepalive_timeout 闲长连接保持打开状态的时间;
  • keepalive_requests 单个客户端长连接可以请求的数量;
  • keepalive 上游服务器长连接的相关指令,每个工作进程中空闲长连接到上游服务器保持开启的连接数量(没有默认值)。要使用连接到上游服务器的长连接,必须要配置文件中下面的指令:

proxy_http_version 1.1; proxy_set_header Connection "";

http_SSL_module模块Nginx开启支持Https协议的SSL模块

#Nginx SSL性能调优ssl_protocols TLSv1 TLSv1.1 TLSv1.2;#注意这里的加密方式ssl_ciphers ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4:HIGH:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!AESGCM;ssl_prefer_server_ciphers on;ssl_session_cache shared:SSL:10m;ssl_session_timeout 10m;


3.服务优化#3.1 系统内核

Linux内核参数部分默认值不适合高并发,Linux内核调优,主要涉及到网络和文件系统、内存等的优化,

  • 临时方法可以通过调整/Proc文件系统,需要注意调整/Proc文件系统系统重启后还原至默认值(不推荐)。
  • 永久修改/etc/sysctl.conf配置文件永久保存

下面是我常用的内核调优配置:

grep -q "net.ipv4.tcp_max_tw_buckets" /etc/sysctl.conf || cat >> /etc/sysctl.conf << EOF########################################net.core.rmem_default = 262144net.core.rmem_max = 16777216net.core.wmem_default = 262144net.core.wmem_max = 16777216#缓冲区队列设置与连接及其如何排队相关##调节系统同时发起的tcp连接数,在高并发的请求中,默认的值可能会导致链接超时或者重传,因此需要结合并发请求数来调节此值。#net.core.somaxconn = 262144#在提交到CPU前网卡中数据包缓冲的速率,高带宽下提高这个值可提高性能;检查内核日志文件中有关这个设置的错误,根据网卡文档中的建议修改这个值。net.core.netdev_max_backlog = 262144#设定系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上net.ipv4.tcp_max_orphans = 262144#用于记录那些尚未收到客户端确认信息的连接请求的最大值(根据类才更改)net.ipv4.tcp_max_syn_backlog = 1024#设定timewait的数量默认是180000设为10000。net.ipv4.tcp_max_tw_buckets = 10000#在高并发情况端口值的起止范围一般端口号设置是1024到65000,用来设定允许系统打开的端口范围;net.ipv4.ip_local_port_range = 1024 65500#用于设置启用timewait快速回收net.ipv4.tcp_tw_recycle = 1#用于设置开启重用,允许将TIME-WAIT sockets重新用于新的TCP连接。net.ipv4.tcp_tw_reuse = 1#用于设置开启SYN Cookies,当出现SYN等待队列溢出时,启用cookies进行处理。net.ipv4.tcp_syncookies = 1#决定了内核放弃连接之前发送SYN ACK包的数量。net.ipv4.tcp_synack_retries = 1#表示在内核放弃建立连接之前发送SYN包的数量。net.ipv4.tcp_syn_retries = 1#决定了套接字保持在FIN-WAIT-2状态的时间。默认值是60秒。#正确设置这个值非常重要,有时即使一个负载很小的Web服务器,也会出现大量的死套接字而产生内存溢出的风险。net.ipv4.tcp_fin_timeout = 30#选项表示当keepalive启用的时候,TCP发送keepalive消息的频度。默认值是2(单位是小时)。net.ipv4.tcp_keepalive_time = 600net.ipv4.tcp_keepalive_intvl = 30net.ipv4.tcp_keepalive_probes = 3net.ipv4.tcp_mem = 786432 1048576 1572864#文件描述符系统级别的限制#kernel.sem = 250 32000 100 128fs.file-max = 6815744vm.swappiness = 10fs.aio-max-nr = 1048576EOFsysctl -p

文件描述符文件描述符是操作系统资源,用于表示连接、打开的文件,以及其他信息。NGINX 每个连接可以使用两个文件描述符。例如如果NGINX充当代理时,通常一个文件描述符表示客户端连接,另一个连接到代理服务器,如果开启了HTTP 保持连接,这个比例会更低(译注:为什么更低呢)。

对于有大量连接服务的系统,下面的设置可能需要调整一下:

#修改文件描述符方式vim /etc/security/limits.conf* - nofile 65536 #用户级别文件描述符限制#然后进行启动文件修改echo "ulimit -Hsn 65536" >> /etc/profile

3.2 编译优化

精简模块:Nginx由于不断添加新的功能,附带的模块也越来越多,建议一般常用的服务器软件使用源码编译安装管理;

(1) 减小Nginx编译后的文件大小

  • 编译Nginx时默认以debug模式进行,而在debug模式下会插入很多跟踪和ASSERT之类的信息,编译完成后一个Nginx要有好几兆字节;因此可以在编译之前,修改相关源码,取消debug模式;

# 找到源码目录下 auto/cc/GCC 文件 debugCFLAGS="$CFLAGS -g" #注释掉或删掉这两行,即可取消debug模式。ls -alh /usr/local/nginx/sbin/nginx-rwxr-xr-x. 1 root root 915K Aug 17 09:49 /usr/local/nginx/sbin/nginx #可以看到体积大大减少

(2) 指定GCC编译参数修改GCC编译参数提高编译优化级别稳妥起见采用 -O2 这也是大多数软件编译推荐的优化级别。

  • Nginx源码文件 auto/cc/gcc 搜索 NGX_GCC_OPT默认GCC编译参数为-O,可以直接修改内容为 NGX_GCC_OPT="-O2" 或者在 ./configure配置时添加--with-cc-opt=-O2选项。

--with-cc-opt=-O3 #编译级别--with-cpu-opt=CPU #为特定的 CPU 编译,有效的值包括:pentium, pentiumpro, pentium3, # pentium4, athlon, opteron, amd64, sparc32, sparc64, ppc64

GCC编译参数优化 [可选项] 总共提供了5级编译优化级别:

  • -O0:无优化。
  • -O和-O1:使用能减少目标代码尺寸以及执行时间并且不会使编译时间明显增加的优化,在编译大型程序的时候会显著增加编译时内存的使用。
  • -O2:包含-O1的优化并增加了不需要在目标文件大小和执行速度上进行折衷的优化。编译器不执行循环展开以及函数内联。此选项将增加编译时间和目标文件的执行性能。
  • -Os:可以看成 -O2.5,专门优化目标文件大小,执行所有的不增加目标文件大小的-O2优化选项,并且执行专门减小目标文件大小的优化选项。适用于磁盘空间紧张时使用。但有可能有未知的问题发生,况且目前硬盘容量很大,常用程序无必要使用。
  • -O3:打开所有 -O2 的优化选项外增加 -finline-functions、-funswitch-loops、-fgcse-after-reload 优化选项。相对于 -O2 性能并未有较多提高,编译时间也最长,生成的目标文件也更大更占内存,有时性能不增反而降低,甚至产生不可预知的问题(包括错误),所以并不被大多数软件安装推荐,除非有绝对把握方可使用此优化级别。

常用编译参数:

#编译0:常规编译参数configure arguments: #安装的目录或者路径#--prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock#执行对应模块nginx所保留的临时文件#--http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp #启动的用户和组用户#--user=nginx --group=nginx #模块参数#--with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module#设置额外的参数将被添加到CFLAGS#--with-cc-opt=-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC #设置附件参数,链接系统库#-with-ld-opt=-Wl,-z,relro -Wl,-z,now -pie#编译1:除多余模块./configure \"--prefix=/App/nginx" \ "--user=nginx" \ "--group=nginx" \"--with-http_stub_status_module" \"--without-http_auth_basic_module" \"--without-http_autoindex_module" \"--without-http_browser_module" \"--without-http_empty_gif_module" \"--without-http_geo_module" \"--without-http_limit_conn_module" \"--without-http_limit_req_module" \"--without-http_map_module" \"--without-http_memcached_module" \"--without-http_proxy_module" \"--without-http_referer_module" \"--without-http_scgi_module" \"--without-http_split_clients_module" \"--without-http_ssi_module" \"--without-http_upstream_ip_hash_module" \"--without-http_upstream_keepalive_module" \"--without-http_upstream_least_conn_module" \"--without-http_userid_module" \"--without-http_uwsgi_module" \"--without-mail_imap_module" \"--without-mail_pop3_module" \"--without-mail_smtp_module" \"--without-poll_module" \"--without-select_module" \"--with-cc-opt=-O2"

3.3 性能优化

缓存和压缩与限制可以提高性能NGINX的一些额外功能可用于提高Web应用的性能,调优的时候web应用不需要关掉但值得一提,因为它们的影响可能很重要。

  • 1)缓存一个启用NGINX缓存的情景,一组web或者应用服务器负载均衡,可以显著缩短对客户端的响应时间,同时大幅度降低后端服务器的负载。缓存本身就可以作个专题来讲,这里我们就不试图讲它了。

# 网页资源缓存location ~* \.(xml|html|htm)$ { # 资源决绝对目录设置 root /var/www/html; # 日志文件的相对路径或完整路径 access_log /path/to/file.log; # 开启日志记录 access_log on; # 设置过期时间 expires 24h;}# 样式、JS、图片资源缓存location ~* \.(css|js|ico|gif|jpg|jpeg|png)$ { root /var/www/html/res; # 禁用404错误日志 log_not_found off; # 关闭日志 access_log off; # 缓存时间7天 expires 7d;}# 字体资源缓存location ~* \.(eot|ttf|otf|woff|woff2|svg)$ { root /var/www/html/static; log_not_found off; access_log off; expires max;}

  • 2)压缩所以使用更小的网络带宽。然而尽管压缩数据会消耗CPU资源,但当需要减少网络带宽使用时这样做非常有效。需要注意的是,不能对已压缩的文件再压缩例如JPEG 文件。

# 启用 gzip 压缩gzip on;# 启用gzip压缩的最小文件,小于设置值的文件将不会压缩gzip_min_length 2k;# gzip 压缩级别,1-10,数字越大压缩的越好,也越占用CPU时间,后面会有详细说明gzip_comp_level 2;# 进行压缩的文件类型,javascript有多种形,其中的值可以在 mime.types 文件中找到。gzip_types text/plain text/css text/javascript application/javascript application/x-javascript application/xml application/x-httpd-php image/x-icon image/jpeg image/gif image/png image/svg xml image/avif image/webp font/ttf font/opentype;# 建议在http header中添加Vary: Accept-Encoding支持gzip_vary on;

  • 3)限制防止用户消耗太多的资源,避免影响系统性能和用户体验及安全性,以下是相关的指令:

limit_conn and limit_conn_zone # NGINX接受客户连接的数量限制,例如单个IP地址的连接。设置这些指令可以防止单个用户打开太多的连接,消耗超出自己的资源。limit_req and limit_req_zon #NGINX处理请求的速度限制,与limit_rate有相同的功能。可以提高安全性,尤其是对登录页面,通过对用户限制请求速率设置一个合理的值,避免太慢的程序覆盖你的应用请求(比如DDoS攻击)。limit_rate # 传输到客户端响应速度的限制(每个打开多个连接的客户消耗更多的带宽)。设置这个限制防止系统过载,确保所有客户端更均匀的服务质量。max_conns #上游配置块中服务器指令参数。在上游服务器组中单个服务器可接受最大并发数量。使用这个限制防止上游服务器过载。设置值为0(默认值)表示没有限制。queue (NGINX Plus - 商业版本提供) # 创建一个队列,用来存放在上游服务器中超出他们最大max_cons限制数量的请求。这个指令可以设置队列请求的最大值,还可以选择设置在错误返回之前最大等待时间(默认值是60秒)。如果忽略这个指令,请求不会放入队列。

简单示例:

http { # 请根据业务需求配置同一IP地址连接数 limit_conn_zone $binary_remote_addr zone=www_weiyigeek_top:10m; # 请根据业务需求配置同一IP地址请求速率 limit_req_zone $binary_remote_addr zone=blog_weiyigeek_top:10m rate=1r/s; server { # 建议创建黑白名单 allow 内部IP或负载均衡IP; deny 恶意IP; # 限流 location ^~ /download/ { # 表示单个IP连接数不超过 2 个 limit_conn www_weiyigeek_top 2; # 表示单个IP请求速率为1s一个, 允许超过频率限制的请求数不多于5个,最多请求不能超过 burst rate 数量。 limit_req zone=blog_weiyigeek_top burst=5 nodelay; alias /data/weiyigeek.top/download/; } }}

  • 4)减少磁盘IO减少磁盘IO次数可以帮助我们更好的提升服务器性能,增强服务器的负载能力。

# 关闭不需要记录指定目录或者文件访问日志access_log off;error_log /dev/null# 为日志写入创建缓存区减少IO次数,例如下面当缓存达到128k或者日志刷新时间为1m时将写入日志文件中(gzip 压缩日志-按需开启)access_log /var/log/nginx/access.log main buffer=128k gzip flush=1m;

3.4 运营优化

1) 永久重定向

如果你的站点需要让http URL跳转到https,则非建议设置永久重定向,而非临时重定向,这可以帮助你站点更好的被收录(SEO)。

例如,配置 http 向 https 跳转 (永久)

# 方式1.Redirect(重定向)- 推荐server { listen 80; server_name weiyigeek.top www.weiyigeek.top; return 301 https://$host$request_uri;}# 方式2.ReWrite 重写server { listen 80; server_name weiyigeek.top www.weiyigeek.top; # 判断请求host是否是 www.weiyigeek.top ,如果是 weiyigeek.top 则重写为 www.weiyigeek.top if ($http_host !~ "^www\.weiyigeek\.top$" { rewrite ^(.*) https://www.weiyigeek.top$1 permanent; }}

3.5 配置优化

nginx配置文件指令优化一览表

TAGS标签:  nginx  代理  服务器  原理  全开  nginx 代理服务

Copyright © 2024 有趣生活 All Rights Reserve吉ICP备19000289号-5 TXT地图HTML地图XML地图