前言

        在本系列的前一篇文章中,我们介绍了Nginx的目前市场使用状况,以及Nginx的安装和配置。并且主要记录了Nginx应用中一个比较重要的模块ngx_http_core_module。接下来我们重要介绍Nginx的其他应用配置。并且以模块的形式进行记录和分析。

目录

本片文章,将主要介绍下面这几个模块。

  • ngx_http_access_module基于ip的访问控制

  • ngx_http_auth_basic_module 基于用户的访问控制

  • ngx_http_stub_status_module 输出nginx的基本信息

  • ngx_http_log_module 指定日志格式记录请求

  • ngx_http_gzip_module 用gzip方法压缩响应数据

  • ngx_http_ssl_module 是否使用加密传输

  • ngx_http_rewrite_module 对用户请求完成重定向替换

  • ngx_http_proxy_module 代理模块

  • ngx_http_headers_module 响应报文头部

  • ngx_http_fastcgi_module fastcgi 模块

ngx_http_access_module

        这个模块能够实现基于IP的访问规则。也就是说能够控制哪些IP地址或者网段能够访问到服务。
        这里的语法如下面所示。

Syntax:	        allow address | CIDR | unix: | all;
Default:	—
Context:	http, server, location, limit_except

        举个例子来说明一下。

location / {
    deny  192.168.1.1;
    allow 192.168.1.0/24;
    allow 10.1.1.0/16;
    allow 2001:0db8::/32;
    deny  all;
    }

        Nginx 在进行匹配的过程中,会自上而下进行匹配,规则最严格的写在前面。在这个例子中,最后的匹配效果就是,系统允许除了192.168.1.1以外的192.168.1.0 整个网段进行访问,允许10.1.0.0 整个网段进行访问,同时允许IPV6地址 2001:0db8:: 进行访问,除此之外,全部拒绝。
    这些都是一些最基本的匹配规则,如果需要更复杂的规则可以参考ngx_http_geo_module模块。

ngx_http_auth_basic_module

        实现基于用户的访问控制,使用basic机制进行用户认证。当用户想要通过浏览器访问web服务的时候,需要输入用户名密码,才可以进行访问。

        首先来看一个例子。

ocation / {
    auth_basic           "closed site";
    auth_basic_user_file /etc/nginx/conf.d/.htpasswd;
    }

        实现的过程很简单, 只需要上面的两行代码就可以搞定。 而Apache服务器在相关的功能确是要复杂的多。

        其中 auth_basic 的基本语法结构如下所示。

Syntax:	        auth_basic string | off;
Default:	auth_basic off;
Context:	http, server, location, limit_except

        auth_basic 的主要作用就是提示提示框的基本内容。也就是下图中箭头指向的内容。

http://ot2trm1s2.bkt.clouddn.com/Linux/2017-10-27-linux-pro-command-5/basic_auth.png

        auth_basic_user_file 的主要作用就是用来存放用户名和密码。

Syntax:	        auth_basic_user_file file;
Default:	—
Context:	http, server, location, limit_except

        用户名和密码采用下面的格式username:passwd:comment

name1:password1
name2:password2:comment
name3:password3

        当然也可以采用加密的方式来进行密码的设置。可以使用httpd-tools工具提供的htpasswd工具来实现。命令格式 htpasswd -c -m FILENAME USERNAME

ngx_http_stub_status_module

        输出Nginx 的基本状态信息。 这可以打开一个专门的页面,用来显示Nginx的基本信息。

Syntax:	        stub_status;
Default:	—
Context:	server, location

        这时Nginx的一个基本的功能。所以我们只要开启一下这个功能就可以。

location /basic_status {
    stub_status;
    }

        输出的状态信息如下所示。

Active connections: 2 
server accepts handled requests
        19      19      14 
