Nginx 高级配置

Nginx 高级配置

1. Nginx 状态页

​ 基于nginx模块ngx_http_auth_basic_module实现,在编译安装nginx的时候需要添加编译参数–with-http_stub_status_module,否则配置完成之后监测会是提示语法错误。

​ 状态页用于输出nginx的基本状态信息

location /nginx_status {
    stub_status;
    allow 192.168.0.0/16;
    allow 127.0.0.1;
    deny all;
}

mark

Active connections: 当前处于活动状态的客户端连接数,包括连接等待空闲连接数。
accepts:统计总值,Nginx自启动后已经接受的客户端请求的总数。
handled:统计总值,Nginx自启动后已经处理完成的客户端请求的总数,通常等于accepts,除非有因
worker_connections限制等被拒绝的连接。
requests:统计总值,Nginx自启动后客户端发来的总的请求数。
Reading:当前状态,正在读取客户端请求报文首部的连接的连接数。
Writing:当前状态,正在向客户端发送响应报文过程中的连接数。
Waiting:当前状态,正在等待客户端发出请求的空闲连接数,开启 keep-alive的情况下,这个值等于active – (reading+writing),

2. Nginx 第三方模块:

​ 第三模块是对nginx 的功能扩展,第三方模块需要在编译安装Nginx 的时候使用参数–add-module=PATH指定路径添加,有的模块是由公司的开发人员针对业务需求定制开发的,有的模块是开源爱好者开发好之后上传到github进行开源的模块,nginx支持第三方模块需要从源码重新编译支持,比如开源的echo模块

https://github.com/openresty/echo-nginx-module

安装echo 模块

参考说明:https://github.com/openresty/echo-nginx-module#installation

echo模块与nginx 的兼容性:https://github.com/openresty/echo-nginx-module#compatibility

在已经有编译后的nginx,添加echo模块

  1. 下载echo源码包,并且停止当前的nginx 进程

    root@z2:/usr/local/src# git clone https://github.com/openresty/echo-nginx-module.git
    root@z2:/usr/local/src# systemctl stop nginx
    
  2. 查看当前nginx 编译参数,为的configure 时添加add-modules 时不影响当前环境

    root@z2:/usr/local/src# nginx -V
    nginx version: nginx/1.16.1
    built by gcc 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) 
    built with OpenSSL 1.1.1  11 Sep 2018
    TLS SNI support enabled
    configure arguments: --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module
    
  3. 切换到原来nginx 的源码包

    root@z2:/usr/local/src# cd nginx-1.16.1/
    
  4. 重新构建编译的环境

    ./configure --prefix=/apps/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module --with-stream_realip_module --add-module=/usr/local/src/echo-nginx-module
    
  5. 编译(不用make install )

    make 时已经生成了所有的程序和文件,make install 只是把生成的文件复制到相应目录,完成了所谓的安装

    root@z2:/usr/local/src/nginx-1.16.1# make
    
  6. 把新生成的nginx 程序拷出来,替换掉原来的nginx 主程序文件,重启即可

    root@z2:/usr/local/src/nginx-1.16.1/objs# mv /apps/nginx/sbin/nginx{,.bak} 
    
    root@z2:/usr/local/src/nginx-1.16.1# cd objs/
    root@z2:/usr/local/src/nginx-1.16.1/objs# cp nginx /apps/nginx/sbin/
    root@z2:/usr/local/src/nginx-1.16.1/objs# systemctl start nginx
    
  7. 验证

      location /hello {
    	default_type    text/plain;
        echo  "hello world";
    }
    

    当访问 http://www.mage.net/hello/ 时,会显示 hello world;

3. Nginx 变量使用

​ nginx的变量可以在配置文件中引用,作为功能判断或者日志等场景使用,变量可以分为内置变量和自定义变量,内置变量是由nginx模块自带,通过变量可以获取到众多的与客户端访问相关的值。

3.1 内置变量

官方文档

下面是常见变量

