nginx(二):进阶配置介绍--rewrite用法,压缩,https虚拟主机等

1、nginx基本状态信息页面

配置示例:

location  /basic_status {
                            stub_status;
                        }

页面展示含义:

Active connections: 291 
server accepts handled requests
    16630948 16630948 31070465 
Reading: 6 Writing: 179 Waiting: 106     

Active connections: 活动状态的连接数;
accepts:已经接受的客户端请求的总数;
handled:已经处理完成的客户端请求的总数;
requests:客户端发来的总的请求数;
Reading:处于读取客户端请求报文首部的连接的连接数;
Writing:处于向客户端发送响应报文过程中的连接数;
Waiting:处于等待客户端发出请求的空闲连接数;

2、记录请求日志

指令:

  1. log_format
    作用域: http
  2. access_log
    作用域: http, server, location, if in location, limit_except
  3. open_log_file_cache
    作用域: http, server, location

2.1 log_format

在http区域定制日志格式
用法:log_format name string …;
name指定一个格式名称,string可以使用nginx核心模块及其它模块内嵌的变量指定格式。

2.2 access_log

可在每个server中,或location中指定一个日志存放路径
用法:

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

指定日志存放路径path,格式format,缓冲区大小buffer,也可启用压缩日志,指定压缩级别gzip

2.3 open_log_file_cache

定义一个缓存保存活跃的日志文件描述符数据
用法:

open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];
open_log_file_cache off;

max:缓存的最大文件描述符数量;
min_users:在inactive指定的时长内访问大于等于此值方可被当作活动项;
inactive:非活动时长;
valid:验证缓存中各缓存项是否为活动项的时间间隔;
配置示例:

log_format combined '$remote_addr - $remote_user [$time_local] '
                       '"$request" $status $bytes_sent '
                       '"$http_referer" "$http_user_agent" "$gzip_ratio"';

access_log /var/logs/nginx-access.log combined buffer=32k;
open_log_file_cache max=1000 inactive=20s valid=1m min_uses=2;

3、rewrite重写

将用户请求的URI基于regex所描述的模式进行检查,而后完成替换;
URL重写是一个非常有用的功能,如果一个网站在改进的过程中结构发生变化,无需客户端更改已保存访问地址仍可正常访问;提升网站安全性,如放盗链行为。

3.1 rewrite

syntax: rewrite regex replacement [flag]
Context:    server, location, if

将用户请求的URI基于regex所描述的模式匹配检查,匹配到时将其替换成replacement指定的新URI;
rewrite指令在同一级配置块中存在多条rewrite规则,会按照顺序自上而下逐一执行;被某一规则替换完成后,重新开始新一轮检查,因此本身具有循环机制,flag所表示的标志位可控制循环机制;如果replacement是以http://或其他协议开头的字符串,则直接以重定向方式返回给客户端;
另外,rewrite指令接收到的URI是不包含host地址的,例如http://cutemsyu.com/articles/…,不包含”cutemsyu.com” ,在写regex规则时应当注意。

[flag] 可用标识如下:

  • last:停止在当前区域继续处理,将重写的新URI在各location中重新处理;
  • break:将此处重写的URI在本块中继续处理,但新的URI不会转向其他location中处理;
  • redirect:将重写的URI直接返回给客户端,状态代码为302,表示临时重定向。用在replacement不以”http://”或”https://”开头的情况下;
  • permanent:将重写的URI直接返回给客户端,状态码为301,指明为永久重定向。

Example:

#flag 是last的一个例子
server {
    ...
    rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
    rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra  last;
    return  403;
    ...
}

#如果上面的rewrite规则写在location中,则应该使用break标识,防止死循环,如果循环超过10此,返回500错误码
location /download/ {
    rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
    rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra  break;
    return  403;
}

3.2 return

syntax: return code [text];
        return code URL;
        return URL;
context: server, location, if

停止处理并返回一个状态码给客户端。

3.3 if 指令

syntax: if (condition) { ... }
context: server, location

引入一个新的配置上下文,满足条件时执行配置块中的指令
condition为判断条件,支持三种设置方法:

  • 变量名,如果变量值为空字符串或者以0开头的任意字符串,则表示条件为false
  • 使用比较符判断变量与字符串的逻辑关系
  • 判断文件或目录存在情况

其中 比较操作符有:

  • =
  • !=
  • ~ 模式匹配,区分字符大小写
  • ~* 模式匹配,不区分字符大小写
  • !~:模式不匹配,区分字符大小写
  • !~*:模式不匹配,不区分字符大小写

文件及目录存在性判断:

  • -e, !-e 检查一个文件,目录,或软链接是否存在
  • -f, !-f 检查一个文件是否存在
  • -d, !-d 检查一个目录是否存在
  • -x, !-x 检查一个文件是否可执行

