Nginx服务优化

Posted oldxulinux

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nginx服务优化相关的知识,希望对你有一定的参考价值。


1.1nginx.conf配置文件基本参数优化

1.1.1  隐藏nginx header内版本号信息

一些特定的系统及服务漏洞一般都和特定的软件及版本号有关,我们应尽量隐藏服务器的敏感信息(软件名称及版本等信息)这样黑客无法猜到有漏洞的服务是否是对应服务的版本,从而确保web服务器最大的安全。

彻底修改nginx错误返回页面,在编译安装之前修改nginx.h文件

  sed -n \'13,17p\' src/core/nginx.h

  #define NGINX_VERSION      "1.6.3"   #将版本随便修改为"8.8.8"

  #define NGINX_VER          "nginx/" NGINX_VERSION

  #define NGINX_VAR          "NGINX"   #NGINX更改为XuLiangWei

   #define NGX_OLDPID_EXT     ".oldbin"

 

 

  sed -n \'49p\' src/http/ngx_http_header_filter_module.c

  static char ngx_http_server_string[] = "Server: nginx" CRLF;  #将nginx更改为XuLiangWei

  sed -i \'s#Server: nginx#Server: OWS#g\' ngx_http_header_filter_module.c  #sed替换方法

 

 

  sed -n \'21,29p\' src/http/ngx_http_special_response.c

  static u_char ngx_http_error_full_tail[] =

  "<hr><center>" NGINX_VER "</center>" CRLF  #将nginx修改为"xuliangwei.com"

  "</body>" CRLF

  "</html>" CRLF

 

 

  http

{

  ......

  server_tokens off;   #在nginx.conf配置文件中,直接使用,网站的错误页面还是会显示版本号信息

  ......

}    

通过浏览器访问也没有nginx的版本号,这样才能确保nginx版本号不被黑客知道。

说明:

q   提升网站安全,要从最简单、最短板、最低点入手解决问题,门大开着,窗户安装再结实也没有意义

q   向有经验的人及优秀的网站公司学习

q   学习看官方闻到那股,根据一手资料去分析

q   命令行输出结果中含有需要过滤掉或者保留的内容时,命令自身可能有参数直接实现。

q   掌握技术思想比解决问题本身更重要:http://oldboy.blog.51cto.com/2561410/1196298

1.1.2  更改nginx默认用户及用户组

为了web服务更安全,我们要尽可能的改掉所有软件默认的配置,包括端口,用户等。例如:前面的linux基础安全,我们就更改过ssh服务的22端口以及禁止root ssh连接等。

更改nginx的用户和用户组的操作方法和步骤如下:

[root@Nginx conf]# pwd  #查看当前路径

/application/nginx/conf

[root@Nginx conf]# grep "#user" nginx.conf.default  #过滤出默认用户

#user  nobody;    #1.一般情况,nginx服务启动,使用的用户和组默认都是nobody,查看默认配置如下

为了防止黑客猜到这个web服务的用户,我们需要更改特殊的用户名例如:nginx或者特殊点xuliangwei,但是这个用户必须是系统里存在的。

 

 

[root@Nginx conf]# useradd nginx -s /sbin/nologin –M  #2.建立nginx用户不需要有系统登录权限,应当禁止其登录能力

[root@Nginx conf]# id nginx  #检查用户用户是否创建成功

uid=500(nginx) gid=500(nginx) groups=500(nginx)

 

 

user  nginx nginx;     ß3.更改nginx服务默认用户和组的方法有两种,第一种为直接更改配置文件参数:

如果注释或不设置上述参数,默认即是nobody用户和组,不推荐使用nobody用户名称,最好采用一个普通用户,如nginx或特殊点的xuliangwei

 

[root@Nginx conf]# ../sbin/nginx -V  ß4.更改默认用户的第二种方法:直接在编译nginx软件时指定编译的用户和组

nginx version: nginx/1.6.3

built by gcc 4.4.7 20120313 (Red Hat 4.4.7-16) (GCC)

TLS SNI support enabled

configure arguments: --prefix=/application/nginx-1.6.3 --user=nginx --group=nginx --with-http_ssl_module --with-http_stub_status_module

提示:其实,在前面编译nginx服务时,我们就是这样呆着参数编译的。

 

5.最后检查nginx进程的对应用户如下

[root@Nginx conf]# ps aux|grep nginx|grep -v grep     

root3999  0.0  0.244556  1044 ?        Ss07:56   0:00 nginx: master process /application/nginx/sbin/nginx

