nginx服务详解

Nginx Web服务应用 3

一、 Nginx介绍 3

1. Nginx的功能描述 3

 主进程主要完成如下工作: 4

 cache loader进程主要完成的任务包括: 4

 cache manager进程的主要任务: 5

2. 优越的特性; 5

3. Nginx的应用场合 5

Nginx使用的epoll模型与Apache使用的select模型区别 5

4. Nginx支持虚拟主机 5

二、 安装Nginx-1.6.3 5

1. 基础软件准备 5

2. 安装Nginx 5

3. nginx缓存安装 6

三、 Nginx技术深入剖析 6

1. Nginx模块的处理流程: 6

2. Nginx配置文件说明 7

四、 虚拟主机配置 9

1. 搭建基于域名的多虚拟机主机 10

2. 基于端口的多虚拟主机 11

3. 基于IP的虚拟主机 11

4. 利用include功能优化Nginx的配置文件 11

5. 虚拟主机别名配置 11

6. Nginx状态信息功能实战 11

 Nginx status介绍 11

 配置Nginx状态信息功能 11

五、 nginx日志配置 12

1. Nginx error_log配置 12

2. Nginx访问日志 12

 访问日志解释: 12

 日志格式允许包含的变量注释如下: 12

3. nginx自动切割访问日志 13

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

六、 Nginx rewrite 13

1. Rewrite介绍 13

2. rewrite语法 13

3. Nginx rewrite企业应用场景 15

4. 实现不同域名的URL跳转 15

5. 根据不同的浏览器将得到不同的结果。 15

6. 301重定向方法 15

7. rewrite案例 16

 多目录转成参数 16

 目录对换 16

 目录自动加“/” 16

 禁止htaccess 16

 禁止多个目录 16

 禁止以/data开头的文件 17

 禁止单个目录 17

 禁止单个文件 17

 给favicon.ico和robots.txt设置过期时间; 17

 设定过期时间 17

 文件反盗链并设置过期时间 17

 只充许固定ip访问网站,并加上密码 18

 将多级目录下的文件转成一个文件,增强seo效果 18

 将根目录下某个文件夹指向2级目录 18

 文件和目录不存在的时候重定向: 18

 域名跳转 18

 多域名转向 19

 三级域名跳转 19

 域名镜向 19

 某个子目录作镜向 19

 给discuz某版块单独配置域名 20

 discuz ucenter 头像 rewrite 优化 20

七、 nginx ssl加密配置 21

1. SSL证书介绍 21

2. ssl认证原理 21

 握手协议 21

 记录协议 22

 警报协议 22

3. 证书功能 22

4. nginx配置HTTPS支持 22

 生成证书 22

 配置nginx 24

 80端口重定向到443 24

 部分页面ssl 24

 实现双向ssl认证 26

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

1. 什么是资源盗链? 26

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

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

4. 网站被盗链的解决方案 26

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

5. Apache web服务实现防盗链 27

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

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

 配置Cookie和rewrite实现Apache防盗链下载 27

7. Nginx web服务实现防盗链实战 27

8. NginxHttpAccessKeyModule实现防盗链介绍 28

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

九、 企业级web Nginx服务优化 28

1. 隐藏nginx header内版本号信息 28

2. 更改默认用户及用户组 29

3. 配置nginx worker进程个数 29

4. 根据cpu核数进行nginx进程优化 30

5. 事件处理模型优化 31

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

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

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

9. 开启高效文件传输模式 34

10. 设置连接超时时间 34

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

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

13. proxy.conf配置参数 36

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

15. 配置nginx gzip压缩功能 37

 需要压缩的对象 38

16. 配置nginx expires功能 38

17. Nginx防蜘蛛爬虫处理 39

18. nginx日志相关优化与安全 40

 自动切割访问日志脚本 40

 不记录不需要的访问日志 40

 访问日志的权限设置 40

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

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

21. nginx错误页面及优雅显示 41

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

23. 使用普通用户启动nginx 42

Nginx Web服务应用

Nginx介绍

nginx(发音"engine x")是俄罗斯软件工程师Igor Sysoev开发的免费开源web服务器软件。Nginx本身是一款静态(html,js,css,jpg等)的www软件,不能解析动态的PHP,JSP,DO。如果要解析,还需要装对应的引擎。具备IMAP/POP3和SMTP服务器功能,Nginx最大的特点是对高并发的支持和高效的负载均衡,在高并发的需求场景下,是Apache服务器不错的替代品。目前,包括新浪、腾讯等知名网站都已使用Nginx作为Web应用服务器。

Nginx的功能描述

Nginx的特性

模块化设计、较好的扩展性

高可靠性:一个master启动一或多个worker,每个worker响应多个请求

低内存消耗:10000个keepalive连接在Nginx中仅消耗2.5MB内存(官方数据)

支持热部署:不停机更新配置文件、更新日志文件、更新服务器程序版本

Nginx的基本功能

静态web资源服务器,能够缓存打开的文件描述符

支持http/imap/pop3/smtp的反向代理;支持缓存、负载均衡

支持fastcgi(fpm)

模块化,非DSO机制,支持过滤器zip压缩,SSI以及图像大小调整

支持SSL

Nginx的扩展功能

基于名称和IP的虚拟主机

支持keepalive的保持机制

支持平滑升级

定制访问日志,支持使用日志缓存区提高日志存储性能

支持url rewrite

支持路径别名(root或alias指定)

支持基于IP以及用户的访问控制

支持传输速率限制,并发限制

Nginx的基本架构

一个master进程,生成一个或者多个worker进程,每个worker响应多个请求

事件驱动:epoll,kqueue,poll,select,rt signals

支持sendfile,sendfile64

支持AIO

支持mmap

Nginx模块类型

Nginx core module: nginx的核心模块

