apache nginx优化

企业级web Nginx服务优化

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

隐藏nginx header内版本号信息

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

利用curl查看隐藏前header内的web版本号信息

[root@nginx ~]# curl -I 192.168.80.104

HTTP/1.1 200 OK

Server: nginx/1.6.3

Date: Tue, 24 May 2016 11:46:12 GMT

Content-Type: text/html

Content-Length: 5

Last-Modified: Fri, 29 Apr 2016 13:10:16 GMT

Connection: keep-alive

ETag: "57235d38-5"

Accept-Ranges: bytes

浏览器访问web服务报错信息

以上两个访问不但暴漏了nginx软件名称,而且暴漏了nginx特定的版本号,这样就会给服务的安全带来一定的风险,应禁止掉。

修改配置文件参数实现隐藏版本号

在nginx配置文件nginx.conf的http标签中加入"server_tokens off;"

官方文档:http://nginx.org/en/docs/http/ngx_http_core_module.html

Syntax: server_tokens on | off | string;

Default:

server_tokens on;

Context: http, server, location

Enables or disables emitting nginx version in error messages and in the “Server” response header field.

更改默认用户及用户组

nginx服务启动,使用的默认用户是nobody

[root@nginx www]# grep "#user" /application/nginx/conf/nginx.conf.default

#user nobody;

为了防止黑客猜到这个用户,我们需要更改下特殊的用户名,提供nginx服务用

更改默认用户的方法有两种,第一种为:

user nginx nginx #配置文件中修改

设置Nginx worker进程运行的用户以及用户组,如果注释或不设置,默认即是nobody用户和组,不推荐使用nobody用户名称,最好采用一个普通用户,如nginx。注意Nginx的主进程还是以root身份运行的,后文也会有不用root进程起服务的配置。

建立nginx用户的操作过程如下:

useradd -s /sbin/nologin -M nginx

第二种为:

useradd -s /sbin/nologin -M nginx #先添加一个用户

./configure --prefix=/application/nginx-1.6.3 --user=nginx --group=nginx --with-http_ssl_module --with-http_stub_status_module #编译nginx时指定用户

ps -ef|grep nginx|grep -v grep #检查nginx进程的对应用户

配置nginx worker进程个数

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

worker_processes 1;

指定了nginx要开启的进程数。建议指定和CPU的数量相等或乘2的进程数。

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

查看linux服务器的核数的方法

例如:CPU个(核)数为4,就配置worker_processes 4;

[root@nginx conf]# grep "physical id" /proc/cpuinfo

physical id : 0

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

[root@nginx conf]# grep worker_processes nginx.conf

worker_processes 4;

[root@nginx conf]# /application/nginx/sbin/nginx -t

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

[root@nginx conf]# ps -ef|grep nginx|grep -v grep

root 2144 1 0 19:53 ? 00:00:00 nginx: master process /application/nginx/sbin/nginx

nginx 2494 2144 0 21:55 ? 00:00:00 nginx: worker process

nginx 2495 2144 0 21:55 ? 00:00:00 nginx: worker process

nginx 2496 2144 0 21:55 ? 00:00:00 nginx: worker process

nginx 2497 2144 0 21:55 ? 00:00:00 nginx: worker process

官网文档:http://nginx.org/en/docs/ngx_core_module.html

Syntax: worker_processes number | auto;

Default: worker_processes 1;

Context: main

Defines the number of worker processes.

The optimal value depends on many factors including (but not limited to) the number of CPU cores, the number of hard disk drives that store data, and load pattern. When one is in doubt, setting it to the number of available CPU cores would be a good start (the value “auto” will try to autodetect it).

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

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

不同的CPU对应配置如下

四核cpu服务器:

worker_cpu_affinity 0001 0010 0100 1000;

#nginx进程CPU亲和力,即把不同的进程分给不同的CPU处理。这里0001 0010 0100 1000是掩码,分别代表第1、2、3、4颗cpu核心。

八核cpu服务器:

worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;

worker_cpu_affinity 0001 0010 0100 1000 0001 0010 0100 1000;

官方文档http://nginx.org/en/docs/ngx_core_module.html

Syntax: worker_cpu_affinity cpumask ...;

worker_cpu_affinity auto [cpumask];

Default: —

Context: main

Binds worker processes to the sets of CPUs. Each CPU set is represented by a bitmask of allowed CPUs. There should be a separate set defined for each of the worker processes. By default, worker processes are not bound to any specific CPUs.

For example,

worker_processes 4;

worker_cpu_affinity 0001 0010 0100 1000;

binds each worker process to a separate CPU, while

worker_processes 2;

worker_cpu_affinity 0101 1010;

binds the first worker process to CPU0/CPU2, and the second worker process to CPU1/CPU3. The second example is suitable for hyper-threading.

测试:

webbench -c 20000 -t 180 http://192.168.80.104 #测试过程这里不再叙述,也可以用ab