nginx4001  0.0  0.344988  1624 ?        S07:56   0:00 nginx: worker process

 

6.更改nginx默认用户及用户组结论

通过查看杉树更改后的nginx进程,我们看到了worker processes的进程对应用户都变成了nginx了。所以,我们有理由得出结论,上述的两种方法都是设置Nginx的worker进程运行的用户的,Nginx的主进程还是以root身份运行的,当然,后文也会有不用root起主进程服务的技巧。

1.1.3  配置nginx worker进程个数

在高并发场景,我们需要事先启动更多的nginx进程以保证快速响应并且处理用户的请求。具体的配置参数如下:

worker_processes8;       ß指定了Nginx要开启的进程数。建议指定的CPU的数量相等或乘2的进程数。

worker_processes参数开始的设置可以等于cpu的个数或核数(worker_cpu_affinity参数中的配置可以指定第一个到最后一个进程分别使用的哪个cpu),进程数多一些,起始提供服务时就不会临时启动新进程提供服务,减少额系统开销,提升了服务速度。特殊场合也可以考虑提高至CPU*2的进程数,具体情况要根据实际的业务来选择,因为这个参数除了CPU盒数影响外,和硬盘存储的数据以及负载也有关。

 

[root@Nginx conf]# grep "physical id" /proc/cpuinfo       ß1.查看Linux服务器的盒数的方法

physical id: 0

[root@Nginx conf]# grep "worker_processes"  nginx.conf    ß2.查看默认的nginx.conf里worker_processes数

worker_processes2;

 

这里我们修改参数值为4,然后重新加载nginx服务,操作过程及结果:

[root@Nginx conf]# sed -i \'s#worker_processes2;#worker_processes  4;#g\' nginx.conf      ß1.修改配置

[root@Nginx conf]# grep "worker_processes"  nginx.conf    ß2.检查修改结果                              

worker_processes4;

[root@Nginx conf]# /application/nginx/sbin/nginx -t       ß3.nginx程序测试是否正确

nginx: the configuration file /application/nginx-1.6.3/conf/nginx.conf syntax is ok

nginx: configuration file /application/nginx-1.6.3/conf/nginx.conf test is successful

[root@Nginx conf]# /application/nginx/sbin/nginx -s reload       ß4.优雅重启nginx

 [root@Nginx conf]# ps aux|grep "nginx"|grep -v "grep"     ß5.检查进程数    

root3999  0.0  0.344556  1704 ?        Ss07:56   0:00 nginx: master process /application/nginx/sbin/nginx

nginx4197  0.0  0.345008  1740 ?        S08:32   0:00 nginx: worker process       

nginx4198  0.0  0.345008  1668 ?        S08:32   0:00 nginx: worker process       

nginx4199  0.0  0.345008  1740 ?        S08:32   0:00 nginx: worker process       

nginx4200  0.0  0.345008  1740 ?        S08:32   0:00 nginx: worker process 

提示:可以看到,当worker_processes 4;worker进程数为4个。Master主进程不包含在内。

1.1.4  根据cpu核数进行nginx进程优化

默认情况nginx的多个进程可能更多的跑在一颗cpu上,本节是分配不同的进程给不同的cpu处理,达到充分利用硬件多核多CPU的目的。

不同的cpu对用配置如下:

worker_cpu_affinity 0001 0010 0100 1000;    ß四核cpu服务器:

ßnginx进程CPU亲和力,即把不同的进程分给不同的CPU处理。

1.1.5  时间处理模型优化

Nginx的连接处理机制在于不同的操作系统采用不同的IO模型,在linux使用epoll的IO多路复用模型,在freed使用kqueue的IO多路复用模型,在solaris使用/dev/poll方式的IO多路复用模型,在windows使用的是icop等等。

根据系统类型不同选择不同use [ kqueue| rtsig | epoll | /dev/poll |select |poll];该参数结合系统使用,不同系统使用参数不同,我们使用的是Centos6.7,因此我们调整为epoll模型。

1.具体的配置参数如下:

events      ßevents指令是设定Nginx的工作模式及连接数上限。

{

  use epoll;    ßuse是个事件模块指令,用来指定Nginx的工作模式。Nginx支持的工作模式有select、poll、kqueue、epoll、rtsig和/dev/poll。其中select和poll都是标准的工作模式,kqueue和epoll是高效的工作模式,不同的是epoll用在Linux平台上,而kqueue用BSD系统中。对于Linux系统Linux2.6的内核,推荐选择epoll工作模式,这是高性能高并发的设置。

}

