[TOC]
修订控制页 1.引言 1.1 目的 为了更好的指导部署与测试艺术升系统nginx网站服务器高性能同时下安全稳定运行,需要对nginx服务进行调优与加固;
本次进行Nginx服务调优加固主要从以下几个部分:
模块性能优化 
系统内核优化 
编译安装优化 
性能参数优化 
安全加固配置 
 
1.2 目标范围 本文档仅供内部使用,禁止外传,帮助研发人员,运维人员对系统长期稳定的运行提供技术文档参考。
1.3 读者对象 1) 项目经理
2.参考说明 2.1 帮助参考 Nginx是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器。Nginx作为负载均衡服务器, Nginx 既可以在内部直接支持 Rails 和 PHP 程序对外进行服务,也可以支持作为 HTTP代理服务器对外进行服务。
Nginx版本选择:
Mainline version 最新版本,推荐测试的业务项目的时候使用 
Stable version  稳定版本,推荐项目上线实际使用 
Legacy versions 历史版本,不推荐选择可能存在脆弱性漏洞 
 
项目结构:
     
      
        
        [TOC]
修订控制页 1.引言 1.1 目的 为了更好的指导部署与测试艺术升系统nginx网站服务器高性能同时下安全稳定运行,需要对nginx服务进行调优与加固;
本次进行Nginx服务调优加固主要从以下几个部分:
模块性能优化 
系统内核优化 
编译安装优化 
性能参数优化 
安全加固配置 
 
1.2 目标范围 本文档仅供内部使用,禁止外传,帮助研发人员,运维人员对系统长期稳定的运行提供技术文档参考。
1.3 读者对象 1) 项目经理
2.参考说明 2.1 帮助参考 Nginx是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器。Nginx作为负载均衡服务器, Nginx 既可以在内部直接支持 Rails 和 PHP 程序对外进行服务,也可以支持作为 HTTP代理服务器对外进行服务。
Nginx版本选择:
Mainline version 最新版本,推荐测试的业务项目的时候使用 
Stable version  稳定版本,推荐项目上线实际使用 
Legacy versions 历史版本,不推荐选择可能存在脆弱性漏洞 
 
项目结构:1 2 3 4 5 6 7 8 9 10 11 /etc/nginx/ ├── client_body_temp   ├── conf               ├── fastcgi_temp       ├── html               ├── logs               ├── proxy_temp         ├── sbin               ├── scgi_temp          └── uwsgi_temp         
Nginx文档帮助: http://nginx.org/en/docs/ 
/etc/nginx/nginx.conf  
/usr/local/nginx/conf/nginx.conf  
/usr/local/etc/nginx/nginx.conf 
 
2.2 参数说明 localtion 请求匹配的url实是一个正则表达式:1 2 3 4 5 6 7 8 9 10 location [=|~|~*|^~] /uri/ { ... } = 表示精确匹配,这个优先级也是最高的 / 通用匹配,任何请求都会匹配到,默认匹配. ~ 表示区分大小写的正则匹配 ~* 表示不区分大小写的正则匹配(和上面的唯一区别就是大小写) !~和!~*分别为区分大小写不匹配及不区分大小写不匹配的正则 !~,!~* : 分别标识为区分大小写不匹配及不区分大小写不匹配的正则 ^~ 表示 uri 以某个常规字符串开头,理解为匹配 url 路径即可。nginx 不对 url 做编码,因此请求为/static/20%/aa,可以被规则^~ /static/ /aa 匹配到(注意是空格) 
Nginx 匹配判断表达式:1 2 3 4 -f 和 !-f: 用来判断是否存在文件 -d 和 !-d: 用来判断是否存在目录 -e 和 !-e: 用来判断是否存在文件或目录 -x 和 !-x: 用来判断文件是否可执行 
例如,匹配末尾为如下后缀的静态并判断是否存在该文件, 如不存在则404。1 2 3 4 5 6 location ~* \.(js|css|jpg|jpeg|gif|png|swf)$ {   if (-f $request_filename) {      return 403;     break;   } } 
3.3 模块说明 查看可用模块编译参数:http://nginx.org/en/docs/configure.html 
http_gzip模块 1 2 3 4 5 6 7 gzip_min_length 1k  gzip_buffers 4 16k  gzip_comp_level 2  gzip_types  gzip_http_version 1.0  gzip_proxied any  gzip_vary on  
http_fastcgi_module模块 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 指令: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; 指令:fastcgi_cache_key         指令:fastcgi_cache_valid       指令:fastcgi_cache_min_uses    指令:fastcgi_cache_use_stale   指令:fastcgi_cache             
keepalive模块 
keepalive_timeout 闲长连接保持打开状态的时间; 
keepalive_requests 单个客户端长连接可以请求的数量; 
keepalive 上游服务器长连接的相关指令,每个工作进程中空闲长连接到上游服务器保持开启的连接数量(没有默认值)。1 2 proxy_http_version 1.1; proxy_set_header Connection "" ; 
 
 
http_ssl_module模块 1 2 3 4 5 6 7 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配置文件永久保存 
 