Example:

if ($http_user_agent ~ MSIE) {
    rewrite ^(.*)$ /msie/$1 break;
}

if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
    set $id $1;  
}

if ($request_method = POST) {
    return 405;
}

if ($slow) {
    limit_rate 10k;
}

if ($invalid_referer) {
    return 403;
}

3.4 rewrite的应用

3.4.1 域名跳转

Example:

#访问video.cutemsyu.com 跳转至v.cutemsyu.com
server {
    listen 80;
    server_name video.cutemsyu.com;
    rewrite ^(.*) http://v.cutemsyu.com$1 ;
    ...
}

3.4.2 rewrite uri中参数

默认情况下nginx进行rewrite后都会自动添加旧地址中参数部分,在replacement末尾添加”?”即可屏蔽旧地址中的参数
Example:

   ##原来的访问的url为http://cutemsyu.com/article/nature/index.php?id=22341
   rewrite ^/article/nature/(.*) http://cutemsyu.com/article/natrue.html permanent
   重写之后访问的URL为http://cutemsyu.com/article/nature.html?id=22341
   也就是说原有的参数部分它会自动补上
   rewrite ^/article/nature/(.*) http://cutemsyu.com/article/natrue.html? permanent
   重写之后的URL为http://cutemsyu.com/article/nature.html,没有原来的参数部分
    

3.4.3 防盗链

通常为了加快客户端访问资源响应时间,服务器不会一次性将全部资源响应给客户端,首先传回网页的文本内容,当客户端解析文本内容中的图片、视频等资源时会再次向服务器发起请求。当某个站点将图片链接指向其他服务器,给其他服务器造成负担,这就是非法的盗链行为。我们在搭建服务站点时要有意识防范盗链行为。
http协议头部中referer头域表示访问当前资源的源地址,根据referer中的源地址URL来判断是否来自本站,如非本站的地址,采取阻断措施防止盗链。

syntax: valid_referers none | blocked | server_names | string ...;
context: server,location;

valid_referers 指令根据规则检测头域中referer中值是否合法,如果非法内嵌变量 $invalid_referer 值为1.
参数含义:

  • none,表示检测referer为空的情况
  • blocked,表示检测referer的值被防火墙或者代理服务器删除的情况,通常referer的值不以http://或https:// 开头
  • server_names,referer的值应该被包含在server_name中
  • string,定义字符串形式。

    1. 开始或尾部带有通配符*
    2. 正则表达式,以~引导,匹配http://后面的内容

Example:

#如果发现盗链,重写链接为指定的表示禁止盗用的图片
server {
    listen 80;
    server_name v.cutemsyu.com;
    location ~* ^.+\.(gif|jpg|png|flv|mp4|swf)$ {
        valid_referers none blocked server_names *.cutemsyu.com ~\.google\.
        if ($invalid_referer) {
            rewrite ^/ http://v.cutemsyu.com/images/forbbiden.jpg
        }
    }
}

4、gzip压缩

压缩文本数据,提升网络响应速度,作为静态服务器使用很有必要开启,压缩文本将节省大量带宽,同时提升响应速度。但是如果作为反向代理服务器则需要考虑,压缩功能是否应该由后端服务器承担,以此减轻前端服务器CPU压力。

4.1 ngx_http_gzip_module

该模块功能是对指定类型数据使用gzip方法压缩
作用域Context: http, server, location

  1. gzip on |off;

此模块gzip功能启用或禁用

  1. gzip_types mime-types … ;

压缩过滤器,仅对指定的MIME类型进行压缩处理

  1. gzip_comp_level level;

设置压缩级别1-9,默认值为1压缩速率最快,压缩比最低

  1. gzip_min_length length;

启用压缩功能的响应报文大小阈值,小于该置不进行压缩。防止有些小数据压缩之后更大的情况,推荐值为1024

  1. gzip_buffers number size;

压缩数据使用缓冲区大小,size默认为内存分页大小

  1. gzip_disable regex;

旧版本的浏览器对于gzip功能支持不完善,对于该指令配置的正则信息与浏览器类型匹配,匹配成功的响应不进行压缩处理

  1. gzip_proxied off | expired | no-cache | no-store | private | no_last_modified | no_etag | auth | any …;

nginx作为反向代理服务器接收后端服务器响应结果压缩控制

4.2 ngx_http_gunzip_module

解压模块,该模块对于不支持压缩功能的浏览器请求,响应结果如果被压缩则将其解压后返回给客户端。适用于某些以gzip方式压缩过存储的数据。
作用域Context: http, server, location
提示该模块不是默认编译内容,编译选项–with-http_gunzip_module

  1. gunzip on |off ;
    是否开启该模块功能

    1. gunzip buffers number size;