1.1.6  调整单个进程允许的客户端最大连接数

这个值根据具体服务器性能和程序的内存使用量来指定(一个进程启动使用额内存根据程序确定)

events      ßevents指令是设定Nginx的工作模式及连接数上限。 

{

worker_connections  20480;    ßworker_connections也是个事件模块指令,用于定义Nginx每个进程的最大连接数,默认是1024.最大客户端连接数有worker_processes和worker_connections决定,即Max_client=worker_processes*worker_connections。进程的最大连接数受Linux系统进程的最大打开文件数限制,在执行操作系统命令 “ulimit –HSn 65535”或配置相应文件后worker_connections的设置才能生效。

}

1.1.7  配置每个进程最大文件打开数

worker_rlimit_nofile 65535;  #放置最上面。每个进程打开的最大文件数,可设置为系统优化后的ulimit –HSn的结果,在第一章系统安装时,调整文件描述符和这个处理的一个问题。

1.1.8  优化服务器名字的hash表大小

确切名字和通配符名字存储在哈希表中。哈希表和监听端口关联,每个端口都最多关联到三张表;确切名字的哈希表,以星号起始的通配符名字的哈希表和以星号结束的通配符名字的哈希表。哈希表的尺寸在配置阶段进行了优化,可以以最小的CPU缓存命中失败来找到名字。Nginx首选搜索确切名字的哈希表,如果没有找到,搜索以星号起始的通配符名字的哈希表,如果还是没有找到,继续搜索以星号结束的通配符名字的哈希表。因为名字是按照域名的节来搜索的,所以搜索通配符名字的哈希表比搜索确切名字的哈希表慢。注意nginx.org存储在通配符名字的哈希表中,而不在确切名字的哈希表中。正则表达式是一个一个串行的测试,所以是最慢的,而且不可扩展。

鉴于以上原因,请尽可能使用确切的名字。举个例子,如果使用nginx.org和www.nginx.org来访问服务器时最频繁的,那么将他们明确的出来就更为有效

 

下面这种方法相比更简单,但是效率也更低:

server {

listen       80;

server_name  nginx.org ;

….

}

 

server {

listen       80;

server_name  nginx.org *.nginx.org;

….

}

1.1.9  开启高效文件传输模式

  sendfile        on;  #sendfile参数用于开启文件高效传输模式。同时将tcp_nopush和tcp_nodelay两个指令设置为on用于防止网络阻塞。

  tcp_nopush     on;   #打开linux下TCP_CORK,sendfile参数打开时才有效,减少报文段的数量之用。  

建议:在http段开启上述功能。

1.1.10设置连接超时时间

 keepalive_timeout   60;   #设置客户端连接保持会话的超时时间。超过这个时间,服务器会关闭该连接。

 tcp_nodelay         on;       #打开tcp_nodelay,在包含了keepalive参数才有效

 client_header_timeout 15; #设置客户端其你去头读取超时时间。如果超过这个时间,客户端还没有发送任何数据,Nginx将返回”Request timeout(408)”错误

 client_body_timeout 15;  #设置客户端请求主体读取超时时间。如超过这个时间,客户端还没有发送任何数据,Nginx将返回”Request timeout(408)”错误 默认值是60.

 send_timeout       15;    #指定响应客户端的超时时间。这个超时仅限于两个链接活动之间的时间,如果超过这个时间,客户端没有任何活动,Nginx将会关闭连接。

1.1.11上传文件大小限制(动态应用)

主配置文件里加入如下参数,具体大小根据你自己的业务做调整。

client_max_body_size 10m;

1.1.12fastcgi调优(配合php引擎动态服务)

 

 

读磁盘写入buffer缓冲区

fastcgi_connect_timeout 120;  #指定连接到后端FastCGI的超时时间,默认60s。

fastcgi_send_timeout 120;  #向FastCGI传送请求的超时时间,这个值是指已经完成两次握手后向FastCGI传送请求的超时时间,默认60s。

fastcgi_read_timeout 120;  #指定接受FastCGI应答的超时时间,这个值是指已经完成两次握手后接受FastCGI应答的超时时间。

fastcgi_buffer_size 64k;  #指定读取astCGI应答第一部分需要用多大的缓冲区,这个值表示将使用1个64KB的缓冲区读取应答的第一部分(应答头),可以设置为fastcgi_buffers现象指定的缓冲区大小。