通过观察,我们发现配置后不同CPU使用率相对平均,和测试前变化不大。因此就认为比较平均,一方面是软件自身再逐渐的优化使用多核CPU,另一方面测试的数有待调整。

另外(taskset - retrieve or set a process's CPU affinity)命令本身也有分配CPU的功能

taskset -c 1,2,3 /etc/init.d/mysql start

事件处理模型优化

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

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

events {

worker_connections 1024;

use epoll;

}

官方文档http://nginx.org/en/docs/events.html

Syntax: use method;

Default: —

Context: events

Specifies the connection processing method to use. There is normally no need to specify it explicitly, because nginx will by default use the most efficient method.

The following connection processing methods are supported:

select — standard method. The supporting module is built automatically on platforms that lack more efficient methods. The --with-select_module and --without-select_module configuration parameters can be used to forcibly enable or disable the build of this module.

poll — standard method. The supporting module is built automatically on platforms that lack more efficient methods. The --with-poll_module and --without-poll_module configuration parameters can be used to forcibly enable or disable the build of this module.

kqueue — efficient method used on FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0, and Mac OS X.

epoll — efficient method used on Linux 2.6+.

Some older distributions like SuSE 8.2 provide patches that add epoll support to 2.4 kernels.

/dev/poll — efficient method used on Solaris 7 11/99+, HP/UX 11.22+ (eventport), IRIX 6.5.15+, and Tru64 UNIX 5.1A+.

eventport — event ports, efficient method used on Solaris 10.

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

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

events {

worker_connections 1024;

use epoll;

}

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

官方文档:http://nginx.org/en/docs/ngx_core_module.html#worker_connections

Syntax: worker_connections number;

Default:

worker_connections 512;

Context: events

Sets the maximum number of simultaneous connections that can be opened by a worker process.

It should be kept in mind that this number includes all connections (e.g. connections with proxied servers, among others), not only connections with clients. Another consideration is that the actual number of simultaneous connections cannot exceed the current limit on the maximum number of open files, which can be changed by worker_rlimit_nofile.

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

worker_rlimit_nofile 32768;

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

官方文档:http://nginx.org/en/docs/ngx_core_module.html#worker_rlimit_nofil

Syntax: worker_rlimit_nofile number;

Default: —

Context: main

Changes the limit on the maximum number of open files (RLIMIT_NOFILE) for worker processes. Used to increase the limit without restarting the main process.

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

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

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

server {

listen 80;

server_name www.etiantian.org etiantian.org *.etiantian.org ;

....

}

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

server {

listen 80;

server_name .etiantian.org ;

....

}

如果定义了大量名字,或者定义了非常长的名字,那就需要在http配置块中调整server_names_hash_max_size and server_names_hash_bucket_size的值。server_names_hash_bucket_size的默认值可能是32、64或其他值,取决于缓存行的长度。如果这个值是32,那么定义“too.long.server.name.example.org”作为虚拟主机名就会失败,显示下面错误信息

could not build the server_names_hash,

you should increase either server_names_hash_max_size: 512

or server_names_hash_bucket_size: 32

可以在http标签中添加如下一行

server_names_hash_bucket_size 64;

官方文档http://nginx.org/en/docs/http/ngx_http_core_module.html#server_names_hash_bucket_size

Syntax: server_names_hash_bucket_size size;

Default:

server_names_hash_bucket_size 32|64|128;

Context: http

Sets the bucket size for the server names hash tables. The default value depends on the size of the processor’s cache line. The details of setting up hash tables are provided in a separate document.

Syntax: server_names_hash_max_size size;

Default:

server_names_hash_max_size 512;

Context: http

Sets the maximum size of the server names hash tables. The details of setting up hash tables are provided in a separate document.

开启高效文件传输模式

sendfile on;

tcp_nopush on;

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

官方文档:http://nginx.org/en/docs/http/ngx_http_core_module.html#sendfile

Syntax: sendfile on | off;

Default:

sendfile off;

Context: http, server, location, if in location

Enables or disables the use of sendfile().

Starting from nginx 0.8.12 and FreeBSD 5.2.1, aio can be used to pre-load data for sendfile():

设置连接超时时间

keepalive_timeout 65;

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

tcp_nodelay on;

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

client_header_timeout 15;

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

client_body_timeout 15;

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

send_timeout 15;

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

官网文档:http://nginx.org/en/docs/http/ngx_http_core_module.html

Syntax: client_header_timeout time;

Default:

client_header_timeout 60s;

Context: http, server

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

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

client_max_body_size 10m;

官方文档:http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size

Syntax: client_max_body_size size;

Default:

client_max_body_size 1m;

Context: http, server, location

Sets the maximum allowed size of the client request body, specified in the “Content-Length” request header field. If the size in a request exceeds the configured value, the 413 (Request Entity Too Large) error is returned to the client. Please be aware that browsers cannot correctly display this error. Setting size to 0 disables checking of client request body size.

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

官网文档:http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html

fastcgi_connect_timeout 300;

#指定连接到后端fastCGI的超时时间

Syntax: fastcgi_connect_timeout time;

Default: fastcgi_connect_timeout 60s;

Context: http, server, location

fastcgi_send_timeout 300;

#向FastCGI传送请求的超时时间,这个值是指已经完成两次握手后向FastCGI传送请求的超时时间

Syntax: fastcgi_send_timeout time;

Default: fastcgi_send_timeout 60s;

Context: http, server, location

fastcgi_read_timeout 300;

#指定接收FastcGI应答的超时时间,这个值是指己经完成两次握手后接收FastCGI应答的超时时间。

Syntax: fastcgi_read_timeout time;

Default: fastcgi_read_timeout 60s;

Context: http, server, location

fastcgi_buffer_size 64k;

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

Syntax: fastcgi_buffer_size size;

Default: fastcgi_buffer_size 4k|8k;

Context: http, server, location

fastcgi_buffers 4 64k;

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

Syntax: fastcgi_buffers number size;

Default: fastcgi_buffers 8 4k|8k;

Context: http, server, location

fastcgi_busy_buffers_size 128k;

#建议为fastcgi_buffers的两倍

fastcgi_temp_file_write_size 128k;

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

fastcgi_cache oldboy_nginx;

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

fastcgi_cache_valid 200 302 1h;

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

fastcgi_cache_valid 301 1d;

fastcgi_cache_valid any 1m;

fastcgi_cache_min_uses 1;

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

以上参数集合

fastcgi_connect_timeout 300;

fastcgi_send_timeout 300;

fastcgi_read_timeout 300;

fastcgi_buffer_size 64k;

fastcgi_buffers 4 64k;

fastcgi_busy_buffers_size 128k;

fastcgi_temp_file_write_size 128k;

fastcgi_cache oldboy_nginx;

fastcgi_cache_valid 200 302 1h;

fastcgi_cache_valid 301 1d;

fastcgi_cache_valid any 1m;

fastcgi_cache_min_uses 1;

proxy.conf配置参数

location ~ .*\.(php|php5)?$ {

root /var/html/bbs;

fastcgi_pass 127.0.0.1:9000;

fastcgi_index index.php;

include fastcgi.conf;

include proxy.conf;

}

vi /application/nginx/conf/proxy.conf

proxy_redirect off;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

client_max_body_size 50m;

client_body_buffer_size 256k;

proxy_connect_timeout 30;

proxy_send_timeout 30;

proxy_read_timeout 60;

proxy_buffer_size 4k;

proxy_buffers 4 32k;

proxy_busy_buffers_size 64k;

proxy_temp_file_write_size 64k;

proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;

proxy_max_temp_file_size 128m;

proxy_store on;

proxy_store_access user:rw group:rw all:r;

#nginx cache

#client_body_temp_path /data/nginx_cache/client_body 1 2;

#proxy_temp_path /usr/local/nginx/proxy_temp 1 2;

更改源码隐藏软件名称及版本号

修改header信息

[root@nginx ~]# cd /server/tools/nginx-1.6.3

[root@nginx nginx-1.6.3]# vi src/http/ngx_http_header_filter_module.c +48

static char ngx_http_server_string[] = "Server: nginx" CRLF;

static char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;

修改上面两行为,然后编译安装

static char ngx_http_server_string[] = "BWS" CRLF;

static char ngx_http_server_full_string[] = "BWS" CRLF;

然后修改nginx.conf配置文件

server_tokens off;

修改403错误页信息

cd /server/tools/nginx-1.6.3

[root@nginx nginx-1.6.3]# vi src/http/ngx_http_special_response.c +29

"<hr><center>nginx</center>" CRLF

修改下面一行为

"<hr><center>BWS(www.etiantian.org)</center>" CRLF

然后重新编译安装

配置nginx gzip压缩功能

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

要压缩的内容(js,css,html),不要压缩的内容(图片,视频,FLASH)

官方文档:http://nginx.org/en/docs/http/ngx_http_gzip_module.html

gzip on; #开启压缩功能

Syntax: gzip on | off;

Default: gzip off;

Context: http, server, location, if in location

gzip_min_length 1k;

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

Syntax: gzip_min_length length;

Default: gzip_min_length 20;

Context: http, server, location

gzip_buffers 4 16k;

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

Syntax: gzip_buffers number size;

Default: gzip_buffers 32 4k|16 8k;

Context: http, server, location

gzip_http_version 1.0;

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

Syntax: gzip_http_version 1.0 | 1.1;

Default: gzip_http_version 1.1;

Context: http, server, location

gzip_comp_level 2;

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

Syntax: gzip_comp_level level;

Default: gzip_comp_level 1;

Context: http, server, location

gzip_types text/plain application/javascript test/css text/xml;

#用来指定压缩的类型,"text/html”类型.总是会被压缩。

提示:gzip_types类型不同的版本可能不同,可以查看:cat /application//nginx/conf/mime.types

Syntax: gzip_types mime-type ...;

Default: gzip_types text/html;

Context: http, server, location

gzip_vary on;

#vary header支持。该选项可以让前端的缓存服务器缓存经过GZIP压缩的页面,例如用Squid缓存经过Nginx压缩的数据。(让前端的缓存不解压缩发送给客户端)

Syntax: gzip_vary on | off;

Default: gzip_vary off;

Context: http, server, location

完整的配置如下

gzip on;

gzip_min_length 1k;

gzip_buffers 4 32k;

gzip_http_version 1.1;

gzip_comp_level 9;

gzip_types text/plain application/javascript test/css text/xml;

gzip_vary on;

需要压缩的对象

大于1K的纯文本文件html、js、css、xml、shtml。

图片视频等不要压缩。因为不但不会减小,在压缩时消耗CPU,MEM资源。

可以通过火狐的yslow插件查看是否压缩

配置nginx expires功能

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

expires功能优点

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

expire功能缺点

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

解决办法:

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

第二个 对缓存的对象改名。图片,附件一般不会被用户修改,如果用户修改了,实际上也都是更改文件名里新传了而己。网站升级对于js,css元素,一般可以改名。把js,css推送到CDN

一般不希望被缓存的内容

1)广告图片

