Contents

Nginx 安全加固与性能调优最佳指南

1.引言

1.1 目的

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

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

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

1.2 目标范围

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

1.3 读者对象

  • 项目经理
  • 开发人员
  • 测试人员
  • 运维人员
  • 相关领导

2.参考说明

2.1 帮助参考

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

Nginx 版本选择:

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

项目结构:

/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/html

Nginx 配置文件:

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

2.2 参数说明

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

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

Nginx 匹配判断表达式:

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

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

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

3.3 模块说明

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

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

http_gzip 模块

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

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

http_fastcgi_module 模块

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

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

keepalive 模块

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

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

http_ssl_module 模块

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

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

3.服务优化

3.1 系统内核

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

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

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

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

文件描述符

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

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

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

3.2 编译优化

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

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

  • 编译 Nginx 时默认以 debug 模式进行,而在 debug 模式下会插入很多跟踪和 ASSERT 之类的信息,编译完成后一个 Nginx 要有好几兆字节;因此可以在编译之前,修改相关源码,取消 debug 模式;
1# 找到源码目录下 auto/cc/gcc 文件 debug
2
3CFLAGS="$CFLAGS -g" #注释掉或删掉这两行,即可取消 debug 模式。
4
5ls -alh /usr/local/nginx/sbin/nginx
6-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'选项
1  --with-cc-opt='-O3' #编译级别
2  --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 性能并未有较多提高,编译时间也最长,生成的目标文件也更大更占内存,有时性能不增反而降低,甚至产生不可预知的问题(包括错误),所以并不被大多数软件安装推荐,除非有绝对把握方可使用此优化级别。

常用编译参数:

 1#编译 0:常规编译参数
 2configure arguments: #安装的目录或者路径#
 3--prefix=/etc/nginx
 4--sbin-path=/usr/sbin/nginx
 5--modules-path=/usr/lib64/nginx/modules
 6--conf-path=/etc/nginx/nginx.conf
 7--error-log-path=/var/log/nginx/error.log
 8--http-log-path=/var/log/nginx/access.log
 9--pid-path=/var/run/nginx.pid
10--lock-path=/var/run/nginx.lock #执行对应模块 nginx 所保留的临时文件#
11--http-client-body-temp-path=/var/cache/nginx/client_temp
12--http-proxy-temp-path=/var/cache/nginx/proxy_temp
13--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp
14--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp
15--http-scgi-temp-path=/var/cache/nginx/scgi_temp #启动的用户和组用户#
16--user=nginx
17--group=nginx #模块参数#
18--with-compat
19--with-file-aio
20--with-threads
21--with-http_addition_module
22--with-http_auth_request_module
23--with-http_dav_module
24--with-http_flv_module
25--with-http_gunzip_module
26--with-http_gzip_static_module
27--with-http_mp4_module
28--with-http_random_index_module
29--with-http_realip_module
30--with-http_secure_link_module
31--with-http_slice_module
32--with-http_ssl_module
33--with-http_stub_status_module
34--with-http_sub_module
35--with-http_v2_module
36--with-mail
37--with-mail_ssl_module
38--with-stream
39--with-stream_realip_module
40--with-stream_ssl_module
41--with-stream_ssl_preread_module #设置额外的参数将被添加到 CFLAGS#
42--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' #设置附件参数,链接系统库#
43-with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'
44
45#编译 1:除多余模块
46./configure \
47"--prefix=/App/nginx" \
48"--user=nginx" \
49"--group=nginx" \
50"--with-http_stub_status_module" \
51"--without-http_auth_basic_module" \
52"--without-http_autoindex_module" \
53"--without-http_browser_module" \
54"--without-http_empty_gif_module" \
55"--without-http_geo_module" \
56"--without-http_limit_conn_module" \
57"--without-http_limit_req_module" \
58"--without-http_map_module" \
59"--without-http_memcached_module" \
60"--without-http_proxy_module" \
61"--without-http_referer_module" \
62"--without-http_scgi_module" \
63"--without-http_split_clients_module" \
64"--without-http_ssi_module" \
65"--without-http_upstream_ip_hash_module" \
66"--without-http_upstream_keepalive_module" \
67"--without-http_upstream_least_conn_module" \
68"--without-http_userid_module" \
69"--without-http_uwsgi_module" \
70"--without-mail_imap_module" \
71"--without-mail_pop3_module" \
72"--without-mail_smtp_module" \
73"--without-poll_module" \
74"--without-select_module" \
75"--with-cc-opt='-O2'"

3.3 性能优化

缓存和压缩与限制可以提高性能

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

1)缓存

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

 1# 网页资源缓存
 2
 3location ~\* \.(xml|html|htm)$ {
 4
 5# 资源决绝对目录设置
 6
 7root /var/www/html;
 8
 9# 日志文件的相对路径或完整路径
10
11access_log /path/to/file.log;
12
13# 开启日志记录
14
15access_log on;
16
17# 设置过期时间
18
19expires 24h;
20}
21
22# 样式、JS、图片资源缓存
23
24location ~\* \.(css|js|ico|gif|jpg|jpeg|png)$ {
25root /var/www/html/res;
26
27# 禁用 404 错误日志
28
29log_not_found off;
30
31# 关闭日志
32
33access_log off;
34
35# 缓存时间 7 天
36
37expires 7d;
38}
39
40# 字体资源缓存
41
42location ~\* \.(eot|ttf|otf|woff|woff2|svg)$ {
43root /var/www/html/static;
44log_not_found off;
45access_log off;
46expires max;
47}