fastcgi_buffers 4 64k;  #指定本地需要用多少盒多大的缓冲区来缓存FastCGI的应答请求。如果一个PHP脚本所产生的页面大小为256KB,那么会为其分配4个64KB的缓冲区来缓存:如果页面大小大于256KB,那么大于256KB的部分会缓存到fastcgi_temp指定的路径中,但是这并不是好方法,因为内存中的数据处理熟读要快于硬盘。一般这个值应该为站点中PHP脚本所产生的页面大小的中间值,如果站点大部分脚本所产生的页面大小为256KB,那么可以把这个值设置为16 16k、“4 64k”等。

fastcgi_busy_buffers_size 128k;  #建议为fastcgi_vuffers的两倍

fastcgi_temp_file_write_size 128k;  #在写入fastcgi_temp_path时将用多大的数据库,默认值是fastcgi_buffers的两倍,设置上述数值设置太小时,若负载上来时可能报502 Bod Gateway

#fastcgi_cache oldboy_nginx;  #表示开启FastCGI缓存并未其指定一个名词。开启缓存非常有用,可以有效降低CPU的负载,并且防止502错误的发生,但是开启缓存也可能会引起其他问题,要根据具体情况选择。

 

用户读取cache缓存区

fastcgi_cache_valid 200 302 1h;  #用来指定应答代码的缓存时间,实例中的值表示将200和302应答缓存一个小时

fastcgi_cache_valid 301 1d; #将301应答缓存1天     

fastcgi_cache_valid any 1m;  #将其他应答缓存为1分钟

fastcgi_cache_min_uses 1;  #缓存在fastcgi_cache_path指令inactive参数值时间内的最少使用次数

1.1.13配置nginx gzip压缩功能

Nginx gzip压缩模块提供了对文件内容压缩的功能,允许nginx服务器将输出内容在发送到客户端之前根据具体的策略进行压缩,以节约网站带宽,同时提升用户访问体验。此功能同apache的mod_deflate压缩功能,依赖ngx_http_gzip_module模块,默认已安装我们已经详细讲解过了压缩的功能。(一般配置在http标签全局生效)

 

gzip  on;      #开启gzip压缩功能

gzip_min_length 1k; #设置允许压缩的页面最小字节数,页面字节数从header头的Content-Length中获取。默认值是0,不管页面多大都进行压缩。建议设置成大于1k。如果小于1k可能会越压越大。

gzip_buffers 4 32k;  #压缩缓存区大小。表示申请4个单位为16k的内存作为压缩结果流缓存,默认值是申请与原始数据大小相同的内存空间来存储gzip压缩结果。

#gzip_http_version 1.1;  #压缩版本(默认1.1,前端为squid2.5时使用1.0)用于设置识别HTTP协议版本,默认是1.1,目前大部分浏览器已经支持GZIP解压,使用默认即可(可以不用配置)。

gzip_comp_level 9;  #压缩比率。用来指定GZIP压缩比,1压缩比最小,处理速度最快;9压缩比最大,传输速度快, 处理最慢,也比较消耗cpu资源。

gzip_types text/plain application/x-javascript text/css application/xml;       ß用来指定压缩的类型,“text/html”类型总是会被压缩。

gzip_vary on;      ßvary header支持。该选项可以让前端的缓存服务器缓存经过GZIP压缩的页面,例如用Sqiud缓存经过Nginx压缩的数据。

提示:gzip_types类型不同的版本可能会有不同,上述是适合1.6.3的nginx。对用的文件类型查看安装目录下的mime.types文件。

建议:大于1k的纯文件文件html,js,css,xmlshtml。图片,视频等不要压缩。因为不但不会减小,在压缩时消耗CPU,MEM资源。

1.1.14配置nginx expires缓存功能

在网站开发和运营中,对于图片,CSS,JS,html等代码缓存10天,这样用户第一次打开页面后,会在本地的浏览器缓存相应的上述内容,这样的缓存可以提高下次用户打开类似页面的加载速度,并节省服务器端大量的带宽。此功能同apache的expires,我们已经详细讲解过了。这里通过location的功能,昂需要缓存的扩展名列出来,然后指定缓存时间。

Expire功能优点:

Expires可以降低网站购买的带宽,节约成本,同时提升了用户访问体验,是web服务非常重要的功能。

Expire功能缺点:

被缓存的页面或数据更新了,用户看到的可能还是旧的内容,反而影响用户体验。