Reading: 0 Writing: 1 Waiting: 1
  • Active connections:当前状态,活动状态的连接数

  • accepts:统计总值,已经接受的客户端请求的总数

  • handled:统计总值,已经处理完成的客户端请求的总数

  • requests:统计总值,客户端发来的总的请求数

  • Reading:当前状态,正在读取客户端请求报文首部的连接的连接数

  • Writing:当前状态,正在向客户端发送响应报文过程中的连接数

  • Waiting:当前状态,正在等待客户端发出请求的空闲连接数

ngx_http_log_module

        根据指定的格式来定义日志的记录。 
        首先来看一段日志记录的代码示例。

log_format compression '$remote_addr - $remote_user [$time_local] '
                       '"$request" $status $bytes_sent '
                       '"$http_referer" "$http_user_agent" "$gzip_ratio"';
access_log /var/log/nginx/nginx-access.log compression buffer=32k;

        能够看出,这里一共有两部分定义,分别是定义日志的记录格式以及指定记录日志的路径。其中log_format 的定义如下。

Syntax:	        log_format name [escape=default|json] string ...;
Default:	log_format combined "...";
Context:	http

log_format 包含了大量的变量定义,常用的变量定义如下:

  • $bytes_sent: 返回给客户端的字节数

  • $connection: 链接请求的序号

  • $request_length: 请求的长度,包含(请求线,请求头和请求体)

  • $request_time : 整个请求所经历的时间。

  • $status : 响应的状态

access_log 的定义如下:

Syntax:	        access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];access_log off;
Default:	access_log logs/access.log combined;
Context:	http, server, location, if in location, limit_except

        在指定 日志存储路径的时候,除了要指定使用的是哪一个log_format 外,还可以指定缓存的大小,gzip压缩的等级,刷新的时间。

ngx_http_gzip_module

        用gzip的方法压缩响应数据,节约带宽。语法如下:

Syntax:	        gzip on | off;
Default:	gzip off;
Context:	http, server, location, if in location

Syntax:	        gzip_comp_level level;
Default:	gzip_comp_level 1;
Context:	http, server, location

还有一些其他的压缩选项,我们列举一下。
1、gzip on | off; 启用或者禁用gizp压缩。
2、gzip_comp_level level; 设置压缩比,从1到9,默认是1.
3、gzip_disable regex ...; 匹配到客户端浏览器不执行压缩
4、gzip_min_length length; 启用压缩功能的响应报文大小阈值
5、gzip_http_version 1.0 | 1.1;设定启用压缩功能时,协议的最小版本,默认是1.1
6、gzip_buffers number size支持实现压缩功能时缓冲区数量及每个缓存区的大小,默认32位主机4K,16位主机8K.
7、 gzip_types mime-type ...; 指明仅对哪些类型的资源执行压缩操作;即压缩过滤器,默认包含有text/html,不用显示指定,否则出错。
8、gzip_vary on | off;如果启用压缩,是否在响应报文首部插入“Vary: AcceptEncoding”

ngx_http_ssl_module

        ssl 模块是一个非常重要的模块,它能够实现http请求的加密传输,也就是实现https的加密传输。这一点是很重要的。当然如果要实现https,就要指定证书文件路径,以及相对应的私钥文件路径等等。

http {

    ...

    server {
        listen              443 ssl;
        keepalive_timeout   70;

        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers         AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:RC4-MD5;
        ssl_certificate     /usr/local/nginx/conf/cert.pem;
        ssl_certificate_key /usr/local/nginx/conf/cert.key;
        ssl_session_cache   shared:SSL:10m;
        ssl_session_timeout 10m;

        ...    
        }
    ...
   }

1、ssl on | off; 为指定虚拟机启用HTTPS protocol, 建议用listen指令替代。如 listen 443 ssl
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]; builtin[:size]:使用OpenSSL内建缓存,为每worker进程私有。[shared:name:size]:在各worker之间使用一个共享的缓存。
6、ssl_session_timeout time; 客户端连接可以复用ssl session cache中缓存的ssl参数的有效时长,默认5m

ngx_http_rewrite_module

将用户请求的URI基于PCRE regex所描述的模式进行检查,而后完成重定向替换。

