[TOC]javascript
一、Nginx 安全优化
1.一、隐藏Nginx版本号
通常来讲,软件的漏洞都和版本有关,这个很像汽车的缺陷,同一批次的要有问题就都有问题,别的批次可能就都是好的,Ngnx基于server_tokens
关键字实现隐藏nginx版本号。php
官方资料css
server_tokens语法:html
syntax: server_tokens on|off; #此行为参数语法,on为开启状态,off为关闭状态 default: server_tokens on; #此行意思是不配置该参数,软件默认状况的结果 context: http,server,location #此行为server_tokens参数能够放置的位置参数做用:激活或禁止Nginx的版本信息显示在报错信息和Server的响应首部位置中。
默认状况下,访问nginx会显示其版本号前端
$ curl -I 127.0.0.1 HTTP/1.1 200 OK Server: nginx/1.16.1 # 这里清晰的暴露了Web版本号(1.6.1)及软件名称(nginx) Date: Sat, 14 Mar 2020 06:43:31 GMT Content-Type: application/octet-stream Content-Length: 20 Connection: keep-alive
隐藏版本号实现:java
Nginx主配置文件nginx.conf中的http标签段内加入"server_tokens off"node
http { ............... server_tokens off; ............... } # 此参数放置在http标签内,做用是控制http response header内的Web服务版本信息的限制,以及错误信息中Web服务版本信息的显示
修改后重启nginx,使用curl -I查看结果mysql
$ curl -I 127.0.0.1 HTTP/1.1 200 OK Server: nginx # 能够看到nginx版本号已经被隐藏了 Date: Sat, 14 Mar 2020 06:45:15 GMT Content-Type: application/octet-stream Content-Length: 20 Connection: keep-alive
1.二、Nginx更改默认用户
为了让Web服务更安全,要尽量地改掉软件默认的全部配置,包括端口,用户等。nginx
那么如今基于yum安装的nginx默认用户都为nginxweb
1.查看nginx进程
$ ps -ef | grep nginx | grep -v grep root 2126 1 0 14:05 ? 00:00:00 nginx: master process nginx nginx 3574 2126 0 14:45 ? 00:00:00 nginx: worker process
能够看到nginx worker进程是由nginx用户运行,固然,Nginx的主进程仍是以root身份运行的。
2.查看nginx用户(默认已建立)
$ id nginx uid=998(nginx) gid=996(nginx) groups=996(nginx)
3.nginx配置中指定用户启动
$ vim /etc/nginx/nginx.conf user nginx; # 指定用户启动nginx
二、优化Nginx服务性能
2.一、Nginx指定进程数
在高并发,高访问量的Web服务场景,须要事先启动好更多的Nginx进程,以保证快速响应并处理大量并发用户的请求。 Nginx服务就至关于饭店,网站用户就至关于顾客,Nginx的进程就至关于服务员,下面就来优化Nginx进程的个数。
worker_processes语法:
syntax: worker_processes number; #此行为参数语法,number为数量 default: worker_processes 1; #此行意思是不匹配该参数,软件默认状况数量为1 context: main; #此行为worker_processes参数能够放置的位置
上述参数调整的是Nginx服务的worker进程数,Nginx有Master进程和worker进程之分,Master为管理进程,真正接待“顾客”的是worker进程。
优化Nginx进程个数的策略: worker进程数最开始的设置能够等于CPU的核数,且worker进程数要多一些,这样起始提供服务时就不会出现由于访问量快速增长而临时启动新进程提供服务的问题,缩短了系统的瞬时开销和提供服务的时间,提高了服务用户的速度。高流量高并发场合也能够考虑将进程数提升至CPU核数*2,具体状况要根据实际的业务来选择,由于这个参数除了要和CPU核数匹配外,也和硬盘存储的数据及系统的负载有关,设置为CPU的核数是一个好的起始配置,这也是官方的建议。
实践修改Nginx配置: 假设服务器的CPU颗数为2颗,核数为4核,则初始的配置可经过查看默认的nginx.conf里的worker_processes数来了解,
$ vim /etc/nginx/nginx.conf user nginx; worker_processes 4; # 这里修改参数值为CPU的总核数4,而后从新加载Nginx服务
如今检查修改后的worker进程数量:
$ ps -ef | grep nginx | grep -v grep root 2126 1 0 11:02 ? 00:00:00 nginx: master process nginx nginx 7039 2126 0 15:02 ? 00:00:00 nginx: worker process nginx 7040 2126 0 15:02 ? 00:00:00 nginx: worker process nginx 7041 2126 0 15:02 ? 00:00:00 nginx: worker process nginx 7042 2126 0 15:02 ? 00:00:00 nginx: worker process
2.二、Nginx 进程优化
默认状况下,Nginx的多个进程有可能跑在某一个CPU或CPU的某一核上,致使Nginx进程使用硬件的资源不均,本节的优化是尽量地分配不一样的Nginx进程给不一样的CPU处理,达到充分有效利用硬件的多CPU多核资源的目的。
在优化不一样的Nginx进程对应不一样的CPU配置时,四核CPU服务器的参数配置参考以下:
worker_processes 4; worker_cpu_affinity 0001 0010 0100 1000; # worker_cpu_affinity就是配置Nginx进程与CPU亲和力的参数,即把不一样的进程分给不一样的CPU处理。这里0001 0010 0100 1000是掩码,分别表明第1,2,3,4核CPU,因为worker_processes进程数为4,所以,上述配置会把每一个进程分配一核CPU处理,默认状况下进程不会绑定任何CPU,参数位置为main段。
四核和八核CPU服务器的参数配置参考以下:
# 八核掩码 worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000; # 四核掩码 worker_cpu_affinity 0001 0010 0100 1000; # worker_cpu_affinity 的做用是绑定不一样的worker进程数到一组CPU上。经过设置bitmask控制进程容许使用的CPU,默认worker进程不会绑定到任何CPU(自动平均分配。)
下面是绑定的实例配置:
worker_processes 4; worker_cpu_affinity 0001 0010 0100 1000; worker_processes 2; worker_cpu_affinity 0101 1010; # 最佳方式绑定方式 worker_processes auto; worker_cpu_affinity auto;
命令方式分配CPU taskset -retrieve or ser a process’s CPU affinity 命令自己也有分配CPU的功能 例如:taskset -c 1,2,3 /etc/init.d/mysqld_start
-c, --cpu-list specify a numerical list of processors instead of a bitmask. The list may contain multiple items, separated by comma, and ranges. For example, 0,5,7,9-11.
2.三、Nginx 事件模型优化
Nginx的链接处理机制在不一样的操做系统会采用不一样的额I/O模型,在Linux下,Nginx使用epoll的I/O多路复用模型,在Freebsd中使用kqueue的I/O多路复用模型,在Solaris中使用/dev/poll方式的I/O多路复用模型,在Windows中使用的是icop,等等。要根据系统类型选择不一样的事件处理模型,可供使用的选择有“use [kqueue|rtsig|epoll|/dev/poll|select|poll];”。
事件模型语法:
synstax: use method; # 络模型配置,method选择模型之一 default: -- # 默认没有设置 context: events # 网络模型配置放置events区块内
实践修改Nginx配置:
$ vi /etc/nginx/nginx.conf # events 区块是一个用来设置链接进程的区块,例如:设置Nginx的网络I/O模型,以及链接数等。 events { use epoll; }
根据Nginx官方文档建议,也能够不指定事件处理模型,Nginx会自动选择最佳的事件处理模型服务。
2.四、Nginx 最大链接数
调整Nginx单个进程容许的客户端最大链接数,这个控制链接数的参数为work_connections,worker_connections的值要根据具体服务器性能和程序的内存使用量来指定(一个进程启动使用的内存根据程序肯定)
worker_connections语法:
synstax: worker_connections number default: worker_connections 512 context: events
实践修改Nginx配置:
$ vi /etc/nginx/nginx.conf events { worker_connections 20480; }
说明: worker_connections用来设置一个worker process支持的最大并发链接数,这个链接数包括了全部连接,例如:代理服务器的链接,客户端的链接等,实际的并发链接数除了受worker_connections参数控制外,还和最大打开文件数worker_rlimit_nofile有关(见下文),Nginx总并发链接=worker数量*worker_connections。
参考资料:http://nginx.org/en/docs/ngx_core_module.html
2.五、Nginx 文件描述符
调整配置Nginx worker进程的最大打开文件数,这个控制链接数的参数为worker_rlimit_nofile。
worker_rlimit_nofile语法:
synstax: worker_rlimit_nofile number default: 无 context: main
实践修改Nginx配置:
$ vi /etc/nginx/nginx.conf # 最大打开文件数,可设置为系统优化后的ulimit-HSn的结果 worker_rlimit_nofile 65535;
说明: 1.此参数的做用是改变worker processes能打开的最大文件数 2.Linux系统文件最大打开数设置:ulimit -n 65535
参考资料:http://nginx.org/en/docs/ngx_core_module.html
2.六、Nginx高效传输
1.设置参数:sendfile on; sendfile参数用于开启文件的高效传输模式。同时将tcp_nopush和tcp_nodelay两个指令设置为on,可防止网络及磁盘I/O阻塞,提高Nginx工做效率。
syntax: sendfile on | off; default: sendfile off; context: http,server,location,if in location
参数做用:激活或禁用sendfile()功能功能。sendfile()是做用于两个文件描述符之间的数据拷贝函数,这个拷贝操做是在内核之中的,被称为“零拷贝”,sendfile()比read和write函数要高效不少,由于,read和write函数要把数据拷贝到应用层再进行操做。相关控制参数还有sendfile_max_chunk。
细节见http://nginx.org/en/docs/http/ngx_http_core_module.html#sendfile
2.设置参数:tcp_nopush on; 提升网络的“传输效率”
syntax: tcp_nopush on | off; default: tcp_nopush off; context: http,server,location
参数做用:激活或禁用Linux上的TCP_CORK socket选项,此选项仅仅当开启sendfile时才生效,激活这个tcp_nopush参数,数据包不会立刻转发出去,而是等数据包最大时,一次性转发出去,有效解决网络堵塞。
细节见http://nginx.org/en/docs/http/ngx_http_core_module.html。
3.设置参数:tcp_nodelay on; 在keeplive链接下,提升网络的传输“实时性” 用于激活tcp_ondelay功能,提升I/O性能。
syntax: tcp_nodelay on | off default: tcp_nodelay on; context: http,server,location
参数做用:默认状况下当数据发送时,内核并不会立刻发送,可能会等待更多的字节组成一个数据包,这样能够提升I/O性能。可是,在每次只发送不多字节的业务场景中,使用 tcp_nodelay功能可以让数据包马上转发出去。
参数生效条件: 激活或禁用TCP_NODELAY选项,当一个链接进入keep-alive状态时生效。 细节见http://nginx.org/en/docs/http/ngx_http_core_module.html。
三、Nginx链接参数优化
1.keepalive_timeout 用于设置客户端链接保持会话的超时时间为60秒。超过这个时间,服务器会关闭该链接,此数值为参考值。
syntax: keepalive_timeout timeout [header_timeout] default: keepalive_timeout 75s; context: http,serverr,location
参数做用:keep-alive可使客户端到服务器端已经创建的链接一直工做不退出,当服务器有持续请求时,keep-alive会使用已经创建的链接提供服务,从而避免服务器从新创建新链接处理请求。
此参数设置一个keep-alive(客户端链接在服务器端保持多久后退出),其单位是秒,和HTTP响应header域的“Keep-Alive:timeout=time”参数有关,这些header信息也会被客户端浏览器识别并处理,不过有些客户端并不能按照服务器端的设置来处理,例如:MSIE大约60秒后会关闭keep-alive链接。 细节见:http://nginx.org/en/docs/http/ngx_http_core_module.html
2.client_header_timeout 用于设置读取客户端请求头数据的超时时间。此处的数值15,其单位是秒,为经验参考值。
syntax: client_header_timeout time; #<==参数语法 default: client_header_timeout 60s; #<==参数默认大小 context: http,server #<==能够放置的标签段
参数做用:设置读取客户端请求头数据的超时时间。若是超过这个时间,客户端尚未发送完整的header数据,服务器端将返回“Request time out (408)”错误,可指定一个超时时间,防止客户端利用http协议进行攻击。
细节见:http://nginx.org/en/docs/http/ngx_http_core_module.html。
3.client_body_timeout 用于设置读取客户端请求主体的超时时间,默认值60
syntax: client_body_timeout time; default: client_body_timeout 60s; context: http,server,location
参数做用:设置读取客户端请求主体的超时时间。这个超时仅仅为两次成功的读取操做之间的一个超时,非请求整个主体数据的超时时间,若是在这个超时时间内,客户端没有发送任何数据,Nginx将返回“Request time out(408)”错误,默认值60,
细节见:http://nginx.org/en/docs/http/ngx_http_core_module.html
4.send_timeout 25 用于指定响应客户端的超时时间。这个超时仅限于两个链接活动之间的时间,若是超过这个时间,客户端没有任何活动或者Nginx数据没有发送完,Nginx都将会关闭链接,默认值为60秒,能够改成参考值25秒。
syntax: send_timeout time; default: send_timeout 60s; context: http,server,location
参数做用:设置服务器端发送HTTP响应信息到客户端的超时时间,这个超时仅仅为两次成功握手后的一个超时,非请求整个响应数据的超时时间,如在这个超时时间内,客户端没有接收任何数据,链接将被关闭。
细节见http://nginx.org/en/docs/http/ngx_http_module.html。
四、Nginx上传文件大小限制
syntax: client_max_body_size size; default: client_max_body_size 1m; context: http,server,location
参数做用:设置最大的容许的客户端请求主体大小,在请求头域有“Content-Length”,若是超过了此配置值,客户端会受到413错误,意思是请求的条目过大,有可能浏览器不能正确显示。设置为0表示禁止检查客户端请求主体大小。此参数对提升服务器端的安全性有必定做用。细节见http://nginx.org/en/docs/http/ngx_http_core_module.html
具体大小根据公司的业务作调整,若是不清楚就先设置为8m把,有关客户端请求主体的解释在HTTP原理一节已经解释过了,通常状况下,HTTP的post方法在提交数据时才会携带请求主体信息。
五、FastCGI调优
FastCGI参数是配合Nginx向后请求PHP动态引擎服务的相关参数。 FastCGI常见参数的Nginx配置示例以下:
$ cat /etc/nginx/nginx.conf worker_processes 4; worker_cpu_affinity 0001 0010 0100 1000; worker_rlimit_nofile 65535; user nginx; events { use epoll; worker_connections 10240; } http { include mime.types; default_type application/octet-stream; sendfile on; tcp_nopush on; keepalive_timeout 65; tcp_nodelay on; client_header_timeout 15; client_body_timeout 15; send_timeout 15; server_tokens off; fastcgi_connect_timeout 30s; #Nginx容许fcgi链接超时时间 fastcgi_send_timeout 30s; #Nginx容许fcgi返回数据的超时时间 fastcgi_read_timeout 30s; #Nginx读取fcgi响应信息的超时时间 fastcgi_buffer_size 64k; #Nginx读取响应信息的缓冲区大小 fastcgi_buffers 4 64k; #指定Nginx缓冲区的数量和大小 fastcgi_busy_buffers_size 128k; #当系统繁忙时buffer的大小 fastcgi_temp_file_write_size 128k; #Nginx临时文件的大小 fastcgi_temp_path /data/ngx_fcgi_tmp; #指定Nginx临时文件放置路径 fastcgi_cache_path /data/ngx_fcgi_cache levels=2:2 keys_zone=ngx_fcgi_cache:10m inactive=1d; #指定Nginx缓存放置路径 server { listen 80; location ~ .*\.(php|php5)?$ { root html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi.conf; fastcgi_cache ngx_fcgi_cache; #开启fcgi缓存并起名叫ngx_fcgi_cache,很重要,有效下降CPU负载,而且防止502错误发生。 fastcgi_cache_valid 200 302 1h; #指定应答代码的缓存时间,1h=1小时 fastcgi_cache_valid 301 1d; #1d=1天 fastcgi_cache_valid any 1m; #and 1m:将其余应答缓存1分钟 fastcgi_cache_min_uses 1; #待缓存内容至少要被用户请求过1次 fastcgi_cache_use_stale error timeout invalid_header http_500; #当遇到error,timeout,或者返回码500时,启用过时缓存返回用户(返回过时也比返回错误强) # fastcgi_cache_key http://$host$request_uri; } }
六、Nginx gzip
Nginx gzip压缩模块提供了压缩文件内容的功能,用户请求的内容在发送到用户客户端以前,Nginx服务器会根据一些具体的策略实施压缩,以节约网站出口带宽,同时加快数据传输效率,来提高用户访问体验。
Nginx gzip压缩的优势 1.提高网站用户体验:发送给用户的内容小了,用户访问单位大小的页面就加快了,用户体验提高了,网站口碑就行了。 2.节约网站带宽成本:数据是压缩传输的,所以节省了网站的带宽流量成本,不过压缩时会稍微消耗一些CPU资源,这个通常能够忽略。
此功能既能提高用户体验,又能使公司少花钱,一举多得。对于几乎全部的Web服务来讲,这是一个很是重要的功能,Apache服务也有此功能。
须要和不须要压缩的对象 1.纯文本内容压缩比很高,所以,纯文本的内容最好进行压缩,例如:html,js,css,xml,shtml等格式的文件。 2.被压缩的纯文本文件必需要大于1KB,因为压缩算法的特殊缘由,极小的文件压缩后可能反而变大。 3.图片,视频(流媒体)等文件尽可能不要压缩,由于这些文件大多都是通过压缩的,若是再压缩极可能不会减小或减小不多,或者有可能增大,同时压缩时还会消耗大量的CPU,内存资源。
参数介绍及配置说明 此压缩功能与早期Apache服务的mod_deflate压缩功能很类似,Nginx的gzip压缩功能依赖于ngx_http_gzip_module模块,默认已安装。
1.gzip压缩配置语法
Syntax: gzip on | off; Default: gzip off; Context: http, server, location, if in location 做用:传输压缩
2.gzip压缩比率配置语法
Syntax: gzip_comp_level level; Default: gzip_comp_level 1; Context: http, server, location 做用:压缩自己比较耗费服务端性能
3.gzip压缩协议版本
Syntax: gzip_http_version 1.0 | 1.1; Default: gzip_http_version 1.1; Context: http, server, location 做用:压缩使用在http那个协议,主流版本1.1
4.扩展压缩模块
Syntax: gzip_static on | off | always; Default: gzip_static off; Context: http, server, location 做用:预读gzip功能
对应的压缩参数说明以下:
#压缩配置 gzip on; #<==开启gzip压缩功能 gzip_min_length 1k; #<==设置容许压缩的页面最小字节数,页面字节数从header头的Content-Length中获取。默认值0,表示无论页面多大都进行压缩。建议设置成大于1K,若是小于1K可能会越压越大。 gzip_buffers 4 16K; #<==压缩缓冲区大小。表示申请4个单位为16K的内存做为压缩结果流缓冲,默认值是申请与原始数据大小相同的内存空间来存储gzip压缩结果。 gzip_http_version 1.1; #<==压缩版本(默认1.1,前端为squid2.5时使用1.0),用于设置识别HTTP协议版本,默认是1.1,目前大部分浏览器已经支持GZIP解压,使用默认便可。 gzip_comp_level 2; #<==压缩比率。用来指定gzip压缩比,1压缩比最小,处理速度最快;9压缩比最大,传输速度快,但处理最慢,也比较消耗CPU资源。 gzip_types text/plain text/css application/x-javascript application/xml application/javascript application/javascript image/jpeg image/jpg image/png; #<==用来指定压缩的类型,“text/html”类型老是会被压缩,这个就是HTTP原理部分讲的媒体类型。压缩类型能够在../conf/mime.types文件中查看 gzip_vary on; #<==vary header支持。该选项可让前端的缓存服务器缓存通过gzip压缩的页面,例如用Squid缓存通过Nginx压缩的数据。
不一样的Nginx版本中,gzip_types的配置可能会有不一样,上述配置示例适合Nginx 1.6.3。对应的文件类型,请查看安装目录下的mime.types文件。
完整的配置以下:
gzip on; gzip_min_length 1k; gzip_buffers 4 16K; gzip_http_version 1.1; gzip_comp_level 9; gzip_types text/plain text/css application/x-javascript application/xml application/javascript image/jpeg image/jpg image/png; gzip_vary on;
更多:http://nginx.org/en/docs/http/ngx_http_gzip_module.html
七、Nginx Expires 缓存
简单说,Nginx expires的功能就是为用户访问的网站内容设定一个过时时间,当用户第一次访问这些内容时,会把这些内容存储在用户浏览器本地,这样用户第二次及之后继续访问该网站时,浏览器会检查加载已经缓存在用户浏览器本地的内容,就不会去服务器请求了,当缓存的内容过时了会向源服务器发送请求,检查缓存内容是否被修改。
更深刻的理解: expires的功能就是容许经过Nginx配置文件控制HTTP的“Expires”和“Cache-Control”响应头部内容,告诉客户端浏览器是否缓存和缓存多久之内访问的内容。这个expires模块控制Nginx服务器应答时的expires头内容和Cache-Control头的max-age指令。缓存的有效期能够设置为相对于源文件的最后修改时刻或客户端的访问时刻。 这些HTTP头向客户端代表了额内容的有效性和持久性。若是客户端本地有内容缓存,则内容就能够从缓存而不是从服务器中读取,而后客户端会检查缓存中的副本,看其是否过时或失效,以决定是否从新从服务器得到内容更新。
Nginx expires功能优势 1.expires能够下降网站的带宽,节约成本。 2.加快用户访问网站的速度,提高用户访问体验。 3.服务器访问量下降了,服务器压力就减轻了,服务器成本也会下降,甚至能够节约人力成本。 4.对于几乎全部的Web服务来讲,这是很是重要的功能之一,Apache服务也有此功能。
Nginx expires配置详解 前面已经介绍了expires的功能原理,接下来就来配置Nginx expires的功能。这里以location标签为例进行讲解,经过location URI规则将须要缓存的扩展名列出来,而后指定缓存时间。若是针对全部内容设置缓存,也能够不用location。Nginx默认安装了expires功能。
1.根据文件扩展名进行判断,添加expires功能范例 范例1:
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 3650d; } #该范例的意思是当用户访问网站URL结尾的文件扩展名为上述指定类型的图片时,设置缓存3650天,即10年。
范例2:
location ~ .*\.(js|css)$ { expires 30d; } #该范例的意思是当用户访问网站URL结尾的文件扩展名为js,css类型的元素时,设置缓存30天,即1个月。
2.根据URL中的路径(目录)进行判断,添加expires功能范例 范例3:
location ~ ^/(images|javascript|js|css|flash|media|static)/ { expires 360d; } #该范例的意思是当用过户访问网站URL中包含上述路径(例:images,js,css,这些在服务器端是程序目录)时,把访问的内容设置缓存360天,即1年。
3.配置Nginx expire配置效果检查
$ cat nginx.conf worker_processes 1; events { worker_connections 1024; } worker_rlimit_nofile 65535; http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server_tokens off; tcp_nopush on; tcp_nodelay on; gzip on; gzip_min_length 1k; gzip_buffers 4 16K; gzip_http_version 1.1; gzip_comp_level 9; gzip_types text/plain application/x-javascript text/css application/xml; gzip_vary on; server { listen 80; server_name blog.youngboy.org; root html/blog; location / { index index.php index.html index.htm; } location ~.*\.(php|php5)?$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi.conf; } location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 3650d; } location ~ .*\.(js|css)$ { expires 30d; } location ~ ^/(images|javascript|js|css|flash|media|static)/ { expires 360d; } } }
使用curl -I 查看expires参数
[root@web01 /]# curl -I http://www.xiongminghao.top/wp-content/themes/wordstar/assets/css/font-awesome.css HTTP/1.1 200 OK Server: nginx Date: Sat, 05 Jan 2019 16:43:02 GMT Content-Type: text/css Content-Length: 37414 Last-Modified: Sat, 29 Dec 2018 07:13:51 GMT Connection: keep-alive Vary: Accept-Encoding ETag: "5c271eaf-9226" Expires: Mon, 04 Feb 2019 16:43:02 GMT #缓存过时时间 Cache-Control: max-age=2592000 #缓存的总时间 Accept-Ranges: bytes
注意事项:expires只能在web节点上的nginx的配置文件里生效,若是配置在nginx方向代理的话,expires是不生效的
八、Nginx 日志文件安全
1.不记录特定的访问日志 在实际工做中,对于负载均衡器健康节点检查或某些特定文件(好比图片,JS,CSS)的日志,通常不须要记录下来,由于在统计PV时是按照页面计算的,并且日志写入太频繁会消耗大量磁盘I/O,下降服务的性能。 具体配置方法为:
location ~ .*\.(js|jpg|JPG|jpeg|JPEG|css|bmp|gif|GIF)$ { access_log off; }
这里用location标签匹配不记录日志的元素扩展名,而后关闭日志
2.访问日志的权限设置 假如日志目录为/app/logs,则受权方法以下:
chown -R root.root /app/logs chmod -R 600 /app/logs
不须要在日志目录上给Nginx用户读或写许可,但不少网友都没注意这个问题,他们把该权限直接给了Nginx或Apache用户,这就成为了安全隐患。
九、Nginx 访问控制
1.根据扩展名限制程序和文件访问 Web2.0时代,绝大多数网站都是以用户为中心多的,例如:bbs,blog,sns产品,这几个产品都有一个共同特色,就是不但容许用户发布内容到服务器,还容许用户发图片甚至上传附件到服务器上,因为为用户开了上传功能,所以给服务器带来了很大的安全风险。虽然不少程序在上传前会着必定的控制,例如:文件大小,类型等,可是,一不当心就会被黑客钻了控制,上传了木马程序。
下面将利用Nginx配置禁止访问和上传资源目录下的PHP,Shell,Perl,Python程序文件,这样用户即便上传了木马文件也无法执行,从而增强了网站的安全。
范例1:配置Nginx,禁止解析指定目录下的指定程序。
location ~ ^/images/.*\.(php|php5|sh|pl|py)$ { deny all; } location ~ ^/static/.*\.(php|php5|sh|pl|py)$ { deny all; } location ~* ^/data/(attachment|avatar)/.*\.(php|php5)$ { deny all; }
对上述目录的限制必须写在Nginx处理PHP服务配置的前面,以下:
location ~ .*\.(php|php5)$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fcgi.conf; }
范例2:Nginx下配置禁止访问*.txt和*.doc文件。 实际配置信息以下:
location ~* \.(txt|doc)$ { if (-f $request_filename) { root /data/www/www; #rewrite ...能够重定向到某个URL break; } } location ~* \.(txt|doc)$ { root /data/www/www; deny all; }
2.禁止访问指定的目录 范例1:配置禁止访问指定的单个或多个目录
#禁止访问单个目录的命令以下: location ~ ^/static { deny all; } #禁止访问多个目录的命令以下: location ~ ^/(static|js) { deny all; }
范例2:禁止访问目录并返回指定的HTTP状态码,命令以下:
server { listen 80; server_name www.youngboy.com youngboy.com; root /data/www/www; index index.html index.htm; access_log logs/www_access.log commonlog; location /admin/ {return 404;} location /tmplates/ {return 403;} }
做用: 禁止访问目录下的指定文件"1",或者禁止访问指定目录下的全部内容。
最佳应用场景: 对于集群的共享存储,通常是存放静态资源文件,因此,可禁止执行指定扩展名的程序,例:.php,.sh,.pl,.py
十、Nginx 限制来源IP访问
使用ngx_http_access_module限制网站来源IP访问
案例环境:phpmyadmin数据库的Web客户端,内部开发人员用的。 范例1:禁止某目录让外界访问,但容许某IP访问该目录,且支持PHP解析,命令以下:
location ~ ^/yunjisuan/ { allow 202.111.12.211; deny all; } location ~ .*\.(php|php5)$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi.conf; }
范例2:限制指定IP或IP段访问,命令以下:
location / { deny 192.168.1.1; allow 192.168.1.0/24; allow 10.1.1.0/16; deny all; }
参考资料:http://nginx.org/en/docs/http/ngx_http_access_module.html
企业问题案例: Nginx作反向代理的时候能够限制客户端IP吗? 答:能够,具体方法以下:
#方法一:使用if来控制,命令以下: if ($remote_addr = 10.0.0.7) { return 403; } if ($remote_addr = 218.247.17.130) { set $allow_access_root 'ture'; } #方法二:利用deny和allow只容许IP访问,命令以下: location / { root html/blog; index index.php index.html index.htm; allow 10.0.0.7; deny all; } #方法三:只拒绝某些IP访问,命令以下: location / { root html/blog; index index.php index.html index.htm; deny 10.0.0.7; allow all; }
注意事项: 1.deny必定要加一个IP,不然会直接跳转到403,再也不往下执行了,若是403默认页是在同一域名下,会形成死循环访问。 2.对于allow的IP段,从容许访问的段位从小到大排列,如127.0.0.0/24的下面才能是10.10.0.0/16,其中: 1)24表示子网掩码:255.255.255.0 2)16表示子网掩码:255.255.0.0 3)8表示子网掩码:255.0.0.0 3.以deny all:结尾,表示除了上面容许的,其余的都禁止。如: 1)deny 192.168.1.1; 2)allow 127.0.0.0/24; 3)allow 192.168.0.0/16; 4)allow 10.10.0.0/16; 5)deny all;
十一、Nginx 禁止非法域名解析
Nginx如何防止用户IP访问网站(恶意域名解析,也至关因而直接IP访问企业网站)
方法一:让使用IP访问网站的用户,或者恶意解析域名的用过户,收到501错误,命令以下:
#直接用新的server标签 server { listen 80 default_server; server_name _; return 501; } 说明:直接报501错误,从用户体验上不是很好
方法二:经过301跳转到主页,命令以下:
#当输入IP地址访问的时候会自动跳转到域名 server { listen 80 default_server; server_name _; rewrite ^(.*) http://blog.youngboy.org/$1 permanent; }
方法三:发现某域名恶意解析到公司的服务器IP,在server标签里添加如下代码便可,如有多个server则要多处添加。
if ($host !~ ^blog.youngboy.org$) { rewrite ^(.*) http://blog.youngboy.org/$1 permanent; } #说明:代码含义为若是header信息的host主机名字非blog.youngboy.org,就301跳转到blog.youngboy.org
十二、Nginx 防盗链
简单的说,就是某些不法网站未经容许,经过在其自身网站程序里非法调用其余网站的资源,而后在本身的网站上显示这些调用的资源,达到填充自身网站的效果。这一举动不只浪费了调用资源网站的网络流量,还形成其余网站的带宽及服务压力吃紧,甚至宕机。
Nginx Web服务实现防盗链实战 在默认状况下,只须要进行简单的配置,便可实现防盗链处理。请看下面的实例。
实战模式演示盗链: 1)假定blog.youngboy.com是盗链的网站域名,先写一个代码程序内容,以下:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title> jason </title> </head> <body bgcolor=green> <img src="http://www.youngboy.org/stu.jpg"> </body> </html>
假定咱们维护的网站是www.youngboy.org。设定一张存在的图片地址,www. youngboy.org/stu.jpg,此时发现blog.youngboy.com盗链了。经过查看流量,分析日志看referer,就能够看到被盗链的具体状况。
下面是查看Web用户http_referer实战演示
#nginx日志格式为www.access.log log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
盗链网站blog.youngboy.com访问咱们的站点时记录的日志
[root@web01 logs]# tail -f www.access.log 10.0.0.1 - - [16/Oct/2018:08:56:43 +0800] "GET /stu.jpg HTTP/1.1" 304 0 "http://blog.youngboy.com/oldboy.html" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.16 Safari/537.36" "-"
对比下可知,盗链的网站多出了一个http_referer的信息,即"http://blog.youngboy.com/oldboy.html" ,表示用户打开咱们网站的资源来自于此网站,也就是该站盗链了咱们的网站www.youngboy.org资源 可在www.youngboy.org网站下设置防盗链,Nginx的方法以下 放置在server标签内
location ~*^.+\.(jpg|gif|png)$ { valid_referers none blocked *.youngboy.com youngboy.com; if ($invalid_referer) { rewrite ^/ http://www.youngboy.com/img/nolink.jpg; } } #提示:要根据本身公司的实际业务(是否有外链的合做)进行域名设置。
盗链的配置参数解释
location ~*^.+\.(jpg|gif|png)$ { #若是访问的文件匹配了括号中的结尾的扩展名,那么就执行下一步匹配 valid_referers none blocked *.youngboy.com youngboy.com; #若是http报文中referer不是youngboy.com,那么就执行一步匹配 if ($invalid_referer) { rewrite ^/ http://www.youngboy.com/img/nolink.jpg; #若是条件不成立,也就是说在http报文中的referer中的域名不是上述填写的域名,那么就会给客户端返回http://www.youngboy.com/img/nolink.jpg; } }
1三、Nginx 优雅错误
范例1:对错误代码403实行本地页面跳转,命令以下:
server { listen 80; server_name blog.youngboy.org; location / { root html/blog; index index.html index.htm; } error_page 403 /403.html; #当出现403错误时,会跳转到403.html页面 } [root@web01 html]# echo “jason 403 page” >blog/403.html [root@web01 blog]# curl blog.youngboy.org/images/oldgirl.sh jason 403 page #上面的/403.html是相对于站点根目录html/blog的。
范例2:对错误代码404实行本地页面优雅显示,命令以下
server { listen 80; server_name blog.youngboy.org; location / { root html/blog; index index.html index.htm; error_page 404 /404.html; #当出现404错误时,会跳转到404.html页面 } } #代码中的/404.html是相对于站点根目录html/blog下的404.html文件,该文件能够是.php .jpg .html等等 error_page支持多个错误代码的跳转例如: error_page 403 404 /403.html;
范例3: 50x页面放到本地单独目录下,进行优雅显示
error_page 500 502 503 504 /50x.html; location = /50x.html { root /data/www/html; } #这里指定单独的站点目录存放到50x.html文件中。
范例4: 错误状态码URL重定向,命令以下:
server { listen 80; server_name blog.youngboy.org; location / { root html/www; index index.html index.htm; error_page 404 http://bbs.youngboy.org; #当出现404错误时,会跳转到指定的URL http://bbs.youngboy.org页面显示给用户,这个URL通常是企业另外的可用地址。 access_log /usr/local/nginx/logs/bbs_access.log commonlog; } } #代码中的/404.html是相对于站点根目录html/www的。
范例5: 将错误状态码重定向到一个location,命令以下:
location / { error_page 404 = @fallback; } location @fallback { proxy_pass http://backend; }
阿里门户网站天猫的Nginx优雅显示配置案例以下:
error_page 500 501 502 503 504 http://err.tmall.com/error2.html; error_page 400 403 404 405 408 410 411 412 413 414 415 http://err.tmall.com/error1.html;
1四、Nginx 防爬虫
咱们能够根据客户端的user-agents信息,轻松地阻止指定的爬虫爬取咱们的网站。下面来看几个案例。 将配置放入server标签 范例1:阻止下载协议代理,命令以下:
##Block download agents## if ($http_user_agent ~* LWP:Simple|BBBike|wget) { return 403; } #若是用户匹配了if后面的客户端(例如wget),就返回403. #这里根据$http_user_agent获取客户端agent,而后判断是否容许或返回指定错误码。
范例2:添加内容防止N多爬虫代理访问网站,命令以下:
#这些爬虫代理使用“|”分隔,具体要处理的爬虫能够根据需求增长或减小,添加的内容以下: if ($http_user_agent ~* "qihoobot|Baiduspider|Googlebot-Modile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Yahoo! SSlurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot"){ return 403; }
范例3:测试禁止不一样的浏览器软件访问,命令以下:
if ($http_user_agent ~* "Firefox|MSIE") { rewrite ^(.*) http://blog.youngboy.org/$1 permanent; } #若是浏览器为Firefox或IE,就会跳转到http://blog.youngboy.org
1五、Nginx 限制HTTP请求方法
最经常使用的HTTP方法为GET,POST,咱们能够经过Nginx限制HTTP请求的方法来达到提高服务器安全的目的,例如,让HTTP只能使用GET,HEAD和POST方法的配置以下:
#Only allow these request methods if ($request_method !~ ^(GET|HEAD|POST)$) { return 501; } #命令解释: ($request_method !~ ^(GET|HEAD|POST)$) #<==若是匹配的http请求方法不是get|head|post就拒绝掉
当上传服务器上传数据到存储服务器时,用户上传写入的目录就不得不给Nginx对应的用户相关权限,这样一旦程序有漏洞,木马就有可能被上传到服务器挂载的对应存储服务器的目录里,虽然咱们也作了禁止PHP,SH,PL,PY等扩展名的解析限制,但仍是会遗漏一些想不到的可执行文件。对于这样状况,该怎么办呢?事实上,还能够经过限制上传服务器的Web服务(能够具体到文件)使用GET方法,防止用户经过上传服务器访问存储内容,让访问存储渠道只能从静态或图片服务器入口进入。
例如,在上传服务器上限制HTTP的GET方法的配置以下:
#Only deny GET request methods ## if ($request_method ~* ^(GET)$) { return 501; } #还能够加一层location,更具体地限制文件名
1六、Nginx 链接限制
链接频率限制 limit_conn_module
请求频率限制 limit_req_module
http协议的链接与请求
HTTP是建⽴在TCP, 在完成HTTP请求须要先建⽴TCP三次握⼿(称为TCP链接),在链接的基础 上在HTTP请求。
Nginx链接限制配置
Nginx链接限制语法
Syntax: limit_conn_zone key zone=name:size; Default: Context: http Syntax: limit_conn zone number; Default: Context: http, server, location
具体配置以下:
http { #http段配置链接限制, 同⼀时刻只容许⼀个客户端IP链接 limit_conn_zone $binary_remote_addr zone=conn_zone:10m; ... server { ... location / { #同⼀时刻只容许⼀个客户端IP链接 limit_conn conn_zone 1; } #压⼒测试 yum install -y httpd-tools ab -n 50 -c 20 http://127.0.0.1/index.html
Nginx 请求限制配置
Nginx请求限制语法 Syntax: limit_req_zone key zone=name:size rate=rate; Default: Context: http Syntax: limit_conn zone number [burst=number] [nodelay]; Default: Context: http, server, location
具体配置以下:
http { ##http段配置请求限制, rate限制速率,限制⼀秒钟最多⼀个IP请求 limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s; ... server { ... location / { #1r/s只接收⼀个请求,其他请求拒绝处理并返回错误码给客户端 limit_req zone=req_zone; #请求超过1r/s,剩下的将被延迟处理,请求数超过burst定义的数量, 多余的请求返回503 #limit_req zone=req_zone burst=3 nodelay; } #压⼒测试 yum install -y httpd-tools ab -n 50 -c 20 http://127.0.0.1/index.html
链接限制没有请求限制有效?
咱们前⾯说过, 多个请求能够建⽴在⼀次的TCP链接之上, 那么咱们对请求的精度限制,固然
⽐对⼀个链接的限制会更加的有效。
由于同⼀时刻只容许⼀个链接请求进⼊。 可是同⼀时刻多个请求能够经过⼀个链接进⼊。 因此请求限制才是⽐较优的解决⽅案。