解决办法:

第一个:缩短缓存时间,例如:1天,不彻底,除非更新频繁率大于1天。

第二个:对缓存的对象改名。

图片,附件一般不会被用户修改,如果用户修改了,实际上也都是更改文件名重新传了而已。

网站升级对于js,css元素,一般可以改名。

 

location ~ .*\\.(gif|jpg|jpeg|png|bmp|swf)$

        {

expires  3650d;      ß一年(以gif|jpg|jpeg|png|bmp|swf结尾的)

        }

location ~.*\\.(js|css)?&

        {

expires  30d;      ß一月

        }

特别注意:location内容一般防到虚拟主机配置中,即server标签中。

 

根据目录进行判断,添加expires功能范例

location ~ ^/(images|javascript|js|flash|media|static)/ {

expires 360d;

}

单个文件添加expires功能范例(给robots.txt设置过期时间;这里为robots.txt为7天并不记录404错误日志)

  location ~(robots.txt) {

log_not_found off;

     expires 7d;

     break;

}

1.1.15使用tmpts文件系统替代频繁访问的目录

[root@Nginx ~]# mkdir /opt/tmp

[root@Nginx ~]# cd /tmp

[root@Nginx tmp]# mv * /opt/tmp/

[root@Nginx tmp]# mount -t tmpfs -o size=16m tmpfs /tmp

   [root@Nginx tmp]# df -h

FilesystemSize  Used Avail Use% Mounted on

/dev/sda362G  4.2G   55G8% /

tmpfs244M     0  244M0% /dev/shm

/dev/sda1190M   36M  145M20% /boot

tmpfs16M     0   16M0% /tmp 

想要永久生效,可以放在/etc/rc.local 或者是 /etc/fstab

1.1.16最小化目录及文件权限设置

 

为了保证网站不遭受目录入侵上传及修改文件。

安全的权限:

所有站点目录的用户和组都应该为root

所有目录权限是默认的755

所有文件权限是默认的644

注意:网站服务的用户不能用root

以上的权限设置可以做到防止黑客上传目录,以及修改站点文件,但是,合理的用户上传的内容也被拒之门外了。那么如何解决可以让合法的用户传文件又不至于被黑客利用攻击呢?

这就是对业务进行分离,在比较好的网站额外架构中,应把资源文件,包括用户上传的图片,附件等的服务和程序服务分离,最好把上传程序服务也分离,这样可以从容按照前面的标准授权了。

大多数公司的不安全授权如下:

chmod –R 777 /sitedir

chown –R nginx.nginx /sitedir

1.1.17Nginx限制HTTP请求方法

我们可以通过Nginx限制Http请求的方法来达到提升服务器安全的目的,例如让Http只能使用GET、HEAD和POST方法的配置如下:

#Only allow these request methods

     if ($request_method !~ ^(GET|HEAD|POST)$ ) {

return 501;

     }

 

#Only allow these request methods

     if ($request_method ~* ^(GET)$ ) {

return 501;

     }

1.1.18Nginx图片及目录防止盗链

 

 

  a.根据http referer实现防盗链

     在http协议中,有一个表头叫referer,使用URL格式来表示从那里来的连接到当前的网页资源。通过referer可以检测目标访问的来源网页,如果是资源文件,可以跟踪到显示它的网页地址,一旦检测出来来源不是本站的,就进行阻止或者返回到指定的页面,Apache,nginx,lighttpd三者都支持防盗链

  b.根据cookies处理

  c.通过加密变换路径实现防盗链

  利用浏览器的referer并且针对扩展名rewrite重定向

location ~ .*\\.(jpg|gif|png|swf|flv|wma|wmv|asf|mp3|mmf|zip|rar)?$ {

valid_referers none blocked *.etiantian.org etiantian.org;

        if ($invalid_referer) {

rewrite ^/ http://www.etiantian.org/img/nolink.jpg;

}

       }

http://oldboy.blog.51cto.com/2561410/909696  流量暴涨

nginx实现下载防盗链模块

http://nginx.org/en/docs/http/ngx_http_secure_link_module.html

1.1.19禁止不同浏览器软件访问

if ($http_user-agent ~* "Firefox|MSIE 8.0"){

#return 403;

     rewrite ^(.*) http://www.xuliangwei.com/$1 permanent;

}

#如果客户端浏览器是firefox或者ie则跳转到www.xuliangwei.com域名,或者也可以给出403错误