1、rewrite regex replacement [flag]

      将用户请求的URI基于regex所描述的模式进行检查,匹配到时将其替换为replacement指定的新的URI
        注意:如果在同一级配置块中存在多个rewrite规则,那么会自下而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查。
        隐含有循环机制,但不超过10次;如果超过,提示500响应码,[flag]所表示的标志位用于控制此循环机制
        如果replacement是以http://或https://开头,则替换结果会直接以重向返回给客户端

Syntax:	        rewrite regex replacement [flag];
Default:	—
Context:	server, location, if

[flag]
        last:重写完成后停止对当前URI在当前location中后续的其它重写操作,而后对新的URI启动新一轮重写检查;提前重启新一轮循环 
         break:重写完成后停止对当前URI在当前location中后续的其它重写操作,而后直接跳转至重写规则配置块之后的其它配置;结束循环,建议在location中使用 
         redirect:临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求;不能以http://或https://开头,使用相对路径,状态码:302
        permanent:重写完成后以永久重定向方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求,状态码:301

2、return

        停止处理,并返回给客户端指定的响应码。语法如下。

Syntax:	return code [text];
        return code URL;
        return URL;
Default:	—
Context:	server, location, if

3、rewrite_log on | off;

        指定是否开启重写日志。将日志信息发送到error_log 。

Syntax:	rewrite_log on | off;
Default:	rewrite_log off;
Context:	http, server, location, if

4、if (condition) { … }

        使用if语句来判断上下文条件是否满足。如果满足就执行配置代码块中的语句。
具体的语法如下。

Syntax:	if (condition) { ... }
Default:	—
Context:	server, location

其中condition与BASH中的条件判断很类似。
比较操作符:

  • ==相同

  • != 不同

  • ~:模式匹配,区分字符大小写

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

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

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

文件及目录存在性判断:

  • -e, !-e 存在(包括文件,目录,软链接)

  • -f, !-f 文件

  • -d, !-d 目录

  • -x, !-x 执行

ngx_http_proxy_module

        将客户端发来的请求转发到另外一台主机。这也就是我们通常所说的反向代理。在实际生产中,我们经常需要根据不同的请求,进行处理和转发,以便能够达到负载均衡的网络拓扑。
        Nginx的http_proxy模块在这方面的处理能力上,是非常优秀的。

1、proxy_pass URL

proxy_pass结构的语法如下所示。

Syntax:	proxy_pass URL;
Default:	—
Context:	location, if in location, limit_except

下面来看一个例子。

server {
    ...
    server_name HOSTNAME;
    location /uri/ {
        proxy_pass http://host[:port]; # 最后没有/
    }
    ...
}

        这里有一点需要注意,proxy_pass后面路径不带uri时,会将location的uri传递(附加)给后端主机。也就是说,上面示例中,如果我们访问http://HOSTNAME/uri时,Nginx会将请求转发到 http://host/uri。

        proxy_pass后面的路径是一个uri时,其会将location的uri替换为proxy_pass的uri。比方说下面的这个例子。

server {
    ...
    server_name HOSTNAME;
    location /uri/ {
        proxy_pass http://host/new_uri/;
    }
    ...
 }

    当用户去请求 http://HOSTNAME/uri/ 的时候,Nginx会自动调度到 http://host/new_uri/ ,这一点,与上面的内容还是有所区别的。

        如果location定义其uri时使用了正则表达式的模式,proxy_pass之后必须不能使用uri; 用户请求时传递的uri将直接附加至后端服务器之后。看一下下面的这个例子。

server {
    ...
    server_name HOSTNAME;
    location ~|~* /uri/ {
         proxy_pass http://host; # 不能加/
    }
    ...
 }

    此时,如果用户访问http://HOSTNAEM/uri/ 的时候,系统会自动调度到 http://host/uri/

2、proxy_set_header field value

        设定发往后端主机的请求报文的请求首部的值。

Syntax:	    proxy_set_header field value;
Default:    proxy_set_header Host $proxy_host;
            proxy_set_header Connection close;