Standard HTTP modules:nginx的标准模块

Optional HTTP modules:nginx的可选模块

Mail modules :nginx的邮件模块

3rd party modules:nginx的第三方模块

Nginx进程详解

主进程主要完成如下工作:

读取并验正配置信息;

创建、绑定及关闭套接字;

启动、终止及维护worker进程的个数;

无须中止服务而重新配置工作特性;

控制非中断式程序升级,启用新的二进制程序并在需要时回滚至老版本;

重新打开日志文件,实现日志滚动;

编译嵌入式perl脚本;

worker进程主要完成的任务包括:

接收、传入并处理来自客户端的连接;

提供反向代理及过滤功能;

cache loader进程主要完成的任务包括:

检查缓存存储中的缓存对象;

使用缓存元数据建立内存数据库;

cache manager进程的主要任务:

缓存的失效及过期检验;

优越的特性;

作为Web服务器;相比较与Apache,Nginx使用更少的资源,支持更多的并发连接,体现更高的效率,这点使Nginx尤为受到虚拟主机提供商的欢迎,能够支持高达50000个并发的连接数的响应。

作为负载均衡服务器器:Nginx既可以在内部直接支持Rails和PHP,也可以支持作为HTTP代理服务器对外惊醒服务,Nginx用C语言编写,不论是系统资源开销还是CPU使用效率都比Perlbal要好的多

作为邮件代理服务器,Nginx同时也是一个非常优秀的邮件代理服务器(最早开发这个产品的目的之一也是作为邮件代理服务器),Last.fm描述了成功并且美妙的使用经验。

Nginx安装非常简单,配置文件非常简介(还能够支持perl语法),Bugs非常少的服务器:Nginx启动特别容易,并且几乎可以做到7*24不间断运行,即使运行数月也不需要重新启动。还能够在不间断服务的情况下进行软件版本平滑升级。

Nginx的应用场合

提供静态服务(图片,视频服务),html,js,css,flv,jpg等。类似Lighttpd并发:几万并发

动态服务,Nginx+Fastcgi的方式运行php,jsp。动态并发:500-1500

提供反向代理服务,或者称之为负载均衡,日PV2000W以下,都可以直接使用Nginx做代理。F5、A10、haproxy、NetScaler

缓存服务。类似squid,varnish,sts

课后作业:Nginx使用的epoll模型与Apache使用的select模型区别

Nginx支持虚拟主机

一个server标签就是虚拟主机

基于域名的虚拟主机。通过域名来区分虚拟主机

应用:外部网站

基于端口的虚拟主机。通过端口来区分虚拟主机

应用:公司内部网站,网站的后台……

基于IP的虚拟主机。几乎不用,不支持ifconfig别名,配置文件可以

安装Nginx-1.6.3

  1. 基础软件准备

安装PCRE

PCRE(Perl Compatible Regular Expressions,中文perl 兼容的正则表达式)是一个Perl库,包括 perl 兼容的正则表达式库。官网:http://www.perl.org

原因:HTTP rewrite module requires the PCRE library

rpm -aq pcre pcre-devel

yum install -y pcre-devel

安装openssl

原因:SSL module require the openssl library

yum install -y openssl-devel

安装Nginx

useradd -s /sbin/nologin -M nginx #创建用户,也可以在安装后创建

mkdir /server/tools -p

cd /server/tools

wget http://nginx.org/download/nginx-1.6.3.tar.gz

tar zxvf nginx-1.6.3.tar.gz

cd nginx-1.6.3

./configure --help #查看帮助

***********************************************

……

--without-http_rewrite_module disable ngx_http_rewrite_module

--without-http_proxy_module disable ngx_http_proxy_module

……

***********************************************

如上模块默认都是被加进去的,如果不想安装类似模块客家以上参数,本次安装参数如下

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

make && make install

cd ..

ln -s /application/nginx-1.6.3 /application/nginx

/application/nginx/sbin/nginx #启动进程,不报错则表示启动成功

ps -ef|grep nginx|egrep -v grep #查看启动进程

netstat -lntup|grep nginx #查看端口,直接过滤80有可能查处多余项

/application/nginx/sbin/nginx -V #查看编译参数

如果/application/nginx/sbin/nginx 出现如下错误:

/usr/local/nginx/sbin/nginx: error while loading shared libraries: libpcre.so.1: cannot open shared object file: No such file or directory

解决办法:

1. ln -s /usr/local/lib/libpcre.so.1 /lib64

2. echo "/usr/local/lib/">>/etc/ld.so.conf

ldconfig

nginx缓存安装

cd /server/scripts

wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz

tar zxvf ngx_cache_purge-2.3.tar.gz

wget http://nginx.org/download/nginx-1.6.3.tar.gz

tar zxvf nginx-1.6.3.tar.gz

cd nginx-1.6.3

./configure --prefix=/data/nginx-1.6.3 --user=nginx --group=nginx --with-http_ssl_module --with-http_stub_status_module --add-module=../ngx_cache_purge-2.3

make && make install

ln -s /data/nginx-1.6.3/ /data/nginx

Nginx技术深入剖析

  1. Nginx模块的处理流程:

客户端发送HTTP request到Nginx服务器 → Nginx基于location的配置选择一个合适的handler → (如果有) load-balancer选择一个后端服务器 → Handler处理请求并顺序将每一个响应buffer发送给第一个filter → 第一个filter讲输出交给第二个filter → 第二个给第三个 → 第三个给第四个 → 以此类推 → 最终响应发送给客户端。模块调用实际上是通过一系列的回调函数做到的,很多很多。名义上来说,你的函数可以在以下时候被执行:

  1. Nginx配置文件说明