1.1.20防止网站恶意解析

案例:你的网站权重比较高,为了提高权重,然后有人恶意解析域名到你的服务器ip地址

  方法一:

server {

listen 80 default;

return 500;

}

第二种方式:

  server {

  listen 80 default_server;

  server_name _;

  return 501;

  } 

 

  方法二:301跳转到本域名,但是还是有非法解析(不推荐)

   if ($host !~ ^www/.eduoldboy/.com$){

      rewrite ^(.*)  http://www. eduoldboy.com$1 permanent;

  } 

1.1.21Nginx防爬虫

if ($http_user_agent ~* "qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot") {

     return 403;

}

1.2Nginx日志相关优化与安全

Nginx没有类似Apache的cronolog日志分割处理的功能,但是可以通过Nginx的信号控制功能或者reload重新加载,然后利用脚本来实现日志的自动切割。

向 Nginx 主进程发送 USR1 信号。USR1 信号是重新打开日志文件(不需要重启服务可能是更好的选择)

 [root@LNMP scripts]# cat cut_log.sh

#!/bin/sh

date=`date +%Y%m%d`

bashdir="/application/nginx"

log_dir="$bashdir/logs"

logname="access_www"

nginxpid=`cat /application/nginx/logs/nginx.pid`

#nginxpid=`ps aux | grep nginx |awk  \'NR==1{print $2}\'`

 

[ -d $log_dir ] && cd $log_dir || exit 1

 

if  [ -f ${logname}.log ];then

    /bin/mv ${logname}.log  ${date}_${logname}.log && \\

     kill -USR1 $nginxpid

else

 echo "plese touch $logname.log"

 exit 2

fi

每天凌晨切割

[root@LNMP scripts]# crontab -l

#################

00 00 * * * /bin/sh  /server/scripts/cut_log.sh >/dev/null 2>&1

1.2.1  不记录不需要的访问日志

对于健康检查或某些(图片,js,css)的日志,一般不需要记录,因为在统计PV时是按照页面计算。而且日志写入频繁会消耗磁盘IO,降低服务性能。

location ~ .*\\.(js|jpg|JPG|jpeg|JPEG|css|bmp|gif|GIF)$ {

access_log off;

}

1.2.2  访问日志的权限设置

假如日志目录为/app/logs,则授权方法

[root@Nginx ~]# mkdir /app/logs –p  #创建/app/logs目录

[root@Nginx ~]# chown -R root.root /app/logs/  #授权/app/logs目录的属主属组为root

[root@Nginx ~]# chmod 700 /app/logs/  #赋予属主读写执行权限

[root@Nginx ~]# ll -d /app/logs/  #查看权限是否ok

drwx------ 2 root root 4096 Oct 10 10:02 /app/logs/

提示:不需要在日志目录上给nginx用户读或者写的许可,否则会有安全隐患,所以不适用nginx用户,只所以设置root也能写入日志,因为nginx的主进程是root用户,所以能够写入。

1.3Nginx站点目录及文件URL访问控制

1.3.1  根据扩展名限制程序和文件访问

Nginx下禁止访问资源目录下的php程序文件,(配置在server标签下)写在php解析前面配置方法如下:

location ~^/images/.*\\.(php|php5)$

{

deny all;

}

location ~ ^/static/.*\\.(php|php5|.sh|.pl|.py)$ 

     deny all; 

    location ~ ^/data/(attachment|avatar)/.*\\.(php|php5)$ 

          deny all;

Nginx下配置禁止访问单目录或多目录(配置在server标签下)配置方法如下:

location ~^/(static)/{

deny all;

}

location ~^/static{

deny all;

}

 

location ~^/(static|js){

deny all;

}

1.3.2  限制来源IP访问

使用nginx_http_access_module模块限制ip访问

范例1:禁止目录让外界访问,但允许某IP访问该目录,且支持PHP解析

location ~ ^/oldboy/ {

        allow 202.111.12.211;

        deny all;

    }

    location ~ ^/oldboy/ {

        deny 192.168.1.1;

        allow 192.168.1.0/24;

        allow 10.1.1.0/16;

        deny all;

    }

企业安利:Nginx做反向代理的时候可以限制客户端IP吗?

使用if来控制

if ( $remote_addr = 10.0.0.8 ){

return 403;

}

if ( $remote_addr = 208.247.17.130 ) {

set $allow_access_root ‘true’;

}

 

1.4Nginx错误页面优雅显示