下面是我常用的内核调优配置:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 grep -q "net.ipv4.tcp_max_tw_buckets"  /etc/sysctl.conf || cat >> /etc/sysctl.conf << EOF net.core.rmem_default = 262144 net.core.rmem_max = 16777216 net.core.wmem_default = 262144 net.core.wmem_max = 16777216 net.core.netdev_max_backlog = 262144 net.ipv4.tcp_max_orphans = 262144 net.ipv4.tcp_max_syn_backlog = 1024 net.ipv4.tcp_max_tw_buckets = 10000 net.ipv4.ip_local_port_range = 1024 65500 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_synack_retries = 1 net.ipv4.tcp_syn_retries = 1 net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_keepalive_time = 600 net.ipv4.tcp_keepalive_intvl = 30 net.ipv4.tcp_keepalive_probes = 3 net.ipv4.tcp_mem = 786432 1048576 1572864 kernel.sem = 250 32000 100 128 fs.file-max = 6815744 vm.swappiness = 10 fs.aio-max-nr = 1048576 EOF sysctl -p 
文件描述符 
对于有大量连接服务的系统,下面的设置可能需要调整一下:1 2 3 4 5 6 vim /etc/security/limits.conf * - nofile 65536   echo  "ulimit -Hsn 65536"  >> /etc/profile
3.2 编译优化 精简模块:Nginx由于不断添加新的功能,附带的模块也越来越多,建议一般常用的服务器软件使用源码编译安装管理;
(1) 减小Nginx编译后的文件大小
编译Nginx时默认以debug模式进行,而在debug模式下会插入很多跟踪和ASSERT之类的信息,编译完成后一个Nginx要有好几兆字节;因此可以在编译之前,修改相关源码,取消debug模式;1 2 3 4 5 CFLAGS="$CFLAGS  -g"   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编译参数-O2 这也是大多数软件编译推荐的优化级别。
Nginx源码文件 auto/cc/gcc 搜索 NGX_GCC_OPT默认GCC编译参数为-O,可以直接修改内容为 NGX_GCC_OPT="-O2" 或者在 ./configure配置时添加--with-cc-opt='-O2'选项。 
 
1 2 --with-cc-opt='-O3'    --with-cpu-opt=CPU    
                weiyigeek.top-
             
GCC编译参数优化 [可选项] 总共提供了5级编译优化级别: 
-O0:无优化。 
-O和-O1:使用能减少目标代码尺寸以及执行时间并且不会使编译时间明显增加的优化,在编译大型程序的时候会显著增加编译时内存的使用。 
-O2:包含-O1的优化并增加了不需要在目标文件大小和执行速度上进行折衷的优化。编译器不执行循环展开以及函数内联。此选项将增加编译时间和目标文件的执行性能。 
-Os:可以看成 -O2.5,专门优化目标文件大小,执行所有的不增加目标文件大小的-O2优化选项,并且执行专门减小目标文件大小的优化选项。适用于磁盘空间紧张时使用。但有可能有未知的问题发生,况且目前硬盘容量很大,常用程序无必要使用。 
-O3:打开所有 -O2 的优化选项外增加 -finline-functions、-funswitch-loops、-fgcse-after-reload 优化选项。相对于 -O2 性能并未有较多提高,编译时间也最长,生成的目标文件也更大更占内存,有时性能不增反而降低,甚至产生不可预知的问题(包括错误),所以并不被大多数软件安装推荐,除非有绝对把握方可使用此优化级别。 
 
