1. 调整参数隐藏nginx软件版本号信息javascript
软件的漏洞和版本有关,咱们应尽可能隐藏或消除web服务对访问用户显示各种敏感信息(例如web软件名称及版本号等信息),这样恶意的用户就很难猜到他攻击的服务器所用的是否有特定漏洞的软件,或者是否有对应漏洞的某一特定版本,从而增强web服务的安全性。
要了解服务器使用的软件版本号,对于linux客户端php
[root@Poppy conf]# curl -i bbs.joker.com HTTP/1.1 200 OK Server: nginx/1.6.3 Date: Fri, 15 Jun 2018 02:18:23 GMT Content-Type: text/html Content-Length: 4 Last-Modified: Thu, 07 Jun 2018 10:06:23 GMT Connection: keep-alive ETag: "5b19039f-4" Accept-Ranges: bytes bbs 浏览器上访问若是出现404的时候,会显示软件和版本号。
咱们来访问下百度看看是否能够隐藏版本css
[root@Poppy conf]# curl -i baidu.com HTTP/1.1 200 OK Date: Fri, 15 Jun 2018 02:23:35 GMT Server: Apache 软件更改为了apache,还隐藏了版本号 Last-Modified: Tue, 12 Jan 2010 13:48:00 GMT ETag: "51-47cf7e6ee8400" Accept-Ranges: bytes Content-Length: 81 Cache-Control: max-age=86400 Expires: Sat, 16 Jun 2018 02:23:35 GMT Connection: Keep-Alive Content-Type: text/html <html> <meta http-equiv="refresh" content="0;url=http://www.baidu.com/"> </html>
经过修改配置文件nginx.conf中的http标签段内加入“server_tokens off”;参数html
[root@Poppy conf]# cat nginx.conf worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; # 访问日志,main就是读http里面的main日志变量 access_log logs/www_access.log main; server_tokens off; include extra/bbs.conf; }
再来访问看看java
[root@Poppy conf]# curl -i bbs.joker.com HTTP/1.1 200 OK Server: nginx Date: Fri, 15 Jun 2018 02:27:21 GMT Content-Type: text/html Content-Length: 4 Last-Modified: Thu, 07 Jun 2018 10:06:23 GMT Connection: keep-alive ETag: "5b19039f-4" Accept-Ranges: bytes bbs
语法格式为node
server_tokens off; off 为关闭 on为开启 (默认开启安)
存放的位置能够是http,server,location
2. 更改源码隐藏nginx软件名称及版本号python
隐藏了nginx版本号后,更近一步,咱们能够经过一些手段把web服务软件的名称也隐藏起来,或者更改成其余web服务软件名以迷惑黑客。因为商业及品牌的展现缘由等,软件提供商不但愿使用者把软件名字隐藏起来。所以,若是要修改软件名称就只能更改nginx源代码
咱们不作修改mysql
3. 更改nginx服务默认用户linux
为了让web服务更安全,要尽量的改掉软件默认的全部配置,包括端口,用户等
nginx服务的默认用户是nobody,即便是注释或者不配置默认用户都是nobodynginx
[root@Poppy conf]# grep "#user" nginx.conf.default #user nobody;
#1 为nginx服务创建新用户的操做过程以下
useradd www -s /sbin/nologin -M
不须要有系统登陆权限,应当禁止其登陆行为
#2 配置nginx服务,让其使用刚创建的nginx用户
第一种方法是直接修改配置文件,将默认的#user nobody改成 user nginx; 第二种方法是直接在编译nginx软件时指定编译的用户和组 ./configure --user=nginx --group=nginx 检查更改用户的效果 [root@Poppy conf]# ps -ef|grep nginx root 9032 1 0 Jun14 ? 00:00:00 nginx: master process /application/nginx/sbin/nginx www 10609 9032 0 10:27 ? 00:00:00 nginx: worker process 能够看到worker process进程对应的用户都变成了nginx。上述2种方法均可以设置nginx的worker进程运行的用户,固然,nginx的主进程仍是以root身份运行的。
优化nginx服务的worker进程个数
在高并发,高访问量的web服务场景,须要事先启动好更多的nginx进程,以保证快速响应并处理大量并发用户的请求
这相似于开饭店,在营业前,须要事先招聘必定数量的服务员准备接待顾客,但这里就有个问题,若是饭店对客流没有正确评估,就会致使一些问题发生,例如;服务员人数招聘多了,可是客流不多,那么服务员就可能很闲,没事干,饭店的成本也就高了;若是客流很大,而服务员人数少了,可能就接待不过来顾客,致使顾客吃饭体验差。所以,饭店要根据客户的流量及并发量来调整接待的服务人员数量,而后根据监测顾客量变化及时调整到最佳的配置。
nginx服务就至关于饭店,网站用户就至关于顾客,nginx的进程就至关于服务员
1. 优化nginx进程对应的配置
优化nginx的进程反应nginx服务的配置参数以下
worker_processes 1;指定了nginx要开启的进程数,结尾的数字就是进程个数
调整的是nginx服务的worker进程数,nginx有master进程和worker进程之分,master是管理进程,worker是工做处理进程
2. 优化nginx进程个数的策略
如何设置worker_processes树木,官方建议咱们起始为cpu的核数,这样起始提供服务时就不会出现由于访问量快速增长而临时启动新进程提供服务的问题,缩短了系统的瞬间开销和提供服务的时间,提高了服务用户的速度。高流量高并发场合也能够考虑将进程数提升至cpu核数具体状况根据实际业务来选择,由于这个参数除了要和cpu核数匹配外,也和硬盘存储的数据及系统的负载有关。
3. 查看web服务器cpu硬件资源信息
[root@Poppy conf]# grep -c processor /proc/cpuinfo 1 一颗cpu一核 [root@Poppy conf]# grep 'physical id' /proc/cpuinfo|sort|uniq|wc -l 1 一颗cpu
4. 实践修改nginx配置
服务器cpu颗数为1颗,核数为4核,则初始的配置可经过查看默认的nginx.conf里的work_process了解,命令以下
[root@Poppy conf]# grep worker_processes nginx.conf worker_processes 1;
咱们修改将其修改成4,而后重启nginx
[root@Poppy conf]# grep worker_processes nginx.conf worker_processes 4;
咱们经过ps -ef,来查看下nginx进程
[root@Poppy conf]# ps -ef|grep nginx root 9032 1 0 Jun14 ? 00:00:00 nginx: master process /application/nginx/sbin/nginx www 10862 9032 0 14:02 ? 00:00:00 nginx: worker process www 10863 9032 0 14:02 ? 00:00:00 nginx: worker process www 10864 9032 0 14:02 ? 00:00:00 nginx: worker process www 10865 9032 0 14:02 ? 00:00:00 nginx: worker process
可知,worker的进程数为4个,ngxin master主进程不包含在这个参数内,nginx master的主进程为管理进程,负责调度和管理worker进程。
默认状况下,nginx的多个进程有可能跑在某一个cpu或cpu的某一核上,致使nginx进程使用硬件的资源不均,如何尽量地分配不一样的nginx进程给不一样的cou处理,达到充分有效利用硬件的多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 0001 0010 0100 1000 0001 0010 0100 1000
worker_cpu_affinity 00000001 00000002 00000003 00000004 00000005 00000006 00000007 00000008
其语法就是
worker_cpu_affinity cpumask; cpumask是掩吗
worker_cpu_affinity的做用是绑定不一样的worker进程数到一组cpu上
压力测试 。webbench -c 2000 -t 180 http://www.joker.com/
nginx的连接处理机制在不一样的操做系统会采用不一样的i/o模型,在linux下,nginx使用epoll的i/o多路复用模型,具体配置以下
events{
events 指令是设定nginx的工做模式及链接数上限
user epoll;
use是一个事件模块指令,用来指定nginx的工做模式。
}
nginx的工做模式
nginx的工做模式有select,poll,kqueue,epoll,rtsig和/dev/poll。其中select,poll都是标准的工做模式,kqueue和epoll是高效的工做模式,不一样的是epoll用来linux平台上,而kqueue用来bsd系统中。对于linux系统linux 2.6+的内核,推荐选择epoll工做模式,这是高性能高并发的设置。
nginx官方文档建议,咱们能够不指定事件处理模型,nginx会自动选择最佳的事件处理模型服务
调整nginx单个进程容许的客户端最大链接数,这个控制链接数的参数为worker_connections
worker_connections的值要根据具体服务器性能和程序的内存使用量来执行(一个进程启动使用的内存根据程序肯定),以下
events{ events指令是设定nginx的工做模式及链接数上限 worker_connections 20480; worker_connections也是个事件模块指令,用于定义nginx每一个进程的最大链接数,默认是1024。最大客户端链接数由worker_processes和worker_connections决定,即max_client=worker_processes*worker_connections。进程的最大链接数接受linux系统接受linux系统进程的最大打开文件数限制,在执行操做系统命令“ulimit -Hsn 65535”或配置相应文件后,worker_connections的设置才能生效 } worker_connections用来设置一个worker process支持的最大并发链接数
调整配置nginx worker进程最大打开文件数,这个控制链接数的参数为worker_rlimit_nofile。
worker_rlimit_nofile 65535;
最大打开文件数,可设置为系统优化后的ulimit -HSn的结果
先要将确切名字和通配符名字存储在散列表中,散列表和监听端口关联,每一个端口最多关联到三张表;确切名字的散列表,以星号起始的通配符名字的散列表和以星号结束的通配符名字的散列表。散列表的尺寸在配置阶段进行了优化,能够以最小的cpu缓存命中失败来找名字。nginx首先会搜索确切名字的散列表,若是没有找到,则搜索以星号起始的通配符名字的散列表,若是仍是没有找到,继续搜索以星号结束的通配符名字的散列表。
[root@Poppy extra]# cat bbs.conf server { listen 80; server_name bbs.joker.com *.joker.com; 很明显*.joker.com效率低 location / { root html/bbs; index index.html; } }
若是你要想定义大量的名字,或者定义很是长的名字,就须要在http配置块中调整server_names_hash_max_size和server_names_hash_bucket_size的值。server_names_hash_max_size的默认值多是32或64,也多是其余值,这取决于cpu的缓存行的长度。那么定义“wwwwwwwwwwwwwwwwwwwwww.joker.com”做为虚拟主机名就会失败,此时会显示下面的错误信息;
could not build the server_name_hash; you should increase server_names_hash_bucket_size:32
出了这种状况,就须要将server_names_hash_max_size扩大一倍。
http{ server_names_hash_max_size 64 ....... }
若是定义了大量名字,会获得以下另一个错误消息;
could not build the server_name_hash; you should increase server_names_hash_max_size:512 # 默认512kb,通常查看系统给出确切的值,cpu l1的4倍到5倍 or server_names_hash_bucket_size; 32
咱们应该修改server_names_hash_max_size的值,此值差很少等于名字列表的名字总量。
注意:后面不能带单位
1. 设置参数sendfile on;
sendfile参数用于开启文件的高效传输模式,同时将tcp_nopush和tcp_nodelay俩个指令设置为on,可防止网络及磁盘i/o阻塞,提高nginx工做效率
在http ,server,location,if in location字段标签里面能够设置
http {
sendfile on; 默认是off
}
激活sendfile功能,sendfile()是做用于俩个文件描述符之间的数据拷贝函数,这个拷贝操做是在内核之中的,被称为“零拷贝”,sendfile()比read和write函数要高效不少,由于,read和write函数要把数据拷贝到应用层在进行操做。
2. 设置参数tcp_nopush
在http,server,location字段标签里面能够设置
http {
sendfile on;
tcp_nopush on; 默认是off
}
激活linux上传递tcp_cork socket选项,此选项仅仅当开启sendfile时才生效,激活这个,tcp_nopush参数能够容许把http response header和文件的开始部分放在一个文件里发布,其积极的做用是减小网络报文段的数量。
1. 连接超时的定义
当服务器创建的连接没有接收处理请求时,可在指定的时间内就让它超时自动退出。还有当nginx和fastcgi服务没法给nginx返回数据,此时能够经过配置nginx服务参数使其不会死等,由于前面用户还等着它返回数据呢。
2. 连接超时的做用
简单地说,连接超时是服务的一种自我管理,自我保护的重要机制。
3. 连接超时带来的问题,以及不一样程序连接设定知识
服务器创建连接是要消耗资源的,超时设置的过短而并发很大,就会致使服务器瞬间没法响应用户的请求,致使用户体验降低。
php程序站点会但愿设置成短连接,由于php程序创建连接消耗资源和时间相对要少些。而对于java程序站点来讲,建议设置长连接,由于java程序创建连接消耗的资源和时间更多。
4. nginx连接超时的参数设置
(1)设置参数;keepalive_timeout 60;
用于设置客户端保持连接会话超时时间为60秒。超过这个时间,服务器会关闭该连接
keepalive_timeout 60;
可设置在http,server,location字段标签中,默认是75s
keep-alive可使客户端到服务器端已经创建的连接一直工做不退出,当服务器有持续请求时,keep-alive会使用已经创建的连接提供服务,从而避免服务器从新创建新连接处理请求。
(2)设置参数:tcp_nodelay on;
用于激活tcp_nodelay功能,提升i/o性能,能够设置在http,server,location字段标签里
http {
sendfile on;
tcp_nodelay on; 默认是on
}
当数据发送时,内核不会立刻发送,可能会等待更多的字节组成一个数据包,这样能够提升i/o性能。可是,在每次只发送不多字节的业务场景汇总,使用tcp_nodelay功能,等待时间会比较长。
(3)设置参数;client_header_timeout 15;
读取客户端请求头数据的超时时间
能够设置在http,server字段标签里
http {
sendfile on;
client_header_timeout 60s; 默认是60s
}
若是超过这个时间,客户端尚未发送完整的header数据,服务器端将返回"Request timo out(408)"错误。
(4) 设置参数;client_body_timeout 15;
用于设置读取客户端请求主体的超时时间,默认值是60
http {
sendfile on;
client_bodyr_timeout 60s; 默认是60s
}
仅仅为俩次成功的读取操做之间的一个超时,非请求整个主体数据的超时时间。若是在这个超时时间内,客户端没有发 人和数据,nginx将返回"Request timo out(408)"错误。
(5) 设置参数;send_timeout 25;
用于指定响应客户端的超时时间。这个超时仅限于2个连接活动之间的时间,若是超过这个时间,客户端没有人和活动,nginx将会关闭连接,默认值为60秒。
http { sendfile on; send_timeout 25; 默认是60s }
服务器传送http响应信息到客户端的超时时间,这个超时仅仅为俩次成功握手后的一个超时,非请求整个响应数据的超时时间,若是在这个超时时间内,客户端没有接收任何数据,连接将被关闭。
备注,细节能够参考http://nginx.org/en/docs/http/ngx_http_core_module模块
可设置在http,server,location字段标签里
http {
sendfile on;
client_max_body_size 8m; 默认是1m
}
设置最大容许客户端请求主体的大小,post请求
nginx gzip压缩模块提供了压缩文件内容的功能,用户请求内容在发送用户客户端以前,nginx服务器会根据一些具体的策略实施压缩,已节约网站出口带宽,同时加快传输效率,来提高用户访问体验
nginx gzip压缩的优势
须要和不须要压缩的对象
功能依赖于ngx_http_gzip_module模块,默认已安装
这个模块主要是负责Gzip功能的开启和设置,对响应数据进行在线实时压缩。指令以下
语法 | 说明 |
---|---|
是否开启压缩 gzip on | off |
该指令用于开启或者关闭Gzip功能, 默认状况下该指令设置为off,只有为on时,下面指令才有效 |
压缩须要申请的空间 gzip_buffers number size |
number:指定Nginx服务器须要向系统申请缓存空间的个数 size :指定缓存空间的大小; 根据该配置,nginx在对响应输出数据经压缩时须要向系统申请number*size 大小的空间用来存储压缩数据. 默认大小是128,其中size的值是取系统内存页一页的大小,为4kb或者8kb 即: gzip_buffers 32 4k | 16 8k |
压缩等级 gzip_comp_level level |
该指令用于设置Gzip压缩程度,包括级别1-9, 级别1表示压缩程度最低效率最高, 级别9表示 压缩程度最高,效率最低 。 默认值是1 |
根据客户端类型动态开启压缩 gzip_disabel regex… |
针对不一样的客户端的请求,能够选择性的开启和关闭Gzip的功能 ,Nginx服务器在响应这种种类的客户端请求时,不使用Gzip功能缓存响应输出数据。regex根据客户端的浏览器标志(User-Agent,UA)设置,支持正则表达式。 例如 gzip_disable MSIE [4-6] 表示MSIE四、MSIE五、MSIE六、这些客户端请求后,nginx不进行Gzip压缩返回 |
根据浏览器版本是否开启压缩 gzip_http_version version |
早期的浏览器也许不支持Gzip的自解压,所以客户端有可能会看到乱码,因此针对不一样的HTTP协议版本,须要选择性地开启或者关闭Gzip功能。 默认设置为1.1版本,即只有客户端1.1及以上版本的HTTP协议,才使用Gzip压缩功能,目前来看大部分浏览器都支持Gzip自解压,因此使用默认值便可。 |
根据响应数据大小是否开启压缩 gzip_min_length length |
Gzip压缩功能对大数据的压缩效果明显,可是若是压缩的数据很小,就可能数据越压缩越大,所以咱们也应该有选择的压缩。当响应页面的大小大于该值才开启Gzip压缩功能。响应页面的大小经过HTTP响应头部中的Content-Length指令获取,若是咱们使用了Chunk编码压缩,Content-Length或不存在或被忽略,这条指令这不起做用。 默认值是20,设置为0表示无论页面多大都要压缩。建议大于1kb的压缩;好比:gzip_min_length 1024 |
根据响应头部是否开启压缩 gzip_proxied off|expired |no-cache | no-store | private | no_last_modified | no_etag | auth | any …; |
off:表示关闭Nginx服务器对后端服务器返回结果的压缩,这是默认设置 expired:表示当后端服务器响应页头部包含用于指示响应数据过时时间的expired头域时,启用对响应数据的Gzip压缩 no-cache:表示当后端服务器响应页头部包含用于通知缓存机制是否缓存的Cache-Control头域,且其指令值为no-cache时,启用对响应数据的Gzip压缩 no-store:表示当后端服务器响应页头部包含用于通知缓存机制是否缓存的Cache-Control头域,且其指令值为no-store时,启用对响应数据的Gzip压缩 private:表示当后端服务器响应页头部包含用于通知缓存机制是否缓存的Cache-Control头域,且其指令值为private时,启用对响应数据的Gzip压缩 no_last_modified:表示当后端服务器响应页头部不包含用于指明获取数据最后修改时间的Last-Modified头域时,启动对响应数据的Gzip压缩 no_etag:表示当后端服务器响应页头部不包含用于标示被请求变量的实体值的ETag头域时,启动对响应数据的Gzip压缩 auth:表示当后端服务器响应页头部包含用于标示HTTP受权证书的Authorization头域时时,启动对响应数据的Gzip压缩 any:无条件启动对响应数据的Gzip压缩 |
根据响应页的MIME类型开启是否压缩 gzip_types mime-type …; |
这个mime-type的默认值是text/html,实际上当gzip设置为on的时候,Nginx服务器会对全部的text/html类型的页面进行Gzip压缩,该变量还能够取值“*”,表示对全部的MIME类型页面进行压缩,通常咱们以下设置: gzip_types text/plain application/x-javascript text/css text/html application/html; |
用与设置Gzip功能是否发送带有“Vary:Accept-Encoding”头域的响应头部 gzip_vary on | off |
该头域的主要功能主要是告诉接收方发送的数据时经过压缩处理,开启后的效果是在响应头部添加Accept-Encoding:gzip.这对于自己不止Gzip压缩的客户端浏览器是颇有用的。 默认是off的,固然我也能够经过nginx配置的add_header指令强制Nginx服务器在响应头部添加“Vary:Accept-Encoding”头域: add_header Vary Accept-Encoding gzip; |
参考以下
gzip on;
gzip_min_length 1k;
gzip_comp_level 6;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary on;
gzip_disable "MSIE [1-6]\.";
就是本地浏览器缓存的有效期,配置参数以下
(1)根据文件扩展名进行判断,添加expires功能,server字段标签中
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)${
expires 3650d;
}
(2) 根据url中的路径(目录)进行判断,添加expires功能
location ~ ^/(images|javascript|js|css|flash|media|static)/ {
expires 360d;
}
(3) 单个文件添加expires功能
下面的命令会给robots.txt机器人文件设置过时时间
location ~ (robots.txt) { expires 70d; break; }
对于负载均衡器健康节点检查或某些特定文件(好比图片,js,css)的日志,由于在统计pv时时按照页面计算的,并且日志写入太频繁会消耗大量磁盘i/o,下降服务的性能
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)${
access_log off;
}
日志权限不要设为nginx,www用户读或写许可。
ab -c 1 -n 10 http://1.1.1.1/ -c 并发数,-n请求总数,1.1.1.1为nginx的ip地址
server { listen port; server_name localhost; root html/a; index index.php; location / { #try_files $uri $uri/ /index.php =404; try_files $uri $uri/ /index.php =500; } error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } location ~ \.php$ { try_files $uri = 404; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } }
用户请求 http://localhost/example 时,这里的 $uri 就是 /example。 try_files 会到硬盘里尝试找这个文件。若是存在名为 /$root/example(其中 $root 是项目代码安装目录html/a)的文件,就直接把这个文件的内容发送给用户。 显然,目录中没有叫 example 的文件。而后就看 $uri/,增长了一个 /,也就是看有没有名为 /$root/example/ 的目录。 又找不到,就会 fall back 到 try_files 的最后一个选项 /index.php,发起一个内部 “子请求”,也就是至关于 nginx 发起一个 HTTP 请求到 http://localhost/index.php。 这个请求会被 location ~ .*\.(php|php5)?$ { ... } catch 住,也就是进入 FastCGI 的处理程序。而具体的 URI 及参数是在 REQUEST_URI 中传递给 FastCGI 和 PHP 程序的,所以不受 URI 变化的影响。