1.4.1  生产环境常见的HTTP状态码列表

生产环境常见的HTTP状态码列表(List of HTTP status codes)为:
说明:求精不求多,有舍才有得 不一样的思维不一样的精彩。《老男孩linux实战培训》也是这个原则。

200 - OK,服务器成功返回网页 
    - Standard response for successful HTTP requests.

301 - Moved Permanently(永久跳转),请求的网页已永久跳转到新位置。
    - This and all future requests should be directed to the given.

403 - Forbidden(禁止访问),服务器拒绝请求
    - forbidden request (matches a deny filter) => HTTP 403
    - The request was a legal request, but the server is refusing to respond to it.

404 - Not Found,服务器找不到请求的页面。
    - The requested resource could not be found but may be available again in the future.

500 - Internal Server Error(内部服务器错误)
    - internal error in haproxy => HTTP 500
    - A generic error message, given when no more specific message is suitable.

502 - Bad Gateway(坏的网关),一般是网关服务器请求后端服务时,后端服务没有按照http协议正确返回结果。
    - the server returned an invalid or incomplete response => HTTP 502
    - The server was acting as a gateway or proxy and received an invalid response from the upstream server.

503 - Service Unavailable(服务当前不可用),可能因为超载或停机维护。
    - no server was available to handle the request => HTTP 503
    - The server is currently unavailable (because it is overloaded or down for maintenance).

504 - Gateway Timeout(网关超时),一般是网关服务器请求后端服务时,后端服务没有在特定的时间内完成服务。
    - the server failed to reply in time => HTTP 504
    - The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.

1.4.2  为什么要配置错误页面优雅显示

error_page   404http://oldboy.blog.51cto.com;

阿里门户网站天猫的Nginx优雅显示配置案例如下:

error_page500 501 502 503 504  http://xuliangwei.com/error2.html;

error_page 400 403 404 405 408 410 411 412 413 414 415 http://xuliangwei.com/error1.html;

1.5系统内核参数优化

kernel.shmall = 4294967296

net.ipv4.tcp_fin_timeout = 2

net.ipv4.tcp_tw_reuse = 1

net.ipv4.tcp_tw_recycle = 1

net.ipv4.tcp_syncookies = 1

net.ipv4.tcp_keepalive_time = 600

net.ipv4.ip_local_port_range = 4000    65000

net.ipv4.tcp_max_syn_backlog = 16384

net.ipv4.tcp_max_tw_buckets = 36000

net.ipv4.route.gc_timeout = 100

net.ipv4.tcp_syn_retries = 1

net.ipv4.tcp_synack_retries = 1

net.core.somaxconn = 16384

net.core.netdev_max_backlog = 16384

net.ipv4.tcp_max_orphans = 16384

net.ipv4.tcp_fin_timeout = 2

net.ipv4.tcp_tw_reuse = 1

net.ipv4.tcp_tw_recycle = 1

net.ipv4.tcp_syncookies = 1

net.ipv4.tcp_keepalive_time =600

net.ipv4.ip_local_port_range = 4000    65000

net.ipv4.tcp_max_syn_backlog = 16384

net.ipv4.tcp_max_tw_buckets = 36000

net.ipv4.route.gc_timeout = 100

net.ipv4.tcp_syn_retries = 1

net.ipv4.tcp_synack_retries = 1

net.core.somaxconn = 16384

net.core.netdev_max_backlog = 16384

net.ipv4.tcp_max_orphans = 16384

#for iptables

net.nf_conntrack_max = 25000000

net.netfilter.nf_conntrack_max = 25000000

net.netfilter.nf_conntrack_tcp_timeout_established = 180

net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120

net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60

net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120

#以下参数是对iptables防火墙的优化,防火墙不开会提示,可以忽略不理。

##net.nf_conntrack_max = 25000000

##net.netfilter.nf_conntrack_max = 25000000

##net.netfilter.nf_conntrack_tcp_timeout_established = 180

##net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120

系统内核参数详解:

 

1.6Include优化配置文件

Include包含文件或目录

Nginx的主配置文件为nginx.conf,主配置文件包含的所有虚拟主机统一放入extra目录中,虚拟主机的配置文件按照网站的域名或功能取名例如:bbs.conf blog.conf等。

如果虚拟主机的数量不是很多,也可以生成一个单独的配置文件,仅仅和Nginx的主配置文件nginx.conf分离开

规范配置文件,它可以放置Nginx配置中任何位置。