Nginx配置文件主要分成四部分:main(全局设置)、server(主机设置)、upstream(上游服务器设置,主要为反向代理、负载均衡相关配置)和 location(URL匹配特定位置后的设置),每部分包含若干个指令。main部分设置的指令将影响其它所有部分的设置;server部分的指令主要用于指定虚拟主机域名、IP和端口;upstream的指令用于设置一系列的后端服务器,设置反向代理及后端服务器的负载均衡;location部分用于匹配网页位置(比如,根目录“/”,“/images”,等等)。他们之间的关系式:server继承main,location继承server;upstream既不会继承指令也不会被继承。它有自己的特殊指令,不需要在其他地方的应用。

cat /application/nginx/conf/nginx.conf

#user nobody; #运行用户

worker_processes 1; #启动进程,通常设置成和cpu的数量相等

#全局错误日志定义类型,[ debug | info | notice | warn | error | crit ]

#error_log logs/error.log;

#error_log logs/error.log notice;

#error_log logs/error.log info;

#pid logs/nginx.pid; #PID进程文件

events {

#参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; epoll模型是Linux 2.6以上版本内核中的高性能网络I/O模型,如果跑在FreeBSD上面,就用kqueue模型。

use epoll;

worker_connections 1024; ;#单个后台worker process进程的最大并发链接数

}

#设定http服务器,利用它的反向代理功能提供负载均衡支持

http {

include mime.types; #设定mime类型,类型由mime.type文件定义

default_type application/octet-stream; #默认文件类型

#定义日志格式

#log_format main '$remote_addr - $remote_user [$time_local] "$request" '

# '$status $body_bytes_sent "$http_referer" '

# '"$http_user_agent" "$http_x_forwarded_for"';

#access_log logs/access.log main; #设定日志格式

sendfile on; #开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。注意:如果图片显示不正常把这个改成off。

#tcp_nopush on; #防止网络阻塞

keepalive_timeout 65; #长连接超时时间,单位是秒

#gzip on; #开启gzip压缩输出

#虚拟主机的配置

server {

listen 80; #监听端口

server_name localhost; #域名可以有多个,用空格隔开

#charset koi8-r; #设置字符集

#access_log logs/host.access.log main; #设定本虚拟主机的访问日志

location / {

root html; #定义服务器的默认网站根目录位置,相对于安装目录

index index.html index.htm; #定义首页索引文件的名称

}

#error_page 404 /404.html;

# redirect server error pages to the static page /50x.html

#

error_page 500 502 503 504 /50x.html; # 定义错误提示页面

location = /50x.html { # 如果访问50x.html,则定位到下面目录去找

root html; #如果没有这个目录,则定位到默认目录“/”

}

# proxy the PHP scripts to Apache listening on 127.0.0.1:80

#

#location ~ \.php$ { #对 "~ \.php$" 启用反向代理

# proxy_pass http://127.0.0.1;

#}

# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000

#

#location ~ \.php$ { #所有php后缀的,都通过fastcgi发送到9000端口上

# root html;

# fastcgi_pass 127.0.0.1:9000;

# fastcgi_index index.php;

# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;

# include fastcgi_params;

#}

# deny access to .htaccess files, if Apache's document root

# concurs with nginx's one

#

#location ~ /\.ht {

# deny all;

#}

}

# another virtual host using mix of IP-, name-, and port-based configuration

#

#server {

# listen 8000;

# listen somename:8080;

# server_name somename alias another.alias;

# location / {

# root html;

# index index.html index.htm;

# }

#}

# HTTPS server

#

#server {

# listen 443 ssl;

# server_name localhost;

# ssl_certificate cert.pem;

# ssl_certificate_key cert.key;

# ssl_session_cache shared:SSL:1m;

# ssl_session_timeout 5m;

# ssl_ciphers HIGH:!aNULL:!MD5;

# ssl_prefer_server_ciphers on;

# location / {

# root html;

# index index.html index.htm;

# }

#}

}

虚拟主机配置

egrep -v "#|^$" nginx.conf.default >nginx.conf #过滤#及空行

  1. 搭建基于域名的多虚拟机主机

worker_processes 1;

error_log logs/error.log error;

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"';

#nginx vhosts config

include extra/www.conf;

include extra/bbs.conf;

include extra/blog.conf;

}

创建配置文件目录及配置文件

cd /application/nginx/conf/

mkdir extra

touch extra/{www,bbs,blog}.conf

[root@nginx conf]# vi extra/www.conf

server {

listen 80;

server_name www.etiantian.org;

location / {

root /var/html/www;

index index.html index.htm;

}

error_page 500 502 503 504 /50x.html;

location = /50x.html {

root html;

}

access_log logs/www_access.log main;

}

创建站点目录

mkdir /var/html/{www,bbs,blog} -p

touch /var/html/{www,bbs,blog}/index.html

for name in www bbs blog; do echo "$name " >/var/html/$name/index.html;done

重启web服务

/application/nginx/sbin/nginx -t

/application/nginx/sbin/nginx -s reload

echo " 192.168.80.104 www.etiantian.org bbs.etiantian.org blog.etiantian.org etiantian.org">>/etc/hosts

如果配置基于域名的多虚拟机主机,使用IP地址访问默认访问第一个server

基于端口的多虚拟主机

在基于域名的多虚拟机主机的基础上,修改两个server使用同一个域名,不同的端口,重启,使用不同的端口访问。

基于IP的虚拟主机

man ip #查找帮助

********************************************

……

ip addr { add | del } IFADDR dev STRING

……

ip addr add 192.168.80.99/24 dev eth0 #在一个网卡上增加另一个IP地址

仅仅修改一个server中的 listen 192.168.80.99:80;

另一个server中为listen 192.168.80.100:80;即可

利用include功能优化Nginx的配置文件