2)网站流量统计文件

3)更新频繁的文件

语法: expires [time|epoch|max|off]

默认值: expires off

作用域: http, server, location

例如:

控制图片等过期时间为30天,当然这个时间可以设置的更长。具体视情况而定

location~ \.(gif|jpg|jpeg|png|bmp|ico)$ {

expires 30d;

}

控制匹配/resource/或者/mediatorModule/里所有的文件缓存设置到最长时间

比如

location ~ /(resource|mediatorModule)/ {

root /opt/demo;

expires max;

}

Nginx防蜘蛛爬虫处理

假定一个场景:某个网站它可能不希望被网络爬虫抓取,例如测试环境不希望被抓取,以免对用户造成误导,那么需要在该网站中申明,本站不希望被抓取。有如下方法:

方法一:修改nginx.conf,禁止网络爬虫的ua,返回403。

server {

listen 80;

server_name 127.0.0.1;

#添加如下内容即可防止爬虫

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

{

return 403;

}

方法2:网站更目录下增加Robots.txt,放在站点根目录下。

在http://tool.chinaz.com/robots/站点可以针对现在的搜索引擎按照想要的规则生成robots.txt文件。

robots.txt是搜索引擎中访问网站的时候要查看的第一个文件。robots.txt文件告诉蜘蛛程序在服务器上什么文件是可以被查看的。

当一个搜索蜘蛛访问一个站点时,它会首先检查该站点根目录下是否存在robots.txt,如果存在,搜索机器人就会按照该文件中的内容来确定访问的范围;如果该文件不存在,所有的搜索蜘蛛将能够访问网站上所有没有被口令保护的页面。百度官方建议,仅当您的网站包含不希望被搜索引擎收录的内容时,才需要使用robots.txt文件。如果您希望搜索引擎收录网站上所有内容,请勿建立robots.txt文件。

Robots协议是国际互联网界通行的道德规范,基于以下原则建立:

1、搜索技术应服务于人类,同时尊重信息提供者的意愿,并维护其隐私权;

2、网站有义务保护其使用者的个人信息和隐私不被侵犯。

当然,如果搜索引擎不遵守约定的Robots协议,那么通过在网站下增加robots.txt也是不起作用的。(在正式环境中,可以适当允许搜索引擎抓取收录)

nginx日志相关优化与安全

编写脚本实现Nginx access日志轮询

自动切割访问日志脚本

#!/bin/bash

Dataformat=`date +%F -d -1day`

Basedir="/application/nginx"

Nginxlogdir="$Basedir/logs"

Logname="access"

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

[ -f ${Logname}.log ] || exit 1

/bin/mv ${Logname}.log ${Dataformat}_${Logname}.log

$Basedir/sbin/nginx -s reload

添加定时任务实现每天定时切割

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

日志相关工具:syslog,rsyslog,Awstats,flume,logstash,scribe,kafka,storm

不记录不需要的访问日志

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

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

access_log off;

}