$remote_addr;
#存放了客户端的地址,注意是客户端的公网IP,也就是一家人访问一个网站,则会显示为路由器的公网IP。
$args;
#变量中存放了URL中的指令,例如http://www.magedu.net/main/index.do?id=20190221&partner=search中的id=20190221&partner=search
$document_root
#保存了针对当前资源的请求的系统根目录,如/apps/nginx/html。
$document_uri
#保存了当前请求中不包含指令的URI,注意是不包含请求的指令,比如 http://www.magedu.net/main/index.do?id=20190221&partner=search会被定义为/main/index.do
$host
#存放了请求的host名称。
$http_user_agent
#客户端浏览器的详细信息
$http_cookie
#客户端的cookie信息。
limit_rate 10240;
echo $limit_rate;
#如果nginx服务器使用limit_rate配置了显示网络速率,则会显示,如果没有设置, 则显示0。
$remote_port
#客户端请求Nginx服务器时随机打开的端口,这是每个客户端自己的端口。
$remote_user;
#已经经过Auth Basic Module验证的用户名。
$request_body_file
#做反向代理时发给后端服务器的本地资源的名称。
$request_method
#请求资源的方式,GET/PUT/DELETE等
$request_filename
#当前请求的资源文件的路径名称,由root或alias指令与URI请求生成的文件绝对路径,
如/apps/nginx/html/main/index.html
$request_uri
#包含请求参数的原始URI,不包含主机名,如:/main/index.do?id=20190221&partner=search 。
$scheme
#请求的协议,如ftp,https,http等。
$server_protocol
#保存了客户端请求资源使用的协议的版本,如HTTP/1.0,HTTP/1.1,HTTP/2.0等。
$server_addr
#保存了服务器的IP地址。
$server_name
#请求的服务器的主机名。
$server_port
#请求的服务器的端口号。
3.2 自定义变量

假如需要自定义变量名称和值,使用指令set $variable value;,则方法如下

Context: server, location, if

Syntax: set $variable value; Default: — 
location /zdy {
    default_type    text/plain;
    set $name mage;
    echo $name;
    set $my_port $server_port;
    echo $my_port;
    echo "$server_name:$server_port";
}

验证:访问http://www.mage.net/zdy/ 得出结果

magedu
80
www.mage.net:80

4. Nginx 自定义访问日志

​ 访问日志是记录客户端即用户的具体请求内容信息,全局配置模块中的error_log是记录nginx服务器运行时的日志保存路径和记录日志的level,因此有着本质的区别,而且Nginx的错误日志一般只有一个,但是访问日志可以在不同server中定义多个,定义一个日志需要使用access_log指定日志的保存路径,使用log_format指定日志的格式,格式中定义要保存的具体日志内容。

4.1如果是要保留日志的源格式,只是添加相应的日志内容,则配置如下:

添加 ‘$server_name:$server_port’

http 中配置

log_format nginx_format1 '$remote_addr - $remote_user [$time_local]"$request" '
                                '$status $body_bytes_sent "$http_referer" '
                                '"$http_user_agent" "$http_x_forwarded_for"' '$server_name:$server_port';

server 中配置

access_log /data/nginx/logs/www-mage-net_access.log nginx_format1;

验证 :

访问http://www.mage.net/时,日志后面有www.mage.net:80

root@z2:~# tail -f /data/nginx/logs/www-mage-net_access.log 

192.168.0.1 - - [12/Mar/2020:10:31:16 +0800]"GET /zdy HTTP/1.1" 200 47 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36" "-"www.mage.net:80

4.2 自定义json格式日志

Nginx 的默认访问日志记录内容相对比较单一,默认的格式也不方便后期做日志统计分析,生产环境中通常将
nginx日志转换为json日志,然后配合使用ELK做日志收集-统计-分析。

即key value 模式

log_format access_json '{"@timestamp":"$time_iso8601",'
                                '"host":"$server_addr",'
                                '"clientip":"$remote_addr",'
                                '"size":$body_bytes_sent'
                                '"responsetime":$request_time,'
                                '"upstreamtime":"$upstream_response_time",'
                                '"upstreamhost":"$upstream_addr",'
                                '"http_host":"$host",'
                                '"uri":"$uri",'
                                '"domain":"$host",'
                                '"xff":"$http_x_forwarded_for",'
                                '"referer":"$http_referer",'
                                '"tcp_xff":"$proxy_protocol_addr",'
                                '"http_user_agent":"$http_user_agent",'
                                '"status":"$status"}';

access_log /data/nginx/logs/www-mage-net_access.log  access_json;
{"@timestamp":"2020-03-12T10:48:58+08:00","host":"192.168.1.102","clientip":"192.168.0.1","size":0"responsetime":0.000,"upstreamtime":"-","upstreamhost":"-","http_host":"www.mage.net","uri":"/index.html","domain":"www.mage.net","xff":"-","referer":"-","tcp_xff":"","http_user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36","status":"304"}

5. Nginx 压缩功能