用于解压数据使用的缓冲区空间配置

4.3 ngx_http_gzip_static_module

静态压缩模块,该模块允许发送预压缩数据,如果客户端请求的数据已被压缩过,且客户端支持gzip压缩,则直接返回压缩数据。
作用域Context: http, server, location
提示该模块不是默认编译内容,编译选项–with-http_gzip_static_module

  1. gzip_static on | off ;
    是否开启该模块
  2. gzip_disable regex;
    对于适配浏览器类型禁止gzip功能

4.4 配置示例

gzip on;
gzip_comp_level 3;
gzip_types text/html text/css text/xml text/plain application/javascript;
gzip_min_length 1024;
gzip_disable "MISE [4-6]\.";
gzip_buffers 8 16K;
gunzip on;         #支持自动解压功能

5、ssl模块

HTTP协议属于明文协议,通过抓包就可获取一些隐私数据。HTTPS经由超文本传输协议HTTP通信,但是数据包由SSL/TLS 安全协议加密,实现加密数据与认证功能。
ngx_http_ssl_module 该模块指令定义https相关设置:证书文件,私钥文件,ssl会话缓存等内容。
作用域Context: http, server

5.1 指令介绍

 1. ssl on | off;
 设定虚拟主机是否启用HTTPS协议
 2. ssl_certificate file;
 指定当前虚拟主机使用的PEM格式的证书文件
 3. ssl_certificate_key file;
 指定当前虚拟主机上与其证书相匹配的私钥文件
 4. ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
 支持ssl协议版本,默认为后三个
 5. ssl_session_cache off | none | [builtin[:size]] [ shared:name:size ];
 ssl会话缓存设置。
 builtin[:size] --使用OpenSSL内建的缓存,此缓存为每worker私有。容易产生内存碎片不推荐。
 shared:name:size --worker之间共享的缓存区域,size单位为bytes,1MB可存储4000个会话;name为共享缓存区域名称,多个虚拟主机可使用同一个共享缓存区。
 6. ssl_session_timeout time;
 客户端可重复使用会话参数的超时时长。默认5分钟

Example:

server {
                listen 443 ssl;
                server_name www.cutemsyu.com;
                root /website/ssl/htdocs;
                ssl on;
                ssl_certificate /etc/nginx/ssl/nginx.crt;
                ssl_certificate_key /etc/nginx/ssl/nginx.key;
                ssl_session_cache shared:sslcache:15m;
                ssl_session_timeout 3m;
            }

5.2 基于域名的HTTPS虚拟主机

值得考虑的一个问题是如何实现多个HTTPS虚拟主机监听在同一IP地址上。
情况一:每个虚拟主机使用各自的证书文件,如下

server {
    listen          443 ssl;
    server_name     www.example.com;
    ssl_certificate www.example.com.crt;
    ...
}

server {
    listen          443 ssl;
    server_name     www.example.org;
    ssl_certificate www.example.org.crt;
    ...
}

如此配置的话,客户端访问这两个站点建立SSL会话时收到的都是默认主机的证书文件。该问题是由于SSL协议造成的,SSL链接在客户端发送HTTP请求之前建立起来的,然而nginx并不知道所请求的服务主机名,因此返回默认服务器证书文件。
解决方法一:
多个HTTPS虚拟主机使用同一证书文件和私钥文件,证书和私钥配置指令在http级别设定,server共享其配置

ssl_certificate     common.crt;
ssl_certificate_key common.key;

server {
    listen          443 ssl;
    server_name     www.example.com;
    ...
}

server {
    listen          443 ssl;
    server_name     www.example.org;
    ...
}

解决办法二:
更通用的办法是使用TLS Server Name Indication extension技术,即SNI。SNI允许在客户端建立SSL会话时传递请求服务器名称,这样服务器就会知道该发送哪个虚拟主机下的证书文件。该技术需要浏览器支持,一般主流浏览器都已支持

  • Opera 8.0;
  • MSIE 7.0 (but only on Windows Vista or higher);
  • Firefox 2.0 and other browsers using Mozilla Platform rv:1.8.1;
  • Safari 3.2.1 (Windows version supports SNI on Vista or higher);
  • and Chrome (Windows version supports SNI on Vista or higher, too)

同时确保nginx支持SNI功能:

$ nginx -V
...
TLS SNI support enabled
...

本篇文章到此结束,下篇总结nginx反向代理,fastcgi模块,感谢关注!

    原文作者:cutemsyu
    原文地址: https://segmentfault.com/a/1190000008033192
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