常用编译参数:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 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 --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 --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'  ./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 性能优化 缓存和压缩与限制可以提高性能 
1)缓存 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 location ~* \.(xml|html|htm)$ {      root /var/www/html;      access_log /path/to/file.log;      access_log on;      expires 24h; } location ~* \.(css|js|ico|gif|jpg|jpeg|png)$ {   root /var/www/html/res;      log_not_found off;      access_log off;      expires 7d; } location ~* \.(eot|ttf|otf|woff|woff2|svg)$ {   root /var/www/html/static;   log_not_found off;   access_log off;   expires max; } 
2)压缩
1 2 3 4 5 6 7 8 9 10 gzip on; gzip_min_length 2k; gzip_comp_level 2; gzip_types text/html 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; gzip_vary on; 
3)限制
1 2 3 4 5 limit_conn and limit_conn_zone   limit_req and limit_req_zon  limit_rate  max_conns  queue (NGINX Plus - 商业版本提供)  
简单示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 http {      limit_conn_zone $binary_remote_addr  zone=www_weiyigeek_top:10m;      limit_req_zone $binary_remote_addr  zone=blog_weiyigeek_top:10m rate=1r/s;   server {          allow 内部IP或负载均衡IP;     deny 恶意IP;               location ^~ /download/ {               limit_conn www_weiyigeek_top 2;               limit_req zone=blog_weiyigeek_top burst=5 nodelay;        alias  /data/weiyigeek.top/download/;     }   } } 
4)减少磁盘IO
1 2 3 4 5 6 access_log off; error_log /dev/null access_log /var/log /nginx/access.log main buffer=128k gzip flush=1m; 
 
3.4 运营优化 1) 永久重定向 
如果你的站点需要让http URL跳转到https,则非建议设置永久重定向,而非临时重定向,这可以帮助你站点更好的被收录(SEO)。
 