​ Nginx支持对指定类型的文件进行压缩然后再传输给客户端,而且压缩还可以设置压缩比例,压缩后的文件大小将比源文件显著变小,这样有助于降低出口带宽的利用率,降低企业的IT支出,不过会占用相应的CPU资源。

Nginx对文件的压缩功能是依赖于模块ngx_http_gzip_module,官方文档, 配置指令如下:

#启用或禁用gzip压缩,默认关闭
gzip on | off;
#压缩比由低到高从1到9,默认为1
gzip_comp_level level;
#禁用IE6 gzip功能
gzip_disable "MSIE [1-6]\.";
#gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
#启用压缩功能时,协议的最小版本,默认HTTP/1.1
gzip_http_version 1.0 | 1.1;
#指定Nginx服务需要向服务器申请的缓存空间的个数*大小,默认32 4k|16 8k;
gzip_buffers number size;
#指明仅对哪些类型的资源执行压缩操作;默认为gzip_types text/html,不用显示指定,否则出错
gzip_types mime-type ...;
#如果启用压缩,是否在响应报文首部插入“Vary: Accept-Encoding”
gzip_vary on | off;

例子:

gzip on;
gzip_comp_level 5;
gzip_min_length 1k;

gzip_types text/plain application/javascript application/x-javascript
text/cssapplication/xml text/javascript application/x-httpd-php image/jpeg
image/gif image/png;

gzip_vary on;

压缩之后

mark

mark

没有压缩之前

root@z2:~# ll  /data/nginx/html/pc/test.html 
-rw-r--r-- 1 root root 1086284 Mar 12 11:48 /data/nginx/html/pc/test.html

root@z2:~# curl -I http://www.mage.net/test.html
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 12 Mar 2020 04:01:55 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 1086284
Last-Modified: Thu, 12 Mar 2020 03:48:20 GMT
Connection: keep-alive
ETag: "5e69b104-10934c"
Accept-Ranges: bytes

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9wbB3aYK-1584259839251)(A:%5Cimage_typoral_used%5Cimage-20200312120616343.png)]

6. https 功能

​ Web网站的登录页面都是使用https加密传输的,加密数据以保障数据的安全,HTTPS能够加密信息,以免敏感信息被第三方获取,所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用HTTPS协议,HTTPS其实是有两部分组成:HTTP + SSL / TLS,也就是在HTTP上又加了一层处理加密信息的模块。服务端和客户端的信息传输都会通过TLS进行加密,所以传输的数据都是加密后的数据。

6.0 https 实现过程如下:

mark

  1. 客户端发起HTTPS请求:

    客户端访问某个web端的https地址,一般都是443端口

  2. 服务端的配置

    ​ 采用https协议的服务器必须要有一套证书,可以通过一些组织申请,也可以自己制作,目前国内很多网站都自己做的,当你访问一个网站的时候提示证书不可信任就表示证书是自己做的,证书就是一个公钥和私钥匙,就像一把锁和钥匙,正常情况下只有你的钥匙可以打开你的锁,你可以把这个送给别人让他锁住一个箱子,里面放满了钱或秘密,别人不知道里面放了什么而且别人也打不开,只有你的钥匙是可以打开的。

  3. 传送证书

    ​ 服务端给客户端传递证书,其实就是公钥,里面包含了很多信息,例如证书得到颁发机构、过期时间等等。

  4. 客户端解析证书

    ​ 这部分工作是有客户端完成的,首先回验证公钥的有效性,比如颁发机构、过期时间等等,如果发现异常则会弹出一个警告框提示证书可能存在问题,如果证书没有问题就生成一个随机值,然后用证书对该随机值进行加密,就像2步骤所说把随机值锁起来,不让别人看到。

  5. 传送4步骤的加密数据

    ​ 就是将用证书加密后的随机值传递给服务器,目的就是为了让服务器得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值进行加密解密了

  6. .服务端解密信息

    ​ 服务端用私钥解密5步骤加密后的随机值之后,得到了客户端传过来的随机值(私钥),然后把内容通过该值进行对称加密,对称加密就是将信息和私钥通过算法混合在一起,这样除非你知道私钥,不然是无法获取其内部的内容,而正好客户端和服务端都知道这个私钥,所以只要机密算法够复杂就可以保证数据的安全性。

  7. 传输加密后的信息

    服务端将用私钥加密后的数据传递给客户端,在客户端可以被还原出原数据内容。

  8. 客户端解密信息

    ​ 客户端用之前生成的私钥获解密服务端传递过来的数据,由于数据一直是加密的,因此即使第三方获取到数据也无法知道其详细内容。