将配置文件中的server模块置于另外一个文件extra/vhost.conf中,然后在nginx.conf文件中加入include extra/vhost.conf;重启即可。也可以添加多个.conf文件,使用include分别包括,也可以直接加入include extra/*.conf;以包含所有.conf文件。

例如: include extra/www.conf;

虚拟主机别名配置

在server_name后直接加别名,可以有多个,使用空格隔开,并且在hosts文件中对别名解析。可以利用此功能监控集群节点下的主机

Nginx状态信息功能实战

Nginx status介绍

Nginx软件功能模块中有一个ngx_http_stub_status_module模块,这个模块的功能是记录Nginx的基本访问状态信息,让读者了解Nginx的工作状态,例如:网站的负载情况。要想使用状态模块,在编译时必须增加http_stub_status_module模块。可通过如下方式查看安装时编译的参数:./nginx/sbin/nginx -V

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状态信息功能

配置文件中添加如下server

server {

listen 80;

server_name status.etiantian.com;

location / {

stub_status on;

access_log off;

}

}

重启服务并在hosts文件中添加主机记录,在浏览器中访问:status.etiantian.com,显示如下:

Active connections: 1 #正在处理的活动链接数

server accepts handled requests

2 2 13

Reading: 0 Writing: 1 Waiting: 0

解析:Active connections //当前 Nginx 正处理的活动连接数。

server accepts handledrequests //总共处理了2个连接 , 成功创建 2 次握手,总共处理了13个请求。

Reading //nginx读取到客户端的 Header 信息数。

Writing //nginx返回给客户端的 Header 信息数。

Waiting //开启 keep-alive 的情况下,这个值等于 active – (reading + writing),意思就是 Nginx 已经处理完正在等候下一次请求指令的驻留连接

nginx日志配置

  1. Nginx error_log配置

nginx的error_log类型如下(从左到右:debug最详细 crit最少):

[ debug | info | notice | warn | error | crit ]

注意:当访问量较大时,不要使用debug,消耗磁盘IO

例如:error_log logs/nginx_error.log crit;

解释:日志文件存储在nginx安装目录下的 logs/nginx_error.log ,错误类型为 crit ,也就是记录最少错误信息;

默认值: error_log logs/error.log error;

配置段: main, http, server, location

参考资料:http://nginx.org/en/docs/ngx_core_module.html#error_log

Nginx访问日志

语法: access_log path [format [buffer=size [flush=time]]];

access_log path format gzip[=level] [buffer=size] [flush=time];

access_log syslog:server=address[,parameter=value] [format];

access_log off;

例如:access_log logs/access.log combined gzip buffer=32k flush=5

默认值: access_log logs/access.log combined;

配置段: http, server, location, if in location, limit_except

访问日志解释:

gzip压缩等级。

buffer设置内存缓存区大小。

flush保存在缓存区中的最长时间。

不记录日志:access_log off;

使用默认combined格式记录日志:access_log logs/access.log 或 access_log logs/access.log combined;

日志格式允许包含的变量注释如下:

$remote_addr, $http_x_forwarded_for 记录客户端IP地址

$remote_user 记录客户端用户名称

$request 记录请求的URL和HTTP协议

$status 记录请求状态

$body_bytes_sent 发送给客户端的字节数,不包括响应头的大小; 该变量与Apache模块mod_log_config里的“%B”参数兼容。

$bytes_sent 发送给客户端的总字节数。

$connection 连接的序列号。

$connection_requests 当前通过一个连接获得的请求数量。

$msec 日志写入时间。单位为秒,精度是毫秒。

$pipe 如果请求是通过HTTP流水线(pipelined)发送,pipe值为“p”,否则为“.”。

$http_referer 记录从哪个页面链接访问过来的

$http_user_agent 记录客户端浏览器相关信息

$request_length 请求的长度(包括请求行,请求头和请求正文)。

$request_time 请求处理时间,单位为秒,精度毫秒; 从读入客户端的第一个字节开始,直到把最后一个字符发送给客户端后进行日志写入为止。

$time_iso8601 ISO8601标准格式下的本地时间。

$time_local 通用日志格式下的本地时间。

官方文档:http://nginx.org/en/docs/http/ngx_http_log_module.html#access_log

nginx自动切割访问日志

自动切割访问日志脚本

#!/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

也可以在脚本中添加多个mv命令对每个虚拟主机进行切割

运维人员必须熟悉的运维工具汇总: http://oldboy.blog.51cto.com/2561410/775056

Nginx rewrite

  1. Rewrite介绍

Rewrite 主要的功能就是实现URL的重写,Nginx的Rewrite规则采用Pcre,perl兼容正则表达式的语法规则匹配,如果需要Nginx的Rewrite功能,在编译Nginx之前,需要编译安装PCRE库。直接用Apache的规则到Nginx下没起作用。原来Apache 重写的规则到nginx上还有一些不太一样的地方。nginx里使用伪静态是直接在nginx.conf 中写规则的,并不需要像apache要开启写模块(mod_rewrite)才能进行伪静态。

rewrite语法

rewrite指令语法:rewrite regex replacement [flag]

默认: none

作用域: server, location, if

变量名:

变量名可以使用"="或"!="运算符

~ 符号表示区分大小写字母匹配

~* 符号表示不区分大小写字母匹配

!~ 和 !~ 与~ !~ 相反

-f 和 !-f 用来判断文件是否存在

-d 和 !-d 用来判断目录是否存在

-e 和 !-e 用来判断文件或目录是否存在

-x 和 !-x 用来判断文件是否可以执行

也支持$1到$9位置参数

例如

server {

listen 80;

server_name etiantian.com;

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

}

上述rewrite指令说明

rewrite为固定关键字,表示开启一条rewrite匹配规则,regex部分是^/(.*),这是一个正则表达式,匹配所有,匹配成功后跳转到http://www.etiantian.com/$1,这里的$1是取前面regex部分()里的内容,结尾permanent表示永久301重定向标记

perl兼容的正则表达式和linux正则表达式有区别,但基本相同

flag标记有:

last 相当于Apache里的[L]标记,表示完成rewrite

break 终止匹配, 不再匹配后面的规则

redirect 返回302临时重定向 地址栏会显示跳转后的地址

permanent 返回301永久重定向 地址栏会显示跳转后的地址

一些可用的全局变量有,可以用做条件判断(待补全)

$args : #这个变量等于请求行中的参数,同$query_string

$content_length : 请求头中的Content-length字段。

$content_type : 请求头中的Content-Type字段。

$document_root : 当前请求在root指令中指定的值。

$host : 请求主机头字段,否则为服务器名称。

$http_user_agent : 客户端agent信息

$http_cookie : 客户端cookie信息

$limit_rate : 这个变量可以限制连接速率。

$request_method : 客户端请求的动作,通常为GET或POST。

$remote_addr : 客户端的IP地址。

$remote_port : 客户端的端口。

$remote_user : 已经经过Auth Basic Module验证的用户名。

$request_filename : 当前请求的文件路径,由root或alias指令与URI请求生成。

$scheme : HTTP方法(如http,https)。

$server_protocol : 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。

$server_addr : 服务器地址,在完成一次系统调用后可以确定这个值。

$server_name : 服务器名称。

$server_port : 请求到达服务器的端口号。

$request_uri : 包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。

$uri : 不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。

$document_uri : 与$uri相同。

例:http://localhost:88/test1/test2/test.php

$host:localhost

$server_port:88

$request_uri:http://localhost:88/test1/test2/test.php

$document_uri:/test1/test2/test.php

$document_root:/var/www/html

$request_filename:/var/www/html/test1/test2/test.php

Nginx rewrite企业应用场景

Nginx的rewrite功能在企业里的应用非常广泛

可以调整用户浏览的URL,看起来更规范,合乎开发人员的需求

为了让搜索引擎收录网站内容及用户体验更好,企业会将动态URL地址伪装成静态地址提供服务

网站更换新域名后,让旧的域名的访问跳转到新的域名商上,例如:京东的360buy换成了jd.com.

根据特殊变量,目录,客户端的信息进行URL跳转等

实现不同域名的URL跳转

例1:实现访问http://blog.etiantian.org跳转到http://www.etiantian.org/blog/oldboy.html外部跳转时使用这种方法,浏览器地址会变为跳转后的地址,另外要事先设置http://www.etiantian.org/blog/oldboy.html有输出结果,不然会出现401等权限错误

配置Nginx rewrite规则

server {

listen 80;

server_name blog.etiantian.org;

location / {

root html/blog;

index index.html index.htm;

}

rewrite ^(.*) http://www.etiantian.org/blog/oldboy.html break;

access_log logs/access_blog.log main;

}

根据不同的浏览器将得到不同的结果。

if ($http_user_agent ~ Firefox) {

rewrite ^(.*)$ /firefox/$1 break;

}

 

if ($http_user_agent ~ MSIE) {

rewrite ^(.*)$ /msie/$1 break;

}

 

if ($http_user_agent ~ Chrome) {

rewrite ^(.*)$ /chrome/$1 break;

}

301重定向方法

进行了301重定向,把www .jefflei.com和jefflei.com合并,并把之前的域名也一并合并. 有两种实现方法,第一种方法是判断nginx核心变量host(老版本是http_host):

server {

server_name www.jefflei.com jefflei.com ;

if ($host != 'www.jefflei.com' ) {

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

}

...

}

第二种方法:

server {

server_name jefflei.com;

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

}

last – 基本上都用这个Flag。

break – 中止Rewirte,不在继续匹配

redirect – 返回临时重定向的HTTP状态302

permanent – 返回永久重定向的HTTP状态301

rewrite案例

多目录转成参数

abc.domian.com/sort/2 => abc.domian.com/index.php?act=sort&name=abc&id=2

if ($host ~* (.*)\.domain\.com) {

set $sub_name $1;

rewrite ^/sort\/(\d+)\/?$ /index.php?act=sort&cid=$sub_name&id=$1 last;

}

目录对换

/123456/xxxx -> /xxxx?id=123456

rewrite ^/(\d+)/(.+)/ /$2?id=$1 last;

例如下面设定nginx在用户使用ie的使用重定向到/nginx-ie目录下:

if ($http_user_agent ~ MSIE) {

rewrite ^(.*)$ /nginx-ie/$1 break;

}

目录自动加“/”

if (-d $request_filename){

rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent;

}

禁止htaccess

location ~/\.ht {

deny all;

}

禁止多个目录

location ~ ^/(cron|templates)/ {

deny all;

break;

}

禁止以/data开头的文件

可以禁止/data/下多级目录下.log.txt等请求;

location ~ ^/data {

deny all;

}

禁止单个目录

不能禁止.log.txt能请求

location /searchword/cron/ {

deny all;

}

禁止单个文件

location ~ /data/sql/data.sql {

deny all;

}

给favicon.ico和robots.txt设置过期时间;

这里为favicon.ico为99 天,robots.txt为7天并不记录404错误日志

location ~(favicon.ico) {

log_not_found off;

expires 99d;

break;

}

location ~(robots.txt) {

log_not_found off;

expires 7d;

break;

}

设定过期时间

设定某个文件的过期时间,这里为600秒,并不记录访问日志

location ^~ /html/scripts/loadhead_1.js {

access_log off;

root /opt/lampp/htdocs/web;

expires 600;

break;

}

文件反盗链并设置过期时间

这里的return 412 为自定义的http状态码,默认为403,方便找出正确的盗链的请求

“rewrite ^/ http://leech.c1gstudio.com/leech.gif;”显示一张防盗链图片

“access_log off;”不记录访问日志,减轻压力

“expires 3d”所有文件3天的浏览器缓存

location ~* ^.+\.(jpg|jpeg|gif|png|swf|rar|zip|css|js)$ {

valid_referers none blocked *.c1gstudio.com *.c1gstudio.net localhost 208.97.167.194;

if ($invalid_referer) {

rewrite ^/ http://leech.c1gstudio.com/leech.gif;

return 412;

break;

}

access_log off;

root /opt/lampp/htdocs/web;

expires 3d;

break;

}

只充许固定ip访问网站,并加上密码

root /opt/htdocs/www;

allow 208.97.167.194;

allow 222.33.1.2;

allow 231.152.49.4;

deny all;

auth_basic "C1G_ADMIN";

auth_basic_user_file htpasswd;

将多级目录下的文件转成一个文件,增强seo效果

/job-123-456-789.html 指向/job/123/456/789.html

rewrite ^/job-([0-9]+)-([0-9]+)-([0-9]+)\.html$ /job/$1/$2/jobshow_$3.html last;

将根目录下某个文件夹指向2级目录

如/shanghaijob/ 指向 /area/shanghai/

如果你将last改成permanent,那么浏览器地址栏显是 /location/shanghai/

rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2 last;

上面例子有个问题是访问/shanghai 时将不会匹配

rewrite ^/([0-9a-z]+)job$ /area/$1/ last;

rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2 last;

这样/shanghai 也可以访问了,但页面中的相对链接无法使用,

如./list_1.html真实地址是/area /shanghia/list_1.html会变成/list_1.html,导至无法访问。

那我加上自动跳转也是不行咯

(-d $request_filename)它有个条件是必需为真实目录,而我的rewrite不是的,所以没有效果

if (-d $request_filename){

rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent;

}

知道原因后就好办了,让我手动跳转吧

rewrite ^/([0-9a-z]+)job$ /$1job/ permanent;

rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2 last;

文件和目录不存在的时候重定向:

if (!-e $request_filename) {

proxy_pass http://127.0.0.1/;

}

域名跳转

server

{

listen 80;

server_name jump.c1gstudio.com;

index index.html index.htm index.php;

root /opt/lampp/htdocs/www;

rewrite ^/ http://www.c1gstudio.com/;

access_log off;

}

多域名转向

server_name http://www.c1gstudio.com/ http://www.c1gstudio.net/;

index index.html index.htm index.php;

root /opt/lampp/htdocs;

if ($host ~ "c1gstudio\.net") {

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

}

三级域名跳转

if ($http_host ~* "^(.*)\.i\.c1gstudio\.com$") {

rewrite ^(.*) http://top.yingjiesheng.com$1/;

break;

}

域名镜向

server

{

listen 80;

server_name mirror.c1gstudio.com;

index index.html index.htm index.php;

root /opt/lampp/htdocs/www;

rewrite ^/(.*) http://www.c1gstudio.com/$1 last;

access_log off;

}

某个子目录作镜向

location ^~ /zhaopinhui {

rewrite ^.+ http://zph.c1gstudio.com/ last;

break;

}

discuz ucenter home (uchome) rewrite

rewrite ^/(space|network)-(.+)\.html$ /$1.php?rewrite=$2 last;

rewrite ^/(space|network)\.html$ /$1.php last;

rewrite ^/([0-9]+)$ /space.php?uid=$1 last;

discuz 7 rewrite

rewrite ^(.*)/archiver/((fid|tid)-[\w\-]+\.html)$ $1/archiver/index.php?$2 last;

rewrite ^(.*)/forum-([0-9]+)-([0-9]+)\.html$ $1/forumdisplay.php?fid=$2&page=$3 last;

rewrite ^(.*)/thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ $1/viewthread.php?tid=$2&extra=page\%3D$4&page=$3 last;

rewrite ^(.*)/profile-(username|uid)-(.+)\.html$ $1/viewpro.php?$2=$3 last;

rewrite ^(.*)/space-(username|uid)-(.+)\.html$ $1/space.php?$2=$3 last;

rewrite ^(.*)/tag-(.+)\.html$ $1/tag.php?name=$2 last;

给discuz某版块单独配置域名

server_name bbs.c1gstudio.com news.c1gstudio.com;

location = / {

if ($http_host ~ news\.c1gstudio.com$) {

rewrite ^.+ http://news.c1gstudio.com/forum-831-1.html last;

break;

}

}

discuz ucenter 头像 rewrite 优化

location ^~ /ucenter {

location ~ .*\.php?$

{

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

fastcgi_pass 127.0.0.1:9000;

fastcgi_index index.php;

include fcgi.conf;

}

location /ucenter/data/avatar {

log_not_found off;

access_log off;

location ~ /(.*)_big\.jpg$ {

error_page 404 /ucenter/images/noavatar_big.gif;

}

location ~ /(.*)_middle\.jpg$ {

error_page 404 /ucenter/images/noavatar_middle.gif;

}

location ~ /(.*)_small\.jpg$ {

error_page 404 /ucenter/images/noavatar_small.gif;

}

expires 300;

break;

}

}

jspace rewrite

location ~ .*\.php?$

{

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

fastcgi_pass 127.0.0.1:9000;

fastcgi_index index.php;

include fcgi.conf;

}

location ~* ^/index.php/

{

rewrite ^/index.php/(.*) /index.php?$1 break;

fastcgi_pass 127.0.0.1:9000;

fastcgi_index index.php;

include fcgi.conf;

}

nginx ssl加密配置

  1. SSL证书介绍

SSL 证书就是遵守 SSL协议,由受信任的数字证书颁发机构CA,在验证服务器身份后颁发,具有服务器身份验证和数据传输加密功能。

SSL证书通过在客户端浏览器和Web服务器之间建立一条SSL安全通道(Secure socket layer(SSL)安全协议是由Netscape Communication公司设计开发。该安全协议主要用来提供对用户和服务器的认证;对传送的数据进行加密和隐藏;确保数据在传送中不被改变,即数据的完整性,现已成为该领域中全球化的标准。由于SSL技术已建立到所有主要的浏览器和WEB服务器程序中,因此,仅需安装服务器证书就可以激活该功能了),即通过它可以激活SSL协议,实现数据信息在客户端和服务器之间的加密传输,可以防止数据信息的泄露。保证了双方传递信息的安全性,而且用户可以通过服务器证书验证他所访问的网站是否是真实可靠。数位签名又名数字标识、签章 (即 Digital Certificate,Digital ID ),提供了一种在网上进行身份验证的方法,是用来标志和证明网路通信双方身份的数字信息文件,概念类似日常生活中的司机驾照或身份证相似。 数字签名主要用于发送安全电子邮件、访问安全站点、网上招标与投标、网上签约、网上订购、安全网上公文传送、网上办公、网上缴费、网上缴税以及网上购物等安全的网上电子交易活动。

ssl认证原理

安全套接字层(SSL) 技术通过加密信息和提供鉴权,保护您的网站安全。一份 SSL 证书包括一个公共密钥和一个私用密钥。公共密钥用于加密信息,私用密钥用于解译加密的信息。浏览器指向一个安全域时,SSL 同步确认服务器和客户端,并创建一种加密方式和一个唯一的会话密钥。它们可以启动一个保证消息的隐私性和完整性的安全会话。

SSL的工作原理中包含如下三个协议。

握手协议(Handshake protocol)

记录协议(Record protocol)

警报协议(Alert protocol)

握手协议

握手协议是客户机和服务器用SSL连接通信时使用的第一个子协议,握手协议包括客户机与服务器之间的一系列消息。SSL中最复杂的协议就是握手协议。该协议允许服务器和客户机相互验证,协商加密和MAC算法以及保密密钥,用来保护在SSL记录中发送的数据。握手协议是在应用程序的数据传输之前使用的。

记录协议

记录协议在客户机和服务器握手成功后使用,即客户机和服务器鉴别对方和确定安全信息交换使用的算法后,进入SSL记录协议,记录协议向SSL连接提供两个服务:

(1)保密性:使用握手协议定义的秘密密钥实现

(2)完整性:握手协议定义了MAC,用于保证消息完整性

警报协议

客户机和服务器发现错误时,向对方发送一个警报消息。如果是致命错误,则算法立即关闭SSL连接,双方还会先删除相关的会话号,秘密和密钥。每个警报消息共2个字节,第1个字节表示错误类型,如果是警报,则值为1,如果是致命错误,则值为2;第2个字节制定实际错误类型。

证书功能

服务器部署了 SSL 证书后可以确保用户在浏览器上输入的机密信息和从服务器上查询的机密信息从用户电脑到服务器之间的传输链路上是高强度加密传输的,是不可能被非法篡改和窃取的。同时向网站访问者证明了服务器的真实身份,此真实身份是通过第三方权威机构验证的。也就是说有两大作用:数据加密和身份认证。

a 确认网站真实性(网站身份认证):用户需要登录正确的网站进行在线购物或其它交易活动,但由于互联网的广泛性和开放性,使得互联网上存在着许多假冒、钓鱼网站,用户如何来判断网站的真实性,如何信任自己正在访问的网站,可信网站将帮你确认网站的身份。当用户需要确认网站身份的时候,只需要点击浏览器地址栏里面的锁头标志即可。

b 保证信息传输的机密性:用户在登录网站在线购物或进行各种交易时,需要多次向服务器端传送信息,而这些信息很多是用户的隐私和机密信息,直接涉及经济利益或私密,如何来确保这些信息的安全呢?可信网站将帮您建立一条安全的信息传输加密通道。

在SSL会话产生时,服务器会传送它的证书,用户端浏览器会自动的分析服务器证书,并根据不同版本的浏览器,从而产生40位或128位的会话密钥,用于对交易的信息进行加密。所有的过程都会自动完成,对用户是透明的,因而,服务器证书可分为两种:最低40位和最低128位(这里指的是SSL会话时生成加密密钥的长度,密钥越长越不容易破解)证书。

最低40位的服务器证书在建立会话时,根据浏览器版本不同,可产生40位或128位的SSL会话密钥用来建立用户浏览器与服务器之间的安全通道。而最低128位的服务器证书不受浏览器版本的限制可以产生128位以上的会话密钥,实现高级别的加密强度,无论是IE或Netscape浏览器,即使使用强行攻击的办法破译密码,也需要10年。

nginx配置HTTPS支持

默认情况下ssl模块并未被安装,如果要使用该模块则需要在编译时指定--with-http_ssl_module参数,安装模块依赖于OpenSSL库和一些引用文件,通常这些文件并不在同一个软件包中。通常这个文件名类似libssl-dev。

生成证书

[root@nginx ~]# cd /application/nginx/conf/

[root@nginx conf]# openssl genrsa -des3 -out server.key 1024 #创建服务器私钥,命令会让你输入一个口令

Generating RSA private key, 1024 bit long modulus

......++++++

...................++++++

e is 65537 (0x10001)

Enter pass phrase for server.key:

Verifying - Enter pass phrase for server.key:

[root@nginx conf]# openssl req -new -key server.key -out server.csr #创建签名请求的证书(CSR)

Enter pass phrase for server.key:

You are about to be asked to enter information that will be incorporated

into your certificate request.

What you are about to enter is what is called a Distinguished Name or a DN.

There are quite a few fields but you can leave some blank

For some fields there will be a default value,

If you enter '.', the field will be left blank.

-----

Country Name (2 letter code) [XX]:china

string is too long, it needs to be less than 2 bytes long

Country Name (2 letter code) [XX]:CN

State or Province Name (full name) []:beijing

Locality Name (eg, city) [Default City]:beijing

Organization Name (eg, company) [Default Company Ltd]:ekwing

Organizational Unit Name (eg, section) []:sre

Common Name (eg, your name or your server's hostname) []:liwenbin

Email Address []:1935845114@qq.com

Please enter the following 'extra' attributes

to be sent with your certificate request

A challenge password []:123456

An optional company name []:

[root@nginx conf]# cp server.key server.key.org

[root@nginx conf]# openssl rsa -in server.key.org -out server.key

#在加载SSL支持的Nginx并使用上述私钥时除去必须的口令:提示:在生成证书请求csr文件时,如果输入了密码,nginx每次启动时都会提示输入这个密码,可以使用私钥来生成解密后的key来代替,效果是一样的,达到免密码重启的效果:

Enter pass phrase for server.key.org:

writing RSA key

[root@nginx conf]# openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt #最后标记证书使用上述私钥和CSR

Signature ok

subject=/C=CN/ST=beijing/L=beijing/O=ekwing/OU=sre/CN=liwenbin/emailAddress=193545114@qq.com

Getting Private key

快速创建过程

cd /application/nginx/conf/

openssl genrsa -des3 -out server.key 1024

openssl req -new -key server.key -out server.csr

cp server.key server.key.org

openssl rsa -in server.key.org -out server.key

openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

配置nginx

server {

listen 443;

server_name www.etiantian.org;

ssl on;

ssl_certificate /application/nginx/conf/server.crt;

ssl_certificate_key /application/nginx/conf/server.key;

# ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;

# ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;

# ssl_prefer_server_ciphers on;

location / {

root /var/html/www;

index index.html index.htm;

}

access_log logs/www_access.log main;

}

ssl_certificate证书其实是个公钥,它会被发送到连接服务器的每个客户端

ssl_certificate_key私钥是用来解密的,所以它的权限要得到保护但nginx的主进程能够读取。当然私钥和证书可以放在一个证书文件中,两个键指定相同的文件,这种方式也只有公钥证书才发送到client。

ssl_protocols 指令用于启动特定的加密协议,nginx在1.1.13和1.0.12版本后默认是ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2,TLSv1.1与TLSv1.2要确保OpenSSL >= 1.0.1 ,SSLv3 现在还有很多地方在用但有不少被攻击的漏洞。

ssl_ciphers选择加密套件,不同的浏览器所支持的套件(和顺序)可能会不同。这里指定的是OpenSSL库能够识别的写法,你可以通过 openssl -v cipher 'RC4:HIGH:!aNULL:!MD5'(后面是你所指定的套件加密算法) 来看所支持算法。

ssl_prefer_server_ciphers on设置协商加密算法时,优先使用我们服务端的加密套件,而不是客户端浏览器的加密套件

重启nginx。

https://www.etiantian.org/通过如下访问

80端口重定向到443

server {

listen 80;

server_name www.etiantian.org;

rewrite ^(.*) https://$server_name$1 permanent;

}

部分页面ssl

一个站点并不是所有信息都是非常机密的,如网上商城,一般的商品浏览可以不通过https,而用户登录以及支付的时候就强制经过https传输,这样用户访问速度和安全性都得到兼顾。

但是请注意不要理解错了,是对页面加密而不能针对某个请求加密,一个页面或地址栏的URL一般会发起许多请求的,包括css/png/js等静态文件和动态的java或php请求,所以要加密的内容包含页面内的其它资源文件,否则就会出现http与https内容混合的问题。在http页面混有https内容时,页面排版不会发生乱排现象;在https页面中包含以http方式引入的图片、js等资源时,浏览器为了安全起见会阻止加载。

下面是只对example.com/account/login登录页面进行加密的例子:

root /apps/www;

index index.html index.htm;

server {

listen 80;

server_name example.com;

location ^~ /account/login {

rewrite ^ https://$server_name:443$request_uri? permanent;

}

location / {

proxy_pass http://localhost:8080;

### Set headers ####

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_redirect off;

}

}

server {

listen 443 ssl;

server_name example.com;

ssl on;

ssl_certificate ../SSL/ittest.pem;

ssl_certificate_key ../SSL/ittest.key;

ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;

ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;

ssl_prefer_server_ciphers on;

location ^~ /account/login {

proxy_pass http://localhost:8080;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_redirect off;

### Most PHP, Python, Rails, Java App can use this header -> https ###

proxy_set_header X-Forwarded-Proto $scheme;

}

location / {

rewrite ^ http://$server_name$request_uri? permanent;

}

}

实现双向ssl认证

上面的两种配置都是去认证被访问的站点域名是否真实可信,并对传输过程加密,但服务器端并没有认证客户端是否可信。(实际上除非特别重要的场景,也没必要去认证访问者,除非像银行U盾这样的情况)

要实现双向认证HTTPS,nginx服务器上必须导入CA证书(根证书/中间级证书),因为现在是由服务器端通过CA去验证客户端的信息。还有必须在申请服务器证书的同时,用同样的方法生成客户证书。取得客户证书后,还要将它转换成浏览器识别的格式(大部分浏览器都认识PKCS12格式):

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

  1. 什么是资源盗链?

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

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

当网站图片及相关资源被盗链后,最直接的影响就是网络带宽占用加大了,带宽费用多了,网络流量也可能忽高忽低,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。

配置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开发做的多。

企业级web Nginx服务优化

  1. 隐藏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;

}

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、html。

图片视频等不要压缩。因为不但不会减小,在压缩时消耗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 #查看帮助

 

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