Context:	http, server, location

        其中 field 指的是,自己定义的变量名称,value指的是,Nginx支持的变量。这样 我们在后端主机上就可以根据自己定义的Field名称进行新的日志记录了。

3、proxy_cache_path

定义可用于proxy功能的缓存。

Syntax:	proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
Default:	—
Context:	http

4、proxy_cache zone | off

        指明调用的缓存,或者关闭缓存机制。

Syntax:	proxy_cache zone | off;
Default:	proxy_cache off;
Context:	http, server, location

5、proxy_cache_key string

        缓存中用于键的内容。

Syntax:	        proxy_cache_key string;
Default:	proxy_cache_key $scheme$proxy_host$request_uri;
Context:	http, server, location

6、proxy_cache_valid [code …] time

        定义对特定响应码的响应内容的缓存时长。 例如 当访问到404的时候,不用每次都去访问服务器,而是直接从缓存中取值。

Syntax:	        proxy_cache_valid [code ...] time;
Default:	—
Context:	http, server, location

看一下下面的这个例子

proxy_cache_path /var/cache/nginx/proxy_cache levels=1:1:1 keys_zone=proxycache:20m inactive=120s max_size=1g;

         /var/cache/nginx/proxy_cache 指的是缓存存放的路径。levels指的是使用了几级缓存,也就是几级目录。keys_zone 指的是缓存的对象,以及大小。 
上面的定义如果要生效,还需要在相应的配置段中定义下面的一些内容。

proxy_cache proxycache;             # 这个proxycache 就是在前面key_zone 中定义的名字
proxy_cache_key $request_uri;       
proxy_cache_valid 200 302 301 1h;   # 每种响应码的缓存时间
proxy_cache_valid any 1m;

7、proxy_cache_use_stale

        指定在被代理的后端服务器出现哪种情况下,可以真接使用过期的缓存响应客户端。

Syntax:	proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | http_429 | off ...;
Default:	proxy_cache_use_stale off;
Context:	http, server, location

8、proxy_cache_methods

    对哪些客户端请求方法对应的响应进行缓存,GET和HEAD方法总是被缓存。

Syntax:	proxy_cache_methods GET | HEAD | POST ...;
Default:	proxy_cache_methods GET HEAD;
Context:	http, server, location

9、proxy_hide_header field

        默认nginx在响应报文不传递后端服务器的首部字段Date, Server, X-Pad, X-Accel-等,用于隐藏后端服务器特定的响应首部。

Syntax:	        proxy_hide_header field;
Default:	—
Context:	http, server, location

10、proxy_connect_timeout time

        定义与后端服务器建立连接的超时时长,如超时会出现502错误,默认为60s,一般不建议超出75s。

Syntax:	        proxy_connect_timeout time;
Default:	proxy_connect_timeout 60s;
Context:	http, server, location

11、proxy_send_timeout time

        将请求发送给后端服务器的超时时长;默认为60s。

Syntax:	        proxy_send_timeout time;
Default:	proxy_send_timeout 60s;
Context:	http, server, location

12、proxy_read_timeout time

        等待后端服务器发送响应报文的超时时长,默认为60s

Syntax:	        proxy_read_timeout time;
Default:	proxy_read_timeout 60s;
Context:	http, server, location

ngx_http_headers_module 模块

        向由代理服务器响应给客户端的响应报文添加自定义首部,或修改指定首部的值。这样用户就不会知道真实服务器的相关信息,客户端接收的信息都是代理服务器经过处理之后转发回去的。

1、add_header name value [always]

        添加自定义的首部

Syntax:	        add_header name value [always];
Default:	—
Context:	http, server, location, if in location

        例如我们可以添加下面几种首部也是可以的。

add_header X-Via $server_addr;
add_header X-Cache $upstream_cache_status;
add_header X-Accel $server_nam

2、 add_trailer name value [always]

        添加自定义响应信息的尾部。这项配置出现了1.13.2版本之后。

Syntax:	        add_trailer name value [always];
Default:	—
Context:	http, server, location, if in location