2)压缩

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

 1
 2# 启用 gzip 压缩
 3
 4gzip on;
 5
 6# 启用 gzip 压缩的最小文件,小于设置值的文件将不会压缩
 7
 8gzip_min_length 2k;
 9
10# gzip 压缩级别,1-10,数字越大压缩的越好,也越占用 CPU 时间,后面会有详细说明
11
12gzip_comp_level 2;
13
14# 进行压缩的文件类型,javascript 有多种形,其中的值可以在 mime.types 文件中找到。
15
16gzip_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;
17
18# 建议在 http header 中添加 Vary: Accept-Encoding 支持
19
20gzip_vary on;

3)限制

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

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

简单示例:

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

4)减少磁盘 IO

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

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

3.4 运营优化

  1. 永久重定向

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

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

 1# 方式 1.Redirect(重定向)- 推荐
 2
 3server {
 4  listen 80;
 5  server_name weiyigeek.top www.weiyigeek.top;
 6  return 301 https://$host$request_uri;
 7}
 8
 9# 方式 2.ReWrite 重写
10
11server {
12  listen 80;
13  server_name weiyigeek.top www.weiyigeek.top;
14
15  # 判断请求 host 是否是 www.weiyigeek.top ,如果是 weiyigeek.top 则重写为 www.weiyigeek.top
16
17  if ($http_host !~ "^www\.weiyigeek\.top$" {
18    rewrite ^(.\*) https://www.weiyigeek.top$1 permanent;
19  }
20}

3.5 配置优化

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

4.安全配置

描述:Nginx 因为安全配置不合适导致的安全问题,Nginx 的默认配置中存在一些安全问题,例如版本号信息泄露、未配置使用 SSL 协议等。 对 Nginx 进行安全配置可以有效的防范一些常见安全问题,按照基线标准做好安全配置能够减少安全事件的发生,保证采用 Nginx 服务器系统应用安全运行;

Nginx 安全配置项:

0.隐藏 nginx 服务及其版本

温馨提示: 在修改相应的源代码文件后需重新编译。

 1 #方式 1:
 2#vi nginx-1.9.11/src/http/ngx_http_header_filter_module.c
 3static char ngx_http_server_string[] = "Server: LTWS" ; #修改处 #修改 nginx_http_header_filter_module
 4#vi nginx-1.9.11/src/http/ngx_http_special_response.c
 5static u_char ngx_http_error_full_tail[] =
 6"<center> NGINX_VER </center>"
 7"<hr><center> http://www.weiyigeek.com</center>"
 8"</body>"
 9"</html>"
10;
11
12static u_char ngx_http_error_tail[] =
13"<hr><center>LTWS</center>"
14"</body>"
15"</html>"
16;
17
18#设置响应头版本版本
19#vim src/core/nginx.h
20#define NGINX_VERSION "secWaf" #可以改成你要的版本号
21#define NGINX_VER "1.1" NGINX_VERSION #改成你的服务名称

WeiyiGeek.

修改服务名及其版本对应文件

设置成功后验证:

WeiyiGeek.

验证服务名及其版本修改

1.低权限用户运行服务

应配置非 root 低权限用户来运行 nginx 服务,设置如下建立 Nginx 用户组和用户,采用 user 指令指运行用户

加固方法:

1groupadd nginxweb;
2useradd -M -g nginxweb -s /sbin/nologin nginxweb
3
4#nginx.conf 中配置 或者编译 的时候指定
5#nginx 安装编译参数--user=nginx --group=nginx
6user nginxweb

2.配置 SSL 及其会话复用

我们应该为提供的站点配置 Secure Sockets Layer Protocol (SSL 协议),配置其是为了数据传输的安全,SSL 依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。

 1server {
 2
 3# 开启 SSL 与 http2 支持
 4
 5listen 443 ssl http2;
 6listen [::]:443 ssl http2;
 7
 8# 开启 SSL ,如果想 http 与 https 公用一个配置则可以将其注释( the "ssl" directive is deprecated )
 9
10# ssl on;
11
12# 配置证书链与证书密钥
13
14ssl_certificate /etc/nginx/ssl/fullchain.cer;
15ssl_certificate_key /etc/nginx/ssl/weiyigeek.top.key;
16
17# ssl 会话复用超时时间以及会话复用缓存大小
18
19ssl_session_timeout 1d;
20ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
21......
22}

3.限制 SSL 协议与加密套件

不应使用不安全 SSLv2、SSLv3 协议即以下和存在脆弱性的加密套件(ciphers), 我们应该使用较新的 TLS 协议也应该优于旧的,并使用安全的加密套件。

1
2# 兼容性较为通用的 SSL 协议与加密算法套件
3
4ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
5ssl_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;
6
7# 浏览器客户端自动协商加密套件(为了兼容性)
8
9ssl_prefer_server_ciphers on;

4.拦截垃圾信息

HTTP Referrer Spam 是垃圾信息发送者用来提高他们正在尝试推广的网站的互联网搜索引擎排名一种技术,如果他们的垃圾信息链接显示在访问日志中,并且这些日志被搜索引擎扫描,则会对网站排名产生不利影响

加固方法:

1if ( $http_referer ~\* (babes|forsale|girl|jewelry|love|nudit|organic|poker|porn|sex|teen) ){
2  return 403;
3}

5.恶意扫描拦截

当恶意攻击者采用扫描器进行扫描时候利用 use-agent 判断是否是常用的工具扫描以及特定的版本,是则返回错误或者重定向;

 1# 封杀各种 user-agent
 2
 3if ($http_user_agent ~\* "java|python|perl|ruby|curl|bash|echo|uname|base64|decode|md5sum|select|concat|httprequest|httpclient|nmap|scan|nessus|wvs" ) {
 4return 403;
 5}
 6
 7if ($http_user_agent ~\* "" ) {
 8return 403;
 9}
10
11# 封杀特定的文件扩展名比如.bak 以及目录;
12
13location ~_ \.(bak|swp|save|sh|sql|mdb|svn|git|old)$ {
14rewrite ^/(._)$ $host permanent;
15}
16location /(admin|phpadmin|status) { deny all; }

WeiyiGeek.

恶意扫描拦截

6.禁用 WebDAV

Nginx 支持 webdav,虽然默认情况下不会编译。如果使用 webdav,则应该在 Nginx 策略中禁用此规则。

加固方法: dav_methods 应设置为 off

7.禁用 Nginx 状态模块

当访问一个特制的 URL 时,如”../nginx.status”,stub_status 模块提供一个简短的 Nginx 服务器状态摘要,大多数情况下不应启用此模块。

加固方法:nginx.conf 文件中 stub_status 不应设置为:on

8.关闭默认错误页上的 Nginx 版本号

如果在浏览器中出现 Nginx 自动生成的错误消息,默认情况下会包含 Nginx 的版本号,这些信息可以被攻击者用来帮助他们发现服务器的潜在漏洞

加固方法: 关闭”Server”响应头中输出的 Nginx 版本号将 server_tokens应设置为:off

1server_tokens off

9.设置 client_body_timeout 超时

client_body_timeout 设置请求体(request body)的读超时时间。仅当在一次 readstep 中,没有得到请求体,就会设为超时。超时后 Nginx 返回 HTTP 状态码 408(Request timed out)。

加固方法:nginx.conf 文件中 client_body_timeout 应设置为:10

10.设置 client_header_timeout

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#nginx.conf 文件中应存在
2if ($request_method !~ ^(GET|HEAD|POST)$ )

14.控制并发连接 limit_zone slimits

limit_zone 配置项限制来自客户端的同时连接数。通过此模块可以从一个地址限制分配会话的同时连接数量或特殊情况。

加固方法:nginx.conf 文件中 limit_zone 应设置为:slimits $binary_remote_addr 5m

1# 设定保存各个键(例如$binary_remote_addr)状态的共享内存空间的参数,zone=空间名字:大小大小的计算与变量有关
2
3limit_conn_zone $binary_remote_addr zone=ops:10m;

15.控制并发连接 limit_conn slimits

该配置项控制一个会话同时连接的最大数量,即限制来自单个 IP 地址的连接数量。

加固方法:nginx.conf 文件中 limit_conn 应设置为: slimits 5

1# 表示同一 IP 同一时间只允许 10 个连接
2
3limit_conn ops 5;

16.主机防 webshell 跨目录浏览以及列目录

加固方法:

1a.在 nginx.conf 里把每个虚拟主机站点请求端口给区别开
2b.为每个站点建一个 conf,并进行配置
3c.修改 php-fpm 启动脚本
4d.启动服务
5
6#在 main-http-server 段中设置开启或者关闭(对于需要列目录的则开启,否则默认是关闭的)
7autoindex off

17.文件名解析漏洞 php*info,加入 fcgi.conf 即可

1if ($request_filename ~\* (.\_)\.php) {
2  set $php_url $1;
3}
4
5if (!-e $php_url.php) {
6  return 403;
7}

18.访问权限控制 nginx

加固方法:

 1#nginx.conf
 2location ~ ^/script/ {
 3  auth_basic "welcome to weiyigeek.github.io";
 4  auth_basic_user_file /var/www/test/script/.htpasswd;
 5}
 6
 7#建立 htpasswd 密码进行认证
 8mkdir /var/www/test/script
 9perl -e "print crypt('baidu.eud',"n");"
10nnUygd3RSf3u6
11
12echo 'nginx:nnUygd3RSf3u6' > /var/www/test/script/.htpasswd
13/usr/local/nginx/sbin/nginx -s reload

19.异常状态返回 200 隐藏 URL

解决办法:

1server{
2  listen 80;
3  server_name weiyigeek.top;
4  index index.html index.htm index.php;
5  root /data/web;
6  error_page 404 =200 /404.jpg;
7}

20.安全模块的选择

1# 安全检测模块选择
2http_sub_module
3http_stub_status_module
4xss-nginx-module
5with-http_ssl_module

21.记录访问者真实 IP

描述后端获取 Proxy 后的真实 Client 的 IP 获取需要安装--with-http_realip_module,然后后端程序采用 JAVA(request.getAttribute("X-Real-IP"))进行获取;

 1set_real_ip_from 100.0.0.0/8;#(这里是已知的代理 ip)
 2real_ip_header X-Forwarded-For;
 3real_ip_recursive on;
 4
 5# 代理转发
 6
 7location / {
 8  proxy_pass http://weiyigeek.top
 9}
10
11proxy_set_header Host $host;
12proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
13set $Real $http_x_forwarded_for;
14if ( $Real ~ (\d+)\.(\d+)\.(\d+)\.(\d+),(.\*) ){
15  set $Real $1.$2.$3.$4;
16}
17proxy_set_header X-Real-IP $remote_addr;
18
19#区别
20$proxy_add_x_forwarded_for #较下面多一个$remote_addr 的(只能获取到与服务器本身直连的上层请求 ip)
21$http_x_forwarded_for
22
23#日志获取
24$http_x_real_ip|$remote_addr #前提条件是 cdn 那边也设置了 X-forward 否则获取的是 cdn 的 ip

22.地区访问响应措施

描述: 如果要使用 geoip 地区选择,我们需要再 nginx 编译时加入 --with-http_geoip_module 编译参数。

1# 例如,访问者 IP 地址不为中国或者美国的都返回 403。
2
3if ( $geoip_country_code !~  ^(CN|US)$ ) {
4  return 403;
5}

23.资源防盗链设置

描述: 为了防止外部站点引用我们的静态资源,我们需要设置那些域名可以访问我们的静态资源。

 1# none : "Referer" 来源头部为空的情况
 2
 3# blocked : "Referer" 来源头部不为空
 4
 5# server_names : "Referer"来源头部包含当前的 server_names(当前域名)
 6
 7location ~\* \.(gif|jpg|png|swf|flv)$ {
 8  valid_referers none blocked weiyigeek.top server_names ~\.google\. ~\.baidu\.; #这是可以盗链的域名或 IP 地址,一般情况可以把 google,baidu,sogou,soso,bing,feedsky,zhuaxia,photozero 等域名放进来
 9  if ($invalid_referer) { #这样设置能够防盗链,不断地 302 重定向很多次,可能会加重服务器的负担,所以不建议这么做,除非有单独的图片服务器支持
10    return 403; # 或者返回 403 错误代码 或者 JSON 字符串
11
12    # 返回json
13    add_header Content-Type 'application/json; charset=utf-8';
14    return 200 "{'msg':'valid'}";
15    # 本地目录重写
16    rewrite ^/.*.(gif|jpg|jpeg|png)$ /static/qrcode.jpg last;
17    # 重写远程URL
18    rewrite ^/ https://www.weiyigeek.top/picture/images/details-image-1.jpg;
19
20  }
21}

24.常规安全响应头配置

描述: 下面收集了 Web 服务中常规的安全响应头, 它可以保证不受到某些攻击,建议在指定的 server{} 代码块进行配置。

 1
 2# HSTS (ngx_http_headers_module is required) 应该只使用 HTTPS 而不是使用 HTTP 通信
 3
 4add_header Strict-Transport-Security "max-age=31536000;includeSubDomains;preload" always;
 5
 6# XXS-Protection
 7
 8add_header X-XSS-Protection "1; mode=block";
 9
10# MIME 模拟探测
11
12add_header X-Content-Type-Options nosniff;
13
14# Frame 安全控制
15
16add_header X-Frame-Options ALLOW-FROM music.163.com;
17
18# Spider Robots 爬取策略限制
19
20add_header X-Robots-Tag none;
21
22# CORS 跨域设置
23
24add_header Access-Control-Allow-Origin '\*.weiyigeek.top';
25add_header Access-Control-Allow-Methods 'GET';
26add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
27
28# CSP
29
30# 现在让我们允许自托管 scripts、images、CSS、fonts 和 AJAX,以及 jQuery CDN 托管脚本和 Google Analytics 的内容:
31
32Content-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 排名以及企业形象造成影响,我们可以通过如下方式进行防范。

 1server {
 2  listen 80 default_server;
 3  server_name 82.156.18.253;
 4
 5
 6
 7# 禁止搜索引擎收录 IP
 8
 9add_header X-Robots-Tag 'noindex,noarchive,nosnippet';
10location ^~ / { # IP 地址访问强制 301 跳转
11  if ( $host = 82.156.18.253 ){
12    return 301 https://www.weiyigeek.top/index.html;
13  } # 请求 host 非指定域名时返回 json
14  if ( $host !~\* weiyigeek\.top ) {
15    add_header Content-Type 'application/json; charset=utf-8';
16    return 200 '{"status":"error","Author":"WeiyiGeek","Site":"https://www.weiyigeek.top","Chinese":"大佬, 请不要把你的域名解析到我的服务器上","English":"Friend, Please do not resolve your domain name to my server"}'; # return 301 https://space.bilibili.com/385802642;
17  }
18}
19...
20}

执行结果:

 1$ curl -I 82.156.18.253
 2HTTP/1.1 301 Moved Permanently
 3Server: nginx
 4Date: Mon, 11 Apr 2022 12:15:02 GMT
 5Content-Type: text/html
 6Content-Length: 162
 7Connection: keep-alive
 8Location: https://www.weiyigeek.top/index.html
 9X-Robots-Tag: noindex,noarchive,nosnippet
10
11$ curl --insecure -I https://82.156.18.253
12HTTP/2 301
13server: nginx
14date: Mon, 11 Apr 2022 12:15:24 GMT
15content-type: text/html
16content-length: 162
17location: https://www.weiyigeek.top/index.html
18x-robots-tag: noindex,noarchive,nosnippet
19
20$ curl weiyigeek.cn
21{"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 段的地址请求访问,那么非白名单中的地址访问将被阻止访问, 我们可以如下配置;

1location / {
2  allow 12.97.167.194;
3  allow 12.33.1.2;
4  allow 12.152.49.4;
5  deny all;
6}

5.配置说明

常用 nginx 配置文件解释:

  1#[Main] Nginx 启动的用户(建议非 root 用户)
  2user nginx;
  3
  4#[Main] NGINX 工作进程数设置值和 CPU 核心数一致(优化选项) #采用 grep ^processor /proc/cpuinfo | wc -l 进行查看或者 auto
  5worker_processes auto;
  6
  7#[Main] 工作模式与连接数上限即每个工作进程可以处理并发的最大连接数(优化选项)
  8events { # [Main-events] nginx 作为反向代理服务器单个进程最大连接数(最大连接数=连接数\*进程数) #建议与 worker_rlimit_nofile 一致
  9worker_connections 65535; #[Main-events] use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; # epoll 模型是 Linux 2.6 以上版本内核中的高性能网络 I/O 模型,如果跑在 FreeBSD 上面,就用 kqueue 模型。
 10use epoll; # [Main-events] 提高性能和吞吐量
 11accept_mutex off;
 12}
 13
 14#[Main] 高并发参数(通过设置 cpu 粘性来降低由于多 CPU 核切换造成的寄存器等现场重建带来的性能损耗)(优化选项)
 15worker_cpu_affinity 0001 0010 0100 1000; # 四核的时候 #假如是 8 cpu 分配如下: worker_cpu_affinity 00000001 00000010 00000100 00001000 0001000000100000 01000000 10000000
 16
 17#[Main] 默认是没有设置,可以限制为操作系统最大的限制 65535。(优化选项)
 18worker_rlimit_nofile 65535
 19
 20#[Main]日志位置和日志级别[ debug | info | notice | warn | error | crit ]
 21#error_log logs/error.log;
 22#error_log logs/error.log notice;
 23#error_log logs/error.log info;
 24error_log logs/error.log error;
 25
 26#服务进程启动文件
 27pid /var/run/nginx.pid;
 28
 29#当前主配置文件包含其他的 nginx 模块配置文件
 30include /etc/nginx/conf.d/\*.conf;
 31
 32#[Main 部分] http 服务器提供 http 服务相关的一些配置参数。例如:是否使用 keepalive 啊,是否使用 gzip 进行压缩等。
 33http { #文件扩展名与文件类型映射表
 34include mime.types; #默认文件类型
 35default_type text/html; #响应的编码格式
 36charset UTF-8; #服务器名字的 hash 表大小
 37server_names_hash_bucket_size 128; #缓冲区代理缓冲用户端请求的最大字节数,
 38client_body_buffer_size 128k #上传文件大小限制
 39client_header_buffer_size 4k; #允许客户端请求的最大单文件字节数。如果有上传较大文件,请设置它的限制值
 40client_max_body_size 50m
 41
 42    #文件访问缓存设置与系统文件描述符设置一致
 43    open_file_cache max=65536  inactive=60s;
 44    open_file_cache_valid      80s;
 45    open_file_cache_min_uses   1;
 46
 47    large_client_header_buffers 4 64k; #设定请求缓
 48
 49    #nginx日志记录格式
 50    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
 51                      '$status $body_bytes_sent "$http_referer" '
 52                     '"$http_user_agent" "$http_x_forwarded_for"';
 53    log_format custom '$remote_addr - $remote_user [$time_local] "$request" '
 54                    '$status $body_bytes_sent "$http_referer" '
 55                    '"$http_user_agent" "$http_x_forwarded_for" rt=$request_time urt=$upstream_response_time';
 56    #使用缓冲而不是每条日志记录都单独执行写操作,NGINX会缓冲一连串的日志记录使用单个操作把它们一起写到文件中。
 57    access_log  logs/access.log  main buffer=1024 flush=60s;
 58    access_log  /var/log/nginx/access.log  custom buffer=128k flush=5m;
 59
 60    #关闭server信息头响应
 61    server_tokens off;
 62
 63    #[MAIN-http]开启高效文件传输模式,指定nginx是否调用sendfile函数来输出文件,减少用户空间到内核空间的上下文切换(与accept_mutex关联配置)
 64    #对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。
 65    #系统调用可以实现从一个文件描述符到另一个文件描述符的数据拷贝,通常实现零拷贝,这能加速TCP数据传输
 66    #当配置环境下有sendfile指令和激活内容更改过滤器的指令时NGINX会自动禁用sendfile。#(优化选项)
 67    sendfile        on;
 68    #防止网络阻塞,不过要包涵在keepalived参数才有效
 69    tcp_nopush on;
 70    tcp_nodelay on;
 71
 72    #空闲长连接保持打开状态的时间(优化选项)
 73    #长连接请求大量小文件的时候,可以减少重建连接的开销,但假如有大文件上传120s内没上传完成会导致失败。如果设置时间过长,用户又多,长时间保持连接会占用大量资源。
 74    keepalive_timeout  120;
 75
 76    #用于指定响应客户端的超时时间。这个超时仅限于两个连接活动之间的时间,如果超过这个时间客户端没有任何活动,Nginx将会关闭连接
 77    #send_timeout  180s
 78
 79    ###模块http_gzip#####
 80    #开启gzip压缩输出,减少网络传输。
 81    gzip  on;
 82    #最小压缩文件大小(注意不能小于1k)
 83    gzip_min_length 1k;
 84    #压缩缓冲区
 85    gzip_buffers 4 64k;
 86    #压缩版本(默认1.1,前端如果是squid2.5请使用1.0)
 87    gzip_http_version 1.1;
 88    #压缩等级
 89    gzip_comp_level 2;
 90    ##压缩类型,默认就已经包含text/html,
 91    gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
 92
 93    ###模块fastcgi#####
 94    #FastCGI相关参数是为了改善网站的性能:减少资源占用,提高访问速度。
 95    # fastcgi_temp_path  /tmp/fastcgi_temp;
 96    # fastcgi_cache_path /tmp/fastcgi_cache levels=1:2 keys_zone=cache_fastcgi:128m inactive=30m max_size=1g;
 97    # fastcgi_cache_key  $host$request_uri;
 98    #指定的Http状态码指定缓存时间
 99    # fastcgi_cache_valid 200 302 1h;
100    # fastcgi_cache_valid 301 1d;
101    # fastcgi_cache_valid any 1m;
102    # fastcgi_cache_min_uses 1;
103    # fastcgi_cache_use_stale error timeout http_500 http_503 invalid_header;
104    #指定链接到后端FastCGI的超时时间。
105    # fastcgi_connect_timeout 300;
106    #向FastCGI传送请求的超时时间,这个值是指已经完成两次握手后向FastCGI传送请求的超时时间。
107    # fastcgi_send_timeout 300;
108    #指定接收FastCGI应答的超时时间,这个值是指已经完成两次握手后接收FastCGI应答的超时时间。
109    # fastcgi_read_timeout 300;
110    #指定读取FastCGI应答第一部分需要用多大的缓冲区,这个值表示将使用1个64KB的缓冲区读取应答的第一部分(应答头),可以设置为gastcgi_buffers选项指定的缓冲区大小。
111    # fastcgi_buffer_size 64k;
112    #一个php脚本所产生的页面大小为256KB,那么会分配4个64KB的缓冲区来缓存
113    # fastcgi_buffers 4 64k;
114    #建议设置为fastcgi_buffer的两倍,繁忙时候的buffer
115    # fastcgi_busy_buffers_size 128k;
116    # fastcgi_temp_file_write_size 128k;
117
118
119    #[Main-http]配置虚拟主机设置
120    #http服务上支持若干虚拟主机。每个虚拟主机一个对应的server配置项,配置项里面包含该虚拟主机相关的配置
121    server {
122        #[Main-http-server] ngnix监听端口
123        listen       80;
124
125        #服务器名:虚拟主机的域名可以写多个域名,可以通过正则匹配。
126        server_name  localhost;
127
128        #实现访问http时自动跳转到https
129        return 301 https://$host$request_uri;
130        #access_log  logs/host.access.log  main;
131
132        #请求正则匹配的来判断访问路径,默认访问localhost:80 访问的是下面这个路径的网页
133        location / {
134            #站点根目录你网站文件存放的地方
135            root   html;
136            #定义路径下默认访问的文件名,一般跟着root放
137            index  index.html index.htm;
138
139            #开启限制IP连接数的时候需要使用
140            #limit_zone crawler $binary_remote_addr 10m;
141
142            #访问控制模块默认就会安装,而且写法也非常简单,可以分别有多个allow,deny,允许或禁止某个ip或ip段访问,
143            #依次满足任何一个规则就停止往下匹配 (安全选项)
144            allow 192.168.10.100;
145            allow 172.29.73.0/24;
146            deny all;
147
148            #认证访问 通过httpd-devel 工具的 htpasswd 来为访问的路径设置登录密码 (安全选项)
149            #比如:htpasswd -c nginx.htpasswd admin 生成了默认使用CRYPT加密的密码文件#
150            auth_basic "Nginx Status"
151            auth_basic_user_file /usr/local/nginx/nginx.passwd
152
153            #列出目录 autoindex Nginx默认是不允许列出整个目录的合适下载服务器。(非常不推荐)
154            #如需此功能,打开nginx.conf文件,在location,server 或 http段中加入autoindex on;
155            #autoindex on
156            #显示出文件的确切大小单位是bytes。改为off后显示出文件的大概大小,单位是kB或者MB或者GB
157            #autoindex_exact_size off
158            #默认为off,显示的文件时间为GMT时间。改为on后,显示的文件时间为文件的服务器时间
159            #autoindex_localtime on;
160        }
161
162        #error_page  404              /404.html;
163        #将服务器错误页面直接指向静态页面/50x.html
164        error_page   500 502 503 504  /50x.html;
165        location = /50x.html {
166            root   html;
167        }
168
169        #代理PHP脚本到Apache上监听127.0.0.1:80 末尾以php或者php5结尾的
170        #location ~ \.(php|php5)?$ {
171        #    proxy_pass   http://127.0.0.1;
172        #}
173
174        #将PHP脚本传递到正在监听127.0.0.1:9000的FastCGI服务器
175        #location ~ .+\.(php|php5)$ {
176        #    root           html;
177        #    fastcgi_pass   127.0.0.1:9000;
178        #    fastcgi_pass   unix:/tmp/php.sock;  #为了安全推荐方式
179        #    fastcgi_index  index.php;
180        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
181        #    include        fastcgi_params;
182        #    fastcgi_cache  cache_fastcgi;
183        #}
184
185
186        # 如果Apache的文档根目录与nginx的根目录一致,则拒绝访问.htaccess文件
187        #location ~ /\.ht {
188        #    deny  all;
189        #}
190
191        #静态资源正则请求路径匹配
192        location ~ .+\.(gif|jpg|jpeg|png|bmp|swf|txt|csv|doc|docx|xls|xlsx|ppt|pptx|flv)$ {
193          root  e:wwwroot;
194          expires 30d;  #缓存有效期30天
195          access_log off; #访问记录
196        }
197        #JS和CSS缓存时间设置
198        location ~ .+\.(js|css|html|xml)$ { expires 30d;}
199
200        #访问控制也可以加入认证
201        location /nginx-status{
202            #nginx中的stub_status模块主要用于查看Nginx的一些状态信息. 本模块默认没有安装需要编译安装。
203            stub_status on;
204            allow 192.168.1.0/24;
205            allow 127.0.0.1;
206            deny all;
207        }
208    }
209
210    #### Nginx反向代理 ######
211    #[Main-http] upstream模块设置反向代理和负载均衡的连接的内部web应用服务IP端口
212    upstream monitor_server {
213        #seesion记录访问的主机,比如第一次访问该服务器后就记录,之后再访问都是该服务器了-进行了绑定
214        ip_hash;
215        #内网的应用服务,weigth参数表示权值越高被分配到的几率越大。
216        #max_fails当有max_fails个请求失败,就表示后端的服务器不可用,默认为1将其设置为0可以关闭检查
217        #fail_timeout 在以后的fail_timeout时间内nginx不会再把请求发往已检查出标记为不可用的服务器
218        server 192.168.0.131:80 weight=9 max_fails=5 fail_timeout=600s;
219        server 192.168.0.132:80 weight=1 max_fails=5 fail_timeout=600s;
220    }
221
222
223    #server指令配置项
224    server {
225        listen 80;
226        #请求响应的域名
227        server_name blog.weiyigeek.top;
228
229        location / {
230          ##### 模块http_proxy:##### 反向代理主要配置
231          #即反向代理,对应upstream负载均衡器
232          proxy_pass http://monitor_server;
233
234          #代理服务器相关信息头设置
235          proxy_redirect off;
236          #如果是有涉及redirect的服务,一定要加上端口8081,否 则默认tomcat在redirect时候默认找80端口
237          proxy_set_header Host $host;
238          #转发请求的原IP地址,程序中通过request.getHeader("Proxy-Client-IP")获得ip
239          proxy_set_header X-Real-IP $remote_addr;
240          #端的Web服务器可以通过X-Forwarded-For获取用户真实IP
241          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
242
243          ##nginx跟后端服务器连接超时时间(代理连接超时)
244          #模块http_proxy代理超时设置
245          proxy_connect_timeout 60s;
246
247          ##nginx跟后端服务器连接超时时间(代理连接超时)
248          proxy_read_timeout 60s;
249
250          #后端服务器数据回传时间(代理发送超时) 间
251          proxy_send_timeout 30s;
252
253          #设置代理服务器(nginx)从后端realserver读取并保存用户头信息的缓冲区大小,默认与proxy_buffers大小相同,其实可以将这个指令值设的小一点
254          proxy_buffer_size 4k
255          #proxy_buffers缓冲区,nginx针对单个连接缓存来自后端realserver的响应,网页平均在32k以下的
256          proxy_buffers 4 32k
257
258          #高负荷下缓冲大小(proxy_buffers*2)
259          proxy_busy_buffers_size 64k
260
261          #当proxy_buffers放不下后端服务器的响应内容时,会将一部分保存到硬盘的临时文件中,这个值用来设置最大临时文件大小,默认1024M
262          #它与proxy_cache没有关系。大于这个值,将从upstream服务器传回。设置为0禁用。
263          proxy_max_temp_file_size 0
264
265          #当缓存被代理的服务器响应到临时文件时,限制每次写临时文件的大小。proxy_temp_path(可以在编译的时候)指定写到哪那个目录。
266          proxy_temp_file_write_size 64k
267
268          #把cookie的作用域替换成我们的域名。
269          #proxy_cookie_domain google.com.hk www.example.com;
270          #proxy_set_header Host "www.google.com.hk";          #设置反向代理得header请求头
271          #proxy_redirect http://www.google.com.hk/ ;          #重定向
272          #proxy_redirect http:// https://;
273          #sub_filter www.google.com.hk www.example.com;       #把谷歌的域名替换成自己的,注意需要安装nginx的sub_filter模块
274          #反向代理的配置. END
275        }
276
277        #本地动静分离反向代理配置
278        #所有jsp的页面均交由tomcat或resin处理
279        location ~ .(jsp|jspx|do)?$ {
280            proxy_set_header Host $host;
281            proxy_set_header X-Real-IP $remote_addr;
282            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
283            proxy_pass http://127.0.0.1:8080;
284        }
285
286        #所有静态文件由nginx直接读取不经过tomcat或resin
287        location ~ \.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$ { expires 15d; }
288
289        location ~ \.(js|css)$ { expires 1h; }
290
291    }
292
293    # 另一个虚拟主机,混合使用IP、名称和基于端口的配置
294    server {
295      listen 80;
296      listen [::]:80;
297      server_name weiyigeek.top;
298      return 301 https://$host$request_uri;
299
300}
301
302    server {
303    listen 443 ssl http2;
304    listen [::]:443 ssl http2;
305    server_name weiyigeek.top;
306
307    # HSTS (ngx_http_headers_module is required) 应该只使用 HTTPS 而不是使用 HTTP 通信
308    add_header Strict-Transport-Security "max-age=31536000;includeSubDomains;preload" always;
309
310    # XXS-Protection
311    add_header X-XSS-Protection "1; mode=block";
312
313    # MIME 模拟探测
314    add_header X-Content-Type-Options nosniff;
315
316    # Frame 安全控制
317    add_header X-Frame-Options ALLOW-FROM music.163.com;
318
319    # Spider Robots 爬取策略限制
320    # add_header X-Robots-Tag none; # 不限制
321    # add_header X-Robots-Tag noindex, noarchive, nosnippet; # 限制
322
323    # 开启 SSL ,如果想http 与 https 公用一个配置则可以将其注释( the "ssl" directive is deprecated )
324    # ssl on;
325
326    # 配置证书链与证书密钥
327    ssl_certificate      /etc/nginx/ssl/fullchain.cer;
328    ssl_certificate_key  /etc/nginx/ssl/weiyigeek.top.key;
329
330    # ssl会话复用超时时间以及会话复用缓存大小
331    ssl_session_timeout 1d;
332    ssl_session_cache shared:MozSSL:10m;  # about 40000 sessions
333
334    # 配置双证书时开启否则应该关闭
335    ssl_session_tickets off;
336
337    ## OCSP stapling
338    ssl_stapling on;
339    ssl_stapling_verify on;
340    # 使用根 CA 和中间证书验证 OCSP 响应的信任链
341    ssl_trusted_certificate /etc/nginx/ssl/ca.cer;
342
343    # 仅使用ECDH是不用配置ssl_dhparam的否则你应该为它配置上
344    # curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam
345    ssl_dhparam /path/to/dhparam;
346
347    # 兼容性较为通用的SSL协议与加密算法套件
348    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
349    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;
350    # 安全配置: ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE;
351    # 证书常规握手加密算法方式共十八个,ECDHE、DHE、AES开头分别6个
352    ; 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;
353
354    # 为了兼容性推荐服务器自动选择要使用的算法套件
355    ssl_prefer_server_ciphers  on;
356
357    # replace with the IP address of your resolver
358    resolver 223.6.6.6 8.8.8.8 192.168.12.254;
359
360}
361}

为了更好的指导部署与测试系统,在保证 nginx 网站服务器高性能的同时下,为了保证其安全稳定运行,我们需要对 nginx 服务进行调优与加固; 本次进行 Nginx 服务调优加固主要从以下几个部分,模块性能优化,系统内核优化,编译安装优化,性能参数优化,安全加固配置, 可以帮助安全开发运维者加速进行 Nginx 服务器相关优化。