6.1 ssl 配置参数

​ nginx 的https 功能基于模块ngx_http_ssl_module实现,因此如果是编译安装的nginx要使用参数
ngx_http_ssl_module开启ssl功能,但是作为nginx的核心功能,yum安装的nginx默认就是开启的,编译安装的nginx需要指定编译参数–with-http_ssl_module开启, 官方文档,配置参数如下:

ssl on | off;
#为指定的虚拟主机配置是否启用ssl功能,此功能在1.15.0废弃,使用listen [ssl]替代。

ssl_certificate /path/to/file;
#当前虚拟主机使用使用的公钥文件,一般是crt文件

ssl_certificate_key /path/to/file;
#当前虚拟主机使用的私钥文件,一般是key文件

ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
#支持ssl协议版本,早期为ssl现在是TSL,默认为后三个

ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
#配置ssl缓存  off: 关闭缓存  none: 通知客户端支持ssl session cache,但实际不支持
#builtin[:size]:使用OpenSSL内建缓存,为每worker进程私有
#[shared:name:size]:在各worker之间使用一个共享的缓存,需要定义一个缓存名称和缓存空间大小,一兆可以存储4000个会话信息,多个虚拟主机可以使用相同的缓存名称。

ssl_session_timeout time;#客户端连接可以复用ssl session cache中缓存的有效时长,默认5m
6.2 自签名 证书
root@z2:~# cd /apps/nginx/
root@z2:/apps/nginx# mkdir certs
root@z2:/apps/nginx# cd certs/

填入 CN BJ BJ mage rs mage.ca

openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 3650 -out ca.crt

填入 CN BJ BJ mage dev www.mage.net

openssl req -newkey rsa:4096 -nodes -sha256 -keyout www.mage.net.key -out www.mage.net.csr

签发证书

openssl x509 -req -days 3650 -in www.mage.net.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out www.mage.net.crt

server 设置

listen 443 ssl;
ssl_certificate /apps/nginx/certs/www.mage.net.crt;
ssl_certificate_key /apps/nginx/certs/www.mage.net.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
6.3 实现多域名HTTPS

Nginx支持基于单个IP实现多域名的功能,并且还支持单IP多域名的基础之上实现HTTPS,其实是基于Nginx的
SNI(Server Name Indication)功能实现,SNI是为了解决一个Nginx服务器内使用一个IP绑定多个域名和证书的
功能,其具体功能是客户端在连接到服务器建立SSL链接之前先发送要访问站点的域名(Hostname),这样服务
器再根据这个域名返回给客户端一个合适的证书。

每个server 配置不同的证书路径即可

7. 关于favicon.ico

​ favicon.ico 文件是浏览器收藏网址时显示的图标,当客户端使用浏览器问页面时,浏览器会自己主动发起请求获取页面的favicon.ico文件,但是当浏览器请求的favicon.ico文件不存在时,服务器会记录404日志,而且浏览器也会显示404报错。 (curl 浏览器并不会)

{"@timestamp":"2020-03-12T18:23:35+08:00","host":"192.168.1.102","clientip":"192.168.0.1","size":548"responsetime":0.000,"upstreamtime":"-","upstreamhost":"-","http_host":"www.mage.net","uri":"/favicon.ico","domain":"www.mage.net","xff":"-","referer":"https://www.mage.net/","tcp_xff":"","http_user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36","status":"404"}

解决办法:

1.不记录相关日志

location = /favicon.ico {
    log_not_found off;
    access_log off;
}

2.设置favicon.ico location

例如: 把天猫的 favicon.ico 给自己网站用用

mark

勾选other,下面的那张小图片就是,下载下来

root@z2:~# mkdir /data/nginx/html/pc/images
root@z2:~# cd  /data/nginx/html/pc/images
root@z2:/data/nginx/html/pc/images# wget https://img.alicdn.com/tfs/TB1XlF3RpXXXXc6XXXXXXXXXXXX-16-16.png
root@z2:/data/nginx/html/pc/images# mv TB1XlF3RpXXXXc6XXXXXXXXXXXX-16-16.png  favicon.ico

conf设置:

#location ~ ^/favicon\.ico$ {
location = /favicon.ico {
	root /data/nginx/html/pc/images;
}

验证:

mark

发布了62 篇原创文章 · 获赞 7 · 访问量 1257

猜你喜欢

转载自blog.csdn.net/qq_36801585/article/details/104880473