例如,配置 http 向 https 跳转 (永久)1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 server {   listen 80;   server_name weiyigeek.top www.weiyigeek.top;   return  301 https://$host $request_uri ; } server {   listen 80;   server_name weiyigeek.top www.weiyigeek.top;      if  ($http_host  !~ "^www\.weiyigeek\.top$"  {     rewrite ^(.*) https://www.weiyigeek.top$1  permanent;   } } 
3.5 配置优化 nginx配置文件指令优化一览表 
位置 
指令 
说明 
优化 
 
 
main 
worker_processes 
工作进程数的选择包括(但不限于)CPU核心的数量、存储数据的硬盘数量及负载模式 
设置 auto 或者   `cat /proc/cpuinfo  
grep processor 
wc -l`  服务器逻辑核心总数 
 
main 
worker_cpu_affinity 
Nginx默认未开启CPU绑定,绑定工作进程到对应CPU核心 
多核CPU建议设置CPU绑定,绑定样例: worker_processes    4;  worker_cpu_affinity 0001 0010 0100 1000;  
 
main 
worker_rlimit_nofile 
打开文件数限制(默认值1024),受限于系统的用户进程打开文件数限制,未设置则使用系统默认值 
修改用户打开文件数限制: echo "* - nofile 65536" >> /etc/security/limits.conf    echo "ulimit -n 65536" >> /etc/profile   
 
main 
worker_connections 
Nginx一个工作进程的最大同时连接数,不仅限于客户端连接,包括了和后端被代理服务器等其他的连接 
建议设置成与   worker_rlimit_nofile   值相等 
 
mian 
sendfile 
在http或server或location环境中包含sendfile指令。 
建议设置成 on 
 
main-events 
accept_mutex 
惊群问题: 
on开启状态为了稳定参数值;   
 
main-events 
use 
定义了Nginx设置用于复用客户端线程的轮询方法(也可称多路复用网络IO模型),自然是选择效率更高的优先(默认即可) 
use epoll 
 
main 
open_file_cache 
开启关闭打开文件缓存默认值 off 关闭,强烈建议开启可以避免重新打开同一文件带来的系统开销节省响应时间 
max=数字设置缓存元素的最大数量  open_file_cache max=65536  inactive=60s   
 
main 
open_file_cache_valid 
设置检查open_file_cache缓存的元素的时间间隔 
80s 
 
main 
open_file_cache_min_uses 
设置在由open_file_cache指令的inactive参数配置的超时时间内文件应该被访问的最小次数。 
1 
 
main 
error_log 
错误的访问请求日志记录,当并发很大时Nginx的访问日志和错误日志的保存肯定会造成对磁盘的大量读写也将影响Nginx的性能 
注释即可 或者 错误日志设置为 error 或者 crit 
 
main-http 
access_log 
成功的访问请求日志记录, 如必须保存日志,可以按每日或者每时或者其它时间段对日志做切割,这也可以减小IO,虽然可能效果不是特别大,不过因为日志文件尺寸变小了很多,也方便查阅或归档分析日志 
建议开启日志记录级别 main  
 
main-http 
gzip 
默认开启了gzip压缩功能:增加CPU的处理时间和负载(默认即可)  
设置 gzip on 即可;(该模块中有附带参数) 
 
main-http 
keepalive_timeout 
空闲长连接保持打开状态的时间;复用之前已建立的TCP连接接收请求、发送回应,减少重新建立TCP连接的资源时间开销 
正数为开启持久连接(常规设置120)而0关闭。  
 
main-http 
keepalive_requests 
单个客户端长连接可以请求的数量但是当使用压力测试工具从一个客户端发送多个请求测试时,这个值设更高些特别有用 
默认值是100 
 
main-http-server-location 
expires 
浏览器缓存设置HTTP应答中的“Expires”和“Cache-Control”头标。”Expires”一般结合”Last-Modified”使用比较缓存时间,避免了从服务器再次传送文件内容减小了服务器压力,节省了带宽同时也提高了用户访问速度 
-1 表示永远过期不缓存,推荐静态文件如js/css等等访问设置 expires 30da; 
 
 
4.安全配置 描述:Nginx因为安全配置不合适导致的安全问题,Nginx的默认配置中存在一些安全问题,例如版本号信息泄露、未配置使用SSL协议等。
Nginx安全配置项: 
0.隐藏nginx服务及其版本 温馨提示: 在修改相应的源代码文件后需重新编译。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 static char ngx_http_server_string[] = "Server: LTWS"  ;  static u_char ngx_http_error_full_tail[] = "<center> NGINX_VER </center>"  "<hr><center> http://www.weiyigeek.com</center>"  "</body>"  "</html>"  ; static u_char ngx_http_error_tail[] = "<hr><center>LTWS</center>"  "</body>"  "</html>"  ; 
                weiyigeek.top-修改服务名及其版本对应文件
             
设置成功后验证:
                weiyigeek.top-验证服务名及其版本修改
             
1.低权限用户运行服务 应配置非root低权限用户来运行nginx服务,设置如下建立Nginx用户组和用户,采用user指令指运行用户
加固方法:1 2 3 4 5 6 groupadd nginxweb; useradd -M -g nginxweb -s /sbin/nologin nginxweb  user nginxweb 
2.配置SSL及其会话复用 我们应该为提供的站点配置Secure Sockets Layer Protocol (SSL协议),配置其是为了数据传输的安全,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 server {      listen 443 ssl http2;   listen [::]:443 ssl http2;            ssl_certificate      /etc/nginx/ssl/fullchain.cer;   ssl_certificate_key  /etc/nginx/ssl/weiyigeek.top.key;      ssl_session_timeout 1d;   ssl_session_cache shared:MozSSL:10m;     ...... } 
3.限制SSL协议与加密套件 不应使用不安全SSLv2、SSLv3协议即以下和存在脆弱性的加密套件(ciphers), 我们应该使用较新的TLS协议也应该优于旧的,并使用安全的加密套件。1 2 3 4 5 6 ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE:ECDH:AES:HIGH:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:!NULL:!aNULL:!eNULL:!EXPORT:!PSK:!ADH:!DH:!DES:!MD5:!RC4; ssl_prefer_server_ciphers  on; 
4.拦截垃圾信息 HTTP Referrer Spam是垃圾信息发送者用来提高他们正在尝试推广的网站的互联网搜索引擎排名一种技术,如果他们的垃圾信息链接显示在访问日志中,并且这些日志被搜索引擎扫描,则会对网站排名产生不利影响1 2 3 if  ( $http_referer  ~* (babes|forsale|girl|jewelry|love|nudit|organic|poker|porn|sex|teen) ){  return  403; } 
5.恶意扫描拦截 当恶意攻击者采用扫描器进行扫描时候利用use-agent判断是否是常用的工具扫描以及特定的版本,是则返回错误或者重定向;1 2 3 4 5 6 7 8 9 10 11 12 13 14 if  ($http_user_agent  ~* "java|python|perl|ruby|curl|bash|echo|uname|base64|decode|md5sum|select|concat|httprequest|httpclient|nmap|scan|nessus|wvs"  ) {    return  403; } if  ($http_user_agent  ~* ""  ) {    return  403; } location ~* \.(bak|swp|save|sh|sql|mdb|svn|git|old)$ {   rewrite ^/(.*)$  $host   permanent; } location /(admin|phpadmin|status)	{ deny all; } 
                weiyigeek.top-恶意扫描拦截
             
6.禁用WebDAV Nginx支持webdav,虽然默认情况下不会编译。如果使用webdav,则应该在Nginx策略中禁用此规则。
7.禁用Nginx状态模块 当访问一个特制的URL时,如”../nginx.status”,stub_status模块提供一个简短的Nginx服务器状态摘要,大多数情况下不应启用此模块。
8.关闭默认错误页上的Nginx版本号 如果在浏览器中出现Nginx自动生成的错误消息,默认情况下会包含Nginx的版本号,这些信息可以被攻击者用来帮助他们发现服务器的潜在漏洞
9.设置client_body_timeout超时 client_body_timeout设置请求体(request body)的读超时时间。仅当在一次readstep中,没有得到请求体,就会设为超时。超时后Nginx返回HTTP状态码408(Request timed out)。
client_header_timeout设置等待client发送一个请求头的超时时间(例如:GET / HTTP/1.1)。仅当在一次read中没有收到请求头,才会设为超时。超时后Nginx返回HTTP状态码408(Request timed out)。
加固方法:nginx.conf文件中client_header_timeout应设置为:10
11.设置keepalive_timeout超时 keepalive_timeout设置与client的keep-alive连接超时时间。服务器将会在这个时间后关闭连接。
加固方法:nginx.conf文件中keepalive_timeout应设置为:55
12.设置send_timeout超时 send_timeout设置客户端的响应超时时间。这个设置不会用于整个转发器,而是在两次客户端读取操作之间。如果在这段时间内,客户端没有读取任何数据,Nginx就会关闭连接。
加固方法:nginx.conf文件中send_timeout应设置为:10
13.Nginx可用的方法应限制为GET, HEAD, POST GET和POST是Internet上最常用的方法。Web服务器方法在RFC 2616中定义禁用不需要实现的可用方法。
加固方法:1 2 if  ($request_method  !~ ^(GET|HEAD|POST)$ )
14.控制并发连接limit_zone slimits limit_zone 配置项限制来自客户端的同时连接数。通过此模块可以从一个地址限制分配会话的同时连接数量或特殊情况。
加固方法:nginx.conf文件中limit_zone应设置为:slimits $binary_remote_addr 5m1 2 limit_conn_zone $binary_remote_addr  zone=ops:10m; 
15.控制并发连接limit_conn slimits 该配置项控制一个会话同时连接的最大数量,即限制来自单个IP地址的连接数量。
加固方法:nginx.conf 文件中 limit_conn 应设置为: slimits 5
16.主机防webshell跨目录浏览以及列目录 加固方法:1 2 3 4 5 6 7 a.在nginx.conf里把每个虚拟主机站点请求端口给区别开 b.为每个站点建一个conf,并进行配置 c.修改php-fpm启动脚本 d.启动服务 autoindex off 
17.文件名解析漏洞php_info,加入fcgi.conf即可 1 2 3 4 5 6 7 if  ($request_filename  ~* (.*)\.php) {    set  $php_url  $1 ; } if  (!-e $php_url .php) {    return  403; } 
18.访问权限控制nginx 加固方法:1 2 3 4 5 6 7 8 9 10 11 12 13 location ~ ^/script/ {     auth_basic "welcome to weiyigeek.github.io" ;     auth_basic_user_file /var/www/test /script/.htpasswd; } mkdir /var/www/test /script perl -e "print crypt('baidu.eud'," n");"  nnUygd3RSf3u6 echo  'nginx:nnUygd3RSf3u6'  > /var/www/test /script/.htpasswd/usr/local /nginx/sbin/nginx -s reload 
                weiyigeek.top-
             
19.异常状态返回200隐藏URL 解决办法:1 2 3 4 5 6 7 server{   listen       80;   server_name  weiyigeek.top;   index index.html index.htm index.php;   root  /data/web;   error_page 404 =200 /404.jpg; } 
20.安全模块的选择 1 2 3 4 5 http_sub_module http_stub_status_module xss-nginx-module with-http_ssl_module 
21.记录访问者真实IP 描述后端获取Proxy后的真实Client的IP获取需要安装--with-http_realip_module,然后后端程序采用JAVA(request.getAttribute("X-Real-IP"))进行获取;1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 set_real_ip_from 100.0.0.0/8; real_ip_header X-Forwarded-For; real_ip_recursive on; location / {   proxy_pass http://weiyigeek.top } proxy_set_header Host $host ; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for ; set  $Real  $http_x_forwarded_for ;if  ( $Real  ~ (\d+)\.(\d+)\.(\d+)\.(\d+),(.*) ){    set  $Real  $1 .$2 .$3 .$4 ; } proxy_set_header X-Real-IP $remote_addr ; $proxy_add_x_forwarded_for  $http_x_forwarded_for $http_x_real_ip |$remote_addr   
22.地区访问响应措施 描述: 如果要使用geoip地区选择,我们需要再nginx编译时加入 --with-http_geoip_module 编译参数。1 2 3 4 # 例如,访问者IP地址不为中国或者美国的都返回403。 if ( $geoip_country_code !~  ^(CN|US)$ ) {   return 403; } 
23.资源防盗链设置 描述: 为了防止外部站点引用我们的静态资源,我们需要设置那些域名可以访问我们的静态资源。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 location ~* \.(gif|jpg|png|swf|flv)$ {    valid_referers none blocked weiyigeek.top server_names ~\.google\. ~\.baidu\.;    if  ($invalid_referer ) {           return  403;           add_header Content-Type 'application/json; charset=utf-8' ;     return  200 "{'msg':'valid'}" ;           rewrite ^/.*.(gif|jpg|jpeg|png)$ /static/qrcode.jpg last;          rewrite ^/ https://www.weiyigeek.top/picture/images/details-image-1.jpg;   }  } 
24.常规安全响应头配置 描述: 下面收集了Web服务中常规的安全响应头, 它可以保证不受到某些攻击,建议在指定的 server{} 代码块进行配置。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 add_header Strict-Transport-Security "max-age=31536000;includeSubDomains;preload"  always; add_header X-XSS-Protection "1; mode=block" ; add_header X-Content-Type-Options nosniff; add_header X-Frame-Options ALLOW-FROM music.163.com; add_header X-Robots-Tag none; add_header Access-Control-Allow-Origin '*.weiyigeek.top' ; add_header Access-Control-Allow-Methods 'GET' ; add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization' ; Content-Security-Policy: default-src 'none' ; script-src 'self'  https://code.jquery.com https://www.google-analytics.com; img-src 'self'  https://www.google-analytics.com; connect-src 'self' ; font-src 'self' ; style-src 'self' ; 
25.防止非所属域名解析到服务器 描述: 为了防止某些未备案的域名或者恶意镜像站域名绑定到我们服务器上, 导致服务器被警告关停,将会对业务或者SEO排名以及企业形象造成影响,我们可以通过如下方式进行防范。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 server {   listen 80 default_server;   server_name 82.156.18.253;      add_header X-Robots-Tag 'noindex,noarchive,nosnippet' ;   location ^~ / {          if  ( $host  = 82.156.18.253 ){       return  301 https://www.weiyigeek.top/index.html;     }          if  ( $host  !~* weiyigeek\.top ) {       add_header Content-Type 'application/json; charset=utf-8' ;       return  200 '{"status":"error","Author":"WeiyiGeek","Site":"https://www.weiyigeek.top","Chinese":"大佬, 请不要把你的域名解析到我的服务器上","English":"Friend, Please do not resolve your domain name to my server"}' ;            }   } ... } 
执行结果: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 $ curl -I 82.156.18.253 HTTP/1.1 301 Moved Permanently Server: nginx Date: Mon, 11 Apr 2022 12:15:02 GMT Content-Type: text/html Content-Length: 162 Connection: keep-alive Location: https://www.weiyigeek.top/index.html X-Robots-Tag: noindex,noarchive,nosnippet $ curl --insecure -I https://82.156.18.253 HTTP/2 301 server: nginx date: Mon, 11 Apr 2022 12:15:24 GMT content-type: text/html content-length: 162 location: https://www.weiyigeek.top/index.html x-robots-tag: noindex,noarchive,nosnippet $ curl weiyigeek.cn {"status" :"error" ,"Author" :"WeiyiGeek" ,"Site" :"https://www.weiyigeek.top" ,"Chinese" :"大佬, 请不要把你的域名解析到我的服务器上" ,"English" :"Friend, Please do not resolve your domain name to my server" } 
25.限制指定客户端地址访问 描述: 有时你的网站可能只需要被某一IP或者IP段的地址请求访问,那么非白名单中的地址访问将被阻止访问, 我们可以如下配置;1 2 3 4 5 6 location / {   allow  12.97.167.194;    allow  12.33.1.2;    allow  12.152.49.4;   deny  all; } 
5.配置说明 常用nginx配置文件解释: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 user nginx; worker_processes  auto; events {               worker_connections  65535;                use epoll;          accept_mutex off; } worker_cpu_affinity 0001 0010 0100 1000;  worker_rlimit_nofile 65535 error_log logs/error.log  error; pid /var/run/nginx.pid; include /etc/nginx/conf.d/*.conf;  http {          include       mime.types;          default_type  text/html;          charset UTF-8;          server_names_hash_bucket_size  128;          client_body_buffer_size 128k          client_header_buffer_size 4k;          client_max_body_size 50m          open_file_cache max=65536  inactive=60s;     open_file_cache_valid      80s;     open_file_cache_min_uses   1;     large_client_header_buffers 4 64k;           log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '                        '$status $body_bytes_sent "$http_referer" '                       '"$http_user_agent" "$http_x_forwarded_for"' ;     log_format custom '$remote_addr - $remote_user [$time_local] "$request" '                      '$status $body_bytes_sent "$http_referer" '                      '"$http_user_agent" "$http_x_forwarded_for" rt=$request_time urt=$upstream_response_time' ;          access_log  logs/access.log  main buffer=1024 flush=60s;     access_log  /var/log /nginx/access.log  custom buffer=128k flush=5m;          server_tokens off;                         sendfile        on;           tcp_nopush on;      tcp_nodelay on;                keepalive_timeout  120;                                   gzip  on;          gzip_min_length 1k;          gzip_buffers 4 64k;          gzip_http_version 1.1;          gzip_comp_level 2;          gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;                                                                                                                                                 server {                  listen       80;                           server_name  localhost;                  return  301 https://$host $request_uri ;                           location / {                          root   html;                          index  index.html index.htm;                                                                              allow 192.168.10.100;             allow 172.29.73.0/24;             deny all;                                                    auth_basic "Nginx Status"              auth_basic_user_file /usr/local /nginx/nginx.passwd                                                                                                                 }                                    error_page   500 502 503 504  /50x.html;         location = /50x.html {             root   html;         }                                                                                                                                                                                             location ~ .+\.(gif|jpg|jpeg|png|bmp|swf|txt|csv|doc|docx|xls|xlsx|ppt|pptx|flv)$ {             root  e:wwwroot;            expires 30d;             access_log off;          }                   location ~ .+\.(js|css|html|xml)$ { expires 30d;}                  location /nginx-status{                          stub_status on;             allow 192.168.1.0/24;             allow 127.0.0.1;             deny all;         }     }                    upstream monitor_server {                  ip_hash;                                    server 192.168.0.131:80 weight=9 max_fails=5 fail_timeout=600s;           server 192.168.0.132:80 weight=1 max_fails=5 fail_timeout=600s;     }                     server {          listen 80;                   server_name blog.weiyigeek.top;                   location / {                                 proxy_pass http://monitor_server;                                 proxy_redirect off;                      proxy_set_header Host $host ;                      proxy_set_header X-Real-IP $remote_addr ;                      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for ;                                             proxy_connect_timeout 60s;                                   proxy_read_timeout 60s;                                      proxy_send_timeout 30s;                                 proxy_buffer_size 4k                      proxy_buffers 4 32k                                 proxy_busy_buffers_size 64k                                            proxy_max_temp_file_size 0                                 proxy_temp_file_write_size 64k                                 client_max_body_size        100m;                                                                                      }                           location ~ .(jsp|jspx|do )?$ {             proxy_set_header Host $host ;             proxy_set_header X-Real-IP $remote_addr ;             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for ;             proxy_pass http://127.0.0.1:8080;         }                  location ~ \.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$ { expires 15d; }         location ~ \.(js|css)$ { expires 1h; }     }                server {       listen 80;       listen [::]:80;       server_name weiyigeek.top;       return  301 https://$host $request_uri ;    }     server {     listen 443 ssl http2;     listen [::]:443 ssl http2;     server_name weiyigeek.top;          add_header Strict-Transport-Security "max-age=31536000;includeSubDomains;preload"  always;          add_header X-XSS-Protection "1; mode=block" ;          add_header X-Content-Type-Options nosniff;          add_header X-Frame-Options ALLOW-FROM music.163.com;                                   ssl_certificate      /etc/nginx/ssl/fullchain.cer;     ssl_certificate_key  /etc/nginx/ssl/weiyigeek.top.key;          ssl_session_timeout 1d;     ssl_session_cache shared:MozSSL:10m;            ssl_session_tickets off;            ssl_stapling on;     ssl_stapling_verify on;          ssl_trusted_certificate /etc/nginx/ssl/ca.cer;               ssl_dhparam /path/to/dhparam;          ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;     ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE:ECDH:AES:HIGH:EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:!NULL:!aNULL:!eNULL:!EXPORT:!PSK:!ADH:!DH:!DES:!MD5:!RC4;               ; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:HIGH:!NULL:!aNULL:!eNULL:!EXPORT:!PSK:!ADH:!DES:!MD5:!RC4;               ssl_prefer_server_ciphers  on;          resolver 223.6.6.6 8.8.8.8 192.168.12.254;   } } 
为了更好的指导部署与测试系统,在保证nginx网站服务器高性能的同时下,为了保证其安全稳定运行,我们需要对nginx服务进行调优与加固; 本次进行Nginx服务调优加固主要从以下几个部分,模块性能优化,系统内核优化,编译安装优化,性能参数优化,安全加固配置,