访问日志的权限设置

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

chown -R root.root /app/logs

chmod -R 700 /app/logs

不需要在日志目录上给nginx用户读或者写许可,这个问题很多网友都没在意,直接给nginx或apache用户。因为apache或nginx的主进程都是以root用户运行的。

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

为了保证apache的网站不遭受木马入侵上传及修改文件

安全的权限:

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

所有目录权限是默认的755

所有文件权限是默认的644

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

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

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

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

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

deny all;

}

location ~ ^/(static|js)/ {

deny all;

}

location ~ ^/(static|js)/ {

return 403;

}

location ~ ^/(static|js)/ {

allow 202.110.21.144;

allow 192.168.80.0/24;

deny all;

}

#http://nginx.org/en/docs/http/ngx_http_access_module.html

nginx错误页面及优雅显示

server

{

listen 80;

server_name www.XXX.com ;

index index.html index.htm index.php;

root /opt/www/;

location ~ .*.(php|php5)?$

{

#fastcgi_pass unix:/tmp/php-cgi.sock;

fastcgi_pass 127.0.0.1:9000;

fastcgi_index index.php;

include fcgi.conf;

}

error_page 404 = /404.html;

创建自己的404.html页面,放在站点目录下面;

error_page 500 502 503 504 = /50x.html;

location = /50x.html {

root /var/html;

}

门户网站nginx优雅显示配置案例

error_page 400 http://err.tmall.com/error1.html

error_page 403 http://err.tmall.com/error2.html

...

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

mkdir /opt/tmp

mv /tmp/* /opt/tmp

mount -t tmpfs -o size=16m tmpfs /tmp #工作中一般给2-4G

echo "mount -t tmpfs -o size=16m tmpfs /tmp" >>/etc/rc.local

vi /etc/fstab #或者在fstab文件中挂载

tmpfs /tmp tmpfs size=2048m 0 0

使用普通用户启动nginx

本优化属架构优化(同样适合其他软件),通过nginx的-c参数指定不同的配置文件,以起多个实例使用。如果使用普通用户,则不能使用80端口,

/application/nginx/sbin/nginx -h #查看帮助

企业级web服务apache mod_deflate模块

IBM、中国、linux文档库http://www.ibm.com/developerworks/cn/views/linux/libraryview.jsp

LAMP 系统性能调优,第 1 部分: 理解 LAMP 架构http://www.ibm.com/developerworks/cn/linux/l-tune-lamp-1/

LAMP 系统性能调优,第 2 部分: 优化 Apache 和 PHP http://www.ibm.com/developerworks/cn/linux/l-tune-lamp-2.html

LAMP 系统性能调优,第 3 部分: MySQL 服务器调优http://www.ibm.com/developerworks/cn/linux/l-tune-lamp-3.html

  1. mod_deflate模块介绍

官方网站:http://httpd.apache.org/docs/2.2/

apache的mod_deflate模块提供了DEFLATE输出过滤器,允许apache服务器将输出内容在发送到客户端之前根据具体的策略进行压缩,以节约网站带宽,同时提升用户访问体验。

mod_deflate模块安装方法

检查apache mod_deflate模块是否安装

/application/apache/bin/apachectl -M #查看所有模块,如果出现(dynamic),表示该模块是DSO方式编译的,如果出现(static) ,表示该模块是编译安装的,以上两种方法不能同时配置,否则会有冲突。

/application/apache/bin/apachectl -l|grep mod_deflate.c #列出编译安装的模块

ls /application/apache/modules/ #以DSO方式编译的模块查看方法

mod_deflate模块常规安装

配置编译时加入如下参数

[root@apache httpd-2.2.27]# ./configure --help|grep deflate

--enable-deflate Deflate transfer encoding support

#--enable-deflate提供对内容的压缩传输编码支持,一般html,js,css等内容的站点,使用此参数功能会大大提高传输速度,提升访问者访间体验。在生产环境中,这是apache调优的一个重要选顶之一

mod_deflate DSO安装方式

cd /server/tools/httpd-2.2.27/modules/filters/

/application/apache/bin/apxs -c -i -a mod_deflate.c

ll /application/apache/modules/

上述apxs参数选项说明

-c此选项表示需要执行编译操作.它首先会编译C源程序(.c)files为对应的目标代码文件(.o),然后连接这些目标代码和files中其余的目标代码文件(.o和.a),以生成动态共享对象dsofile。如果没有指定-o选项,则此输出文件名由files中的第一个文件名推测得到,也就是默认为modname.so。

-i此选项表示需要执行安装操作,以安装一个或多个动态共享对象到服务器的modules目录中。

-a此选项自动增加一个LoadModule行到http.conf文件中,以激活此模块

mod_deflate模块在apache中的应用

可以在主配置中配置,也可以在虚拟主机中配置

整个配置过程十分简单,只需要把下面内容完整的复制到httpd.conf或者httpd-vhosts虚拟机主机标签的结尾保存即可使所有的虚拟主机生效。

环境1:在主httpd.conf配里中配里如下

http://httpd.apache.org/docs/2.2/mod/mod_deflate.html

<IfModule mod_deflate.c>

DeflateCompressionLevel 9

AddOutputFilterByType DEFLATE text/html text/plain text/css text/xml # 压缩类型

AddOutputFilterByType DEFLATE application/javascript

AddOutputFilterByType DEFLATE application/x-httpd-php

SetOutputFilter DEFLATE

#DeflateFilterNote Input instream

#DeflateFilterNote Output outstream

#DeflateFilterNote Ratio ratio #在日志中存放压缩率标记,这个功能一般不用

#LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' deflate #日志格式

#CustomLog logs/deflate_log.log deflate #记录压缩日志

</IfModule>

测试:访问网站通过火狐浏览器的yslow插件查看,也可以通过curl -I 域名地址 查看。

mod_expires模块在apache中的应用

mod_expires模块查看、安装过程同mod_deflate模块,仅仅在编译的时候添加--enable-deflate参数,或者以DSO方式指定mod_expires.c

语法:

Description: Value of the Expires header configured by MIME type

Syntax: ExpiresByType MIME-type <code>seconds

Context: server config, virtual host, directory, .htaccess #也可以为location

Override: Indexes

Status: Extension

Module: mod_expires

整个配置十分简单,只需要把下面内容完整的复制到httpd.conf结尾保存即可使所有的虚拟主机生效。

<IfModule mod_expires.c> #此行为注释,不生效,也可以不写

ExpiresActive on

ExpiresDefault "access plus 12 month"

ExpiresByType text/html "access plus 12 months"

ExpiresByType image/gif "access plus 12 month"

ExpiresByType image/jpeg "access plus 12 month"

ExpiresByType application/x-javascript "access plus 12 month"

ExpiresByType text/css "access plus 12 month"

ExpiresByType application/x-shockwave-flash "access plus 12 month"

ExpiresByType image/jpg "access plus 12 months"

ExpiresByType image/png "access plus 12 months"

ExpiresByType video/x-flv "access plus 12 months"

</IfModule>

不记录不需要的访问日志

#不记录图片,js,css访问日志

<FilesMatch "\.(ico|gif|jpg|png|bmp|swf)">

SetEnv IMAG 1

</FilesMatch>

CustomLog logs/access_log combined env=!IMAG

RS服务器不记录负载均衡器健康检查的日志

SetEnvIfRequest_URI "^/checkstatus.html" dontlog

ErrorLog"logs/error_log"

LogLevel warn

CustomLog"logs/access_log" combined env=!dontlog

禁止资源目录解析php程序

方法一:提示下载不解析

<Directory "/var/html/bbs/attachments">

Optionss FollowSymLinks

AllowOverride None

Order allow,deny

Allow from all

php_flag engine off

</Directory>

方法二:返回403错误

<Directory /var/html/blog/attachments>

<file ~ ".php">

Order allow,deny

deny from all

</files>

</Directory>

worker/perfork模式说明及优化配置

查看当前使用的模式:默认是prefork

[root@apache ~]# /application/apache/bin/apachectl -l|egrep "worker|prefork"

[root@apache ~]# /application/apache/bin/apachectl -l|sed -n "/worker\|prefork/p"

prefork模式(进程模式,默认)

prefork使用的是多个子进程,而每个子进程只有一个线程,每个进程在某个确定的时间只能维持一个连接。一个主进程,多个子进程

工作原理:

控制进程最初建立若干个子进程,为了不在请求到来时再生成子进程,所以要根据需求不断的创建新的子进程,最大可以达到每秒32个直到满足需求为止。

安装方法:

在编译的过程中,加入参数--with-mpm=prefork如果不加也可以,因为默认的话,会采用prefork模式

优点:效率高,稳定,安全.对于线程调试困难的平台来说,调试更加容易些。

缺点:和woker模式比消耗资源多

常用配置参考:

<IfModule mpm_prefork_module>

StartServers 10

MinSpareServers 10

MaxSpareServers 15

ServerLimit 2000

MaxClients 1000

MaxRequestsPerChild 5000

</IfModule>

ps -ef|grep http|wc -l #此模式下查看apache的并发

worker模式

worker模式是apache2.x新引进来的模式,是线程与进程的结合,在worker模式下会有多个子进程,每个子进程又会有多个线程,每个线程在某个确定的时间只能维持一个连接。一个主进程,多个子进程,每个子进程又有多个线程。

工作原理:

由主控制进程生成若干个子进程,而每个子进程中又包含固定的线程数,各个线程独立处理请求,同样为了不在请求到来时再生成线程,在配里文件中设置了最小和最大的空闲线程数及所有子进程中的线程总数,如果现有子进程中的线程总数不能满足并发及负载,控制进程将派生新的子进程。

子进程和线程的区别:http://blog.csdn.net/wangkehuai/article/details/7089323

安装方法:

在编译的过程中,加入参数--with-mpm=worker

优点:内存占用比prefork模式低,适合高并发、高流HTTP服务

缺点:假如一个线程崩溃,整个进程就会连同其任何线程一起”死掉”.由于线程共享内存空间,所以一个程式在运行时必须被系统识别为”每个线程都是安全的”。服务稳定性不如prefork模式

<IfModule mpm_worker_module>

StartServers 3

MaxClients 2000

ServerLimit 25

MinSpareThreads 50

MaxSpareThreads 200

ThreadLimit 200

ThreadsPerChild 100

MaxRequestsPerChild 0

</IfModule>

worker模式下所能同时处理的请求总数是由子进程总数乘以ThreadsPerchild值决定的,应该大于等于maxclients。如果负载很大,现有的子进程数不能满足时,控制进程会派生新的子进程。

默认最大的子进程总数是16,如需加大时也需要显式声明ServerLimit 的值(最大值是20000)。

特别说明:

如果显式声明了ServerLimit,那么它乘以ThreadsPerChild的值必须大于等于MaxClients,而且MaxClients必须是ThreadsPerChild的整数倍,否则Apache将会自动调节到一个相应值(可能是个非期望值)

数学表达:

MaxClients<=总的进程数(ServerLimit)*线程数(ThreadsPerChild)

MaxClients%ThreadsPerChild=0

worker MPM也有不完善的地方,如果一个线程崩溃,整个进程就会连同其所有线程一起”死掉”。

pstree -a|grep http|wc -l #此模式下查看apache的并发

禁止目录索引及用户重载

<Directory "/var/html">

Options -Indexes FollowSymLinks #Indexs前加-,或去掉Indexs,禁止目录索引

AllowOverride None #禁止用户重载

Order allow,deny

Allow from all

/Directory

提示:禁止用户重载这会加快服务器响应速度,因为它不在为每个请求寻找每个目录访问控制文件(.htaccess)。也杜绝了开发人员变相修改配置的安全隐患。

避免使用.htaccess文件

首先是从web性能考虑。如果AllowOverride启用了支持.htaccess文件,则Apache需要在每个站点目录中查找.htaccess文件,因此,无论是否真正用到,启用.htaccess都会导致web性能的下降.另外,对每一个请求,都需要读取一次.htaccess文件。

其次是安全考虑.这样会允许开发人员或者代码管理者可以修改服务器的配置,这可能会导致某些意想不到的修改,应该避免使用.htaccess文件功能,如果要实现类似的功能,可以在主配里中配置。

关闭无用的CGI功能配置

将配置文件中下面内容及其模块中的注释都干掉

<IfModule alias_module>

ScriptAlias /cgi-bin/ "/application/apache2.2.27/cgi-bin/"

</IfModule>

<IfModule cgid_module>

</IfModule>

<Directory "/application/apache2.2.27/cgi-bin">

AllowOverride None

Options None

Order allow,deny

Allow from all

</Directory>

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

mkdir /opt/tmp

mv /tmp/* /opt/tmp

mount -t tmpfs -o size=16m tmpfs /tmp #工作中一般给2-4G

echo "mount -t tmpfs -o size=16m tmpfs /tmp" >>/etc/rc.local

vi /etc/fstab #或者在fstab文件中挂载

tmpfs /tmp tmpfs size=2048m 0 0

使用CDN做网站加速

简单地讲,通过在现有的Internet中增加一层新的网络架构,将网站的内容发布到最接近用户的cache服务器内,通过DNS负载均衡的技术,判断用户来源就近访问cache服务器取得所需的内容,杭州的用户访问近杭州服务器上的内容,北京的访问近北京服务器上的内容。这样可以有效减少数据在网络上传输的时间,提高速度。把静态内容分布到CDN减少了用户影响时间20%或更多。

CDN技术示意图:

网宿,蓝讯(chinacache),快网

Web服务资源防盗链技术实战

  1. 什么是资源盗链?

简单的说,就是某些不法的网站,通过在其自身网站程序里未经许可非法调用其他网站的资源,然后在自己的网站上显示这些调用的资源,达到了填充自身网站显示的效果,但是浪费了调用资源网站的网络流t,造成其他网站的带宽及服务压力吃紧,甚至宕机。

网站资源被盗链带来的问题

当网站图片及相关资源被盗链后,最直接的影响就是网络带宽占用加大了,带宽费用多了,网络流量也可能忽高忽低,nagios/zabbix等报警服务频繁报警。

最严里的情况就是网站的资源被非法使用,导致网站带宽成本加大以及服务器压力加大,多的导致数万元的损失以及网站的正常用户访问受到影响.

网站资源被盗链严重问题企业真实案例

某月某日,接到运维的朋友紧急求助,其公司的CDN源站,源站的流量没有变动,CDN那边的流量无故超了好几个G, 不知道怎么处理?老男孩补充,曾遇到过一张图片不到一天,跑了20多T的网络流量。

该故障的影响:由于是购买的CDN网站加速服务,虽然流量多了几个G,但是业务未受影响,但是,这么大的异常流量,持续下去可直接导致公司无故损失数万元.解决这个问题体现运维的价值。轻松应对IDC机房带宽突然暴涨问题http://oldboy.blog.51cto.com/2561410/909696

那么这样的问题如何能够及时发现呢?

第一、对IDC及CDN带宽做监控报警。

第二、作为高级运维或者运维经理,每天上班的一个重要任务,就是经常查看网站流量图,关注流量变化,关注异常流量。

第三、对访问日志做分析,对于异常流量能迅速定位,并且和公司市场推广等有比较好的默契沟通交流,以便调度带宽和服务器资源.确保网站正常的访问体验得到保证。更多企业案例,及实战解决方案见老男孩的博文http://oldboy.blog.51cto.com/2561410/909696

网站被盗链的解决方案

常见防盗链解决方案的基本原理

1.根据http referer实现防盗链

在HTTP协议中,有一个表头字段叫referer,使用URL格式来表示从哪里来的链接到当前网页的资源。通过referer可以检测目标访问的来源网页,如果是资源文件,可以跟踪到显示它的网页地址,一旦检测出来源不是本站进行阻止或返回指定的页面。

Apache,nginx,lighttpd三者都支持根据http referer实现防盗链

2.根据cookie处理

3.通过加密变换访问路径实现防盗链

lighttpd有类似的插件mod-secdownload

Apache web服务实现防盗链

Apache 防盗链的第一种实现方法,可以用 Rewrite 实现。首先要确认 Apache 的 rewrite module可用:能够控制 Apache httpd.conf 文件的,打开 httpd.conf,确保有这么一行配置:

LoadModule rewrite_module modules/mod_rewrite.so

然后在相应虚拟主机配置的地方,加入下列代码:

ServerName www.etiantian.org

#防盗链配置参数

RewriteEngine On

RewriteCond %{HTTP_REFERER} !^http://www.etiantian.org/.*$ [NC]

RewriteCond %{HTTP_REFERER} !^http://www.etiantian.org$ [NC]

RewriteCond %{HTTP_REFERER} !^http://blog.etiantian.org/.*$ [NC]

RewriteCond %{HTTP_REFERER} !^http://blog.etiantian.org$ [NC]

RewriteRule .*\.(gif|jpg|swf)$ http://www.etiantian.org/img/nolink.gif [R,NC]

说明:

1. www.etiantian.org、blog.etiantian.org表示网站的信任站点

2. .(gif|jpg|swf)表示要保护的防止被盗连的文件的扩展名

3. nolink.gif为上述扩展名的资源被盗链后的重定向页面/图片。用以输出警示信息,这张图片应该尽可能的小。

在其他的网站中,如果调用www.etiantian.org提供的图片URL,这样就会转向http://www.etiantian.org/img/nolink.gif,这个转向图片可能是版权信息的提示。

利用referer和rewrite实现Apache防盔链小结

通过判断referer变量的值,来判断图片或资源的引用是否合法,只有在根据配置符合设定需求范围内的referer,这样的网站内容,才能调用访问指定的资源内容,从而实现了资源被网站盗链的目的。需要注意的是:不是所有的用户代理(浏览器)都会设置referer变量,而且有的还可以手工修改referer,referer是可以被伪造的。上面配置,只是一种简单的防护手段。应付一般的盗链也足够了。

利用Cookie和rewrite实现Apache防盗链下载

常见的的网站防盗链都是通过Referer来判断用户来路的,不过这样的方法对于下载工具来说形同虚设,因为现在的下载工具早就能伪造Referer了。

Cookie配合Rewr1te模块很简单的可实现防盗链下载,首先在浏览页面的时候,会向客户端发送一个特别的Cookie,例如“Site=etiantian.org",盗链而来的将没有这个Cookie。

1、配置Cookie和rewrite实现Apache防盗链下载

在主配置文件httpd.conf或者在虚拟主机httpd-vhosts.conf中配置如下:

RewriteEngine On

RewriteCond %{HTTP_COOKIE} !^.*(?:Site=etiantian.org).*$

#对于Cookie里面没有特殊记录的请求进行重定向到错误页面

RewriteRule ^.*$/error.html #将非法访问重定向到错误页面

说明:这样如果一个盗链而来的请求将会因为役有特殊Cookie而被重定向到错误页面.就算实际地址暴露也不怕。至于这个cookie的内容是什么以及有效时间完全可以由管理员自己来设定,也就是说下载工具也没法伪造,从而防止了服务器资源被盗链的危险。

Nginx web服务实现防盗链实战

在默认情况下,只需要进行简单的配置,即可实现防盗链处理。请看下面的实例

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

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

if ($invalid_referer) {

rewrite ^/ http://www.etiantian.org/img/nolink.gif; #或者下面一行

#return 403;

}

}

提示:要根据自己公司实际业务,是否有外链的合作,进行设置域名允许。

NginxHttpAccessKeyModule实现防盗链介绍

如果不怕麻烦,有条件实现的话,推荐使用NginxHttpAccessKeyModule这个东西。他的运行方式是:如我的download目录下有一个file.zip的文件.对应的URI是http://www.ccvita.com/download/file.zip使用ngx_http_accesskey_module模块后http//www.ccvita.com/download/file.zip?key=09093abeac094.只有给定的key值正确了,才能够下载download目录下的file.zip。而且key值是根据用户的IP有关的,这样就可以避免被盗链了。据说NginxHttpAccessKeyModule现在连迅雷都可以防了,可以尝试一下。

在产品设计上解决盗链方案

将计就计,为网站上传的图片增加水印

图片添加版权水印。很多网站一般直接转载图片是为了快捷,但是对于有水印的图片,很多站长是不愿意进行转载的

rewrite规则:工作中301跳转,URI跳转运维做(产品,运营,市场),复杂的rewrite开发做的多。

服务器技术交流群请加微信 YJZyjz