http {

…….

          include vhosts/*.conf;          ß包含vhosts下所有以conf结尾的文件

include extra/www.conf;     ß包含www网站虚拟主机配置文件

include extra/bbs.conf;         ß包含bbs网站虚拟主机配置文件

include extra/blog.conf;    ß包含blog网站虚拟主机配置文件

.......  

  }

1.7NGINX监牢模式

 

1.7.1  Nginx服务使用普通用户

默认情况下,Nginx的Master进程使用的是root用户,worker进程使用的是Nginx指定的普通用户,使用root用户跑Nginx的Master进程有两个最大的问题。

管理权限必须是root,这就使得最小化分配权限原则遇到难题。

使用root跑Nginx服务,一旦网站出现漏洞,用户就可以很容易地获得服务器的root权限。

因此,不用给开发人员,甚至普通运维人员管理权限,就可以很好的管理Nginx服务。

1.7.2  Nginx服务降权解决方案

q   给Nginx服务降权,用inca用户跑Nginx服务,给开发及运维设置普通账户,只要和inca同组即可管理Nginx,该方案解决了Nginx管理问题,防止root分配权限过大。

q   开发人员使用普通账户即可管理nginx服务以及站点下的程序、看日志。

q   采取项目负责制度,即谁服务项目维护出题就是谁负责。

很多公司开发和运维为争root权限不可开交,甚至大打出手的也有。

参考资料:到底要不要给开发人员管理服务器的权限?http://down.51cto.com/data/844517

[root@web-node1 ~]# useradd inca

[root@web-node1 ~]# su - inca

[inca@web-node1 ~]$ mkdir conf logs www

[inca@web-node1 ~]$ cp /application/nginx/conf/mime.types ./conf/

[inca@web-node1 ~]$ echo inca > www/index.html

[inca@web-node1 ~]$ cat conf/nginx.conf

worker_processes4;

worker_cpu_affinity 0001 0010 0100 1000;

worker_rlimit_nofile 65535;

error_log/home/inca/logs/error.log;

user inca inca;

pid/home/inca/logs/nginx.pid;

events {

    use epoll;

worker_connections  10240;

}

http {

include/home/inca/conf/mime.types;

default_typeapplication/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"\';

 

    server {

listen       8080;

server_name  www.etiantian.org;

root   /home/inca/www;

location / {

index  index.php index.html index.htm;

}

access_log/home/inca/logs/www_log_access.logmain;

}

}

[inca@web-node1 ~]$ /application/nginx/sbin/nginx -c /home/inca/conf/nginx.conf &>/dev/null

[inca@web-node1 ~]$ ps aux|grep nginx

inca1619  0.0  0.242452  1032 ?        Ss21:07   0:00 nginx: master process /application/nginx/sbin/nginx -c /home/inca/conf/nginx.conf

inca1620  0.0  1.046704  5296 ?        S21:07   0:00 nginx: worker process

inca1621  0.0  1.046704  5416 ?        S21:07   0:00 nginx: worker process

inca1622  0.0  1.046704  5416 ?        S21:07   0:00 nginx: worker process

inca1623  0.0  1.046704  5404 ?        S21:07   0:00 nginx: worker process

本解决方案的优点如下:

q   给Nginx服务降权,让网站更安全。

q   按用户设置站点权限,使站点更独立(无需虚拟化隔离)

q   开发不需要用root即可完整管理服务及站点。

q   可实现对责任划分:网络问题属于运维的责任,网站打不开就是开发责任或共同承担。

 

 

1.9Nginx程序架构优化

为网站程序解藕

解耦是开发人员中流行的一个名词,简单地说就是把一堆程序代码按照业务用途分开,然年后提供服务,例如:注册、登陆、上传、下载、用户中心、搜索、商品、价格、购物车、结算、物流、订单、评价、积分、积分抽奖、等应该是独立的程序服务,只不过在客户端看来是一个整体而已,如果中小公司做不到上述细致的解耦,起码也要让下面的几个程序模块独立。

q   网页页面服务。

q   图片附件及下载服务。

q   上传图片服务。

上述三者的功能尽量分离。

 

以上是关于Nginx服务优化的主要内容,如果未能解决你的问题,请参考以下文章

Nginx服务优化及优化深入

Nginx服务优化(由浅到深)!

Nginx服务优化(由浅到深)!

Nginx安全优化与性能调优

企业级Web Nginx 服务优化

根据参数优化nginx的服务性能