ngx_http_fastcgi_module

        在对PHP程序的处理上,Nginx与Apache有所不同,Nginx默认不支持PHP模块。所以Nginx是通过代理的形式进行处理。也就是说,当Nginx接收到关于php的请求以后,Nginx将这种请求发送到能够处理PHP的服务器上去处理。而且,在转发的过程中必须要使用fast-cgi协议。也就是说,支持php的应用服务器必须支持fast-cgi模式。所以可以将Nginx和Apache结合使用。

1、fastcgi_pass address

        address为后端的fastcgi server的地址。

Syntax:	        fastcgi_pass address;
Default:	—
Context:	location, if in location

2、fastcgi_index name

        fastcgi默认的主页资源。

Syntax:	        fastcgi_index name;
Default:	—
Context:	http, server, location

3、fastcgi_param parameter value [if_not_empty]

        设置传递给 FastCGI服务器的参数值,可以是文本,变量或组合。

Syntax:	        fastcgi_param parameter value [if_not_empty];
Default:	—
Context:	http, server, location

我们可以看一下下面的几个例子。

示例1
(1)在后端服务器先配置fpm server和mariadb-server
(2)在前端nginx服务上做以下配置:

location ~* \.php$ {
    fastcgi_pass 后端fpm服务器IP:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME /app/php$fastcgi_script_name;
    include fastcgi_params;
    …
}

示例2 
通过/pm_status和/ping来获取fpm server状态信息

location ~* ^/(pm_status|ping)$ {
    include fastcgi_params;
    fastcgi_pass 后端fpm服务器IP:9000;
    fastcgi_param SCRIPT_FILENAME $fastcgi_script_name;
  }

4、fastcgi_cache_path

        定义fastcgi的缓存

Syntax:	fastcgi_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size 
         [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] 
        [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] 
        [purger_files=number] [purger_sleep=time] [purger_threshold=time];
Default:	—
Context:	http

path : 缓存位置为磁盘上的文件系统
max_size=size : 磁盘path路径中用于缓存数据的缓存空间上限
levels=levels: 缓存目录的层级数量,以及每一级的目录数量
levels=ONE:TWO:THREE 示例:leves=1:2:2
keys_zone=name:size k/v映射的内存空间的名称及大小
inactive=time 非活动时长

5、fastcgi_cache

&msp;调用指定的缓存空间来缓存数据。

Syntax:	        fastcgi_cache zone | off;
Default:	fastcgi_cache off;
Context:	http, server, location

6、fastcgi_cache_key string

定义用作缓存项的key的字符串。

Syntax:	        fastcgi_cache_key string;
Default:	—
Context:	http, server, location

7、fastcgi_cache_methods

为哪些请求方法设置缓存。

Syntax:	fastcgi_cache_methods GET | HEAD | POST ...;
Default:	fastcgi_cache_methods GET HEAD;
Context:	http, server, location

8、fastcgi_cache_min_uses number

        缓存空间中的缓存项在inactive定义的非活动时间内至少要被访问到此处所指定的次数方可被认作活动项。

Syntax:	        fastcgi_cache_min_uses number;
Default:	fastcgi_cache_min_uses 1;
Context:	http, server, location

9、fastcgi_keep_conn on | off

收到后端服务器响应后,fastcgi服务器是否关闭连接,建议启用长连接。

Syntax:	        fastcgi_keep_conn on | off;
Default:	fastcgi_keep_conn off;
Context:	http, server, location

10、fastcgi_cache_valid [code …] time

不同的响应码各自的缓存时长

Syntax:	fastcgi_cache_valid [code ...] time;
Default:	—
Context:	http, server, location

        至此,我们就已经介绍了Nginx的大部分常用应用。当然在实际使用中情况还可能更复杂。到时,可以参考Nginx的文档参考。下面附上一个学习过程中的配置图,以便参考。可右键在新的标签页中打开,查看大图。

Nginx%E9%85%8D%E7%BD%AE%E7%A4%BA%E4%BE%8