Linux-nginx高级配置

nginx状态页

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

注意:状态页显示的是整个服务器的状态,而非虚拟机主机的状态

#配置示例:
location /nginx_status {
   stub_status;
   auth_basic           "auth login";
   auth_basic_user_file /apps/nginx/conf/.htpasswd;
   allow 192.168.0.0/16;
   allow 127.0.0.1;
   deny all;
 }

#状态页用于输出nginx的基本状态信息:
#输出信息示例:
Active connections: 291
server accepts handled requests
 16630948 16630948 31070465
 上面三个数字分别对应accepts,handled,requests三个值
Reading: 6 Writing: 179 Waiting: 106

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

 

分析网站当前访问量
[root@centos7 ~]#curl http://wang:123456@www.wangxiaochun.com/nginx_status 2> /dev/null |awk '/Reading/{print $2,$4,$6}'
0 1 15

Nginx 第三方模块

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

echo模块官方说明

 

[root@centos8 ~]# systemctl stop nginx
[root@centos8 ~]# vim /apps/nginx/conf/conf.d/pc.conf
 location /main {
     index index.html;
     default_type text/html;
     echo "hello world,main-->";
     echo $remote_addr ;
     echo_reset_timer;   #将计时器开始时间重置为当前时间
     echo_location /sub1;
     echo_location /sub2;
     echo "took $echo_timer_elapsed sec for total.";
 }
 location /sub1 {
     echo_sleep 1;
     echo sub1;
 }
 location /sub2 {
     echo_sleep 1;
     echo sub2;
 }

 

Nginx 变量使用

nginx的变量可以在配置文件中引用,作为功能判断或者日志等场景使用

变量可以分为内置变量和自定义变量

内置变量是由nginx模块自带,通过变量可以获取到众多的与客户端访问相关的值。

http://nginx.org/en/docs/varindex.html

 

常用内置变量

$remote_addr;
#存放了客户端的地址,注意是客户端的公网IP
$proxy_add_x_forwarded_for #此变量表示将客户端IP追加请求报文中X
-Forwarded-For首部字段,多个IP之间用逗号分隔,如果请求中没有X-Forwarded-For,就使用$remote_addr the “X-Forwarded-For” client request header field with the $remote_addr variable appended to it, separated by a comma. If the “X-Forwarded-For” field is not present in the client request header, the $proxy_add_x_forwarded_for variable is equal to the $remote_addr variable. $args;
#变量中存放了URL中的所有参数,例如:http:
//www.magedu.org/main/index.do? id=20190221&partner=search
#返回结果为: id
=20190221&partner=search $document_root;
#保存了针对当前资源的请求的系统根目录,例如:
/apps/nginx/html。 $document_uri;
#保存了当前请求中不包含参数的URI,注意是不包含请求的指令,比 如:http:
//www.magedu.org/main/index.do?id=20190221&partner=search会被定义 为/main/index.do

#返回结果为:/main/index.do $host;
#存放了请求的host名称 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,不包含主机名,相当于:$document_uri
?$args,例如:/main/index.do? id=20190221&partner=search $scheme;
#请求的协议,例如:http,https,ftp等 $server_protocol;
#保存了客户端请求资源使用的协议的版本,例如:HTTP
/1.0,HTTP/1.1,HTTP/2.0等 $server_addr;
#保存了服务器的IP地址 $server_name;
#请求的服务器的主机名 $server_port;
#请求的服务器的端口号 $http_user_agent;
#客户端浏览器的详细信息 $http_cookie;
#客户端的所有cookie信息 $cookie_
<name>

#name为任意请求报文首部字部cookie的key名 $http_<name>

#name为任意请求报文首部字段,表示记录请求报文的首部字段,ame的对应的首部字段名需要为小写,如果有 横线需要替换为下划线 arbitrary request header field; the last part of a variable name is the field name converted to lower case with dashes replaced by underscores #用下划线代替横线 #示例: echo $http_user_agent; echo $http_host; $sent_http_<name>

#name为响应报文的首部字段,name的对应的首部字段名需要为小写,如果有横线需要替换为下划线,此变量 有问题 echo $sent_http_server; $arg_<name>

#此变量存放了URL中的指定参数,name为请求url中指定的参数 echo $arg_id;

 

自定义变量

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

语法格式:

语法格式:
Syntax: set $variable value;
Default: —
Context: server, location, if
set $name magedu;
echo $name;
set $my_port $server_port;
echo $my_port;
echo "$server_name:$server_port";
#输出信息如下
[root@centos6 ~]#curl www.magedu.org/main
magedu
80
www.magedu.org:80

 

Nginx 自定义访问日志

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

访问日志由 ngx_http_log_module 模块实现

 

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

自定义默认格式日志

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

#注意:此指令只支持http块,不支持server块
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';
#注意:此指令一定要在放在log_format命令后
access_log logs/access.log nginx_format1;
#重启nginx并访问测试日志格式
==> /apps/nginx/logs/access.log <==
10.0.0.1 - - [22/Feb/2019:08:44:14 +0800] "GET /favicon.ico HTTP/1.1" 404 162 "-
" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:65.0) Gecko/2
0100101 Firefox/65.0" "-"www.magedu.org:80

 

自定义json格式日志

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

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",'
        '"xff":"$http_x_forwarded_for",'
           '"referer":"$http_referer",'
        '"tcp_xff":"$proxy_protocol_addr",'
        '"http_user_agent":"$http_user_agent",'
        '"status":"$status"}';
     access_log /apps/nginx/logs/access_json.log access_json;
    
#重启Nginx并访问测试日志格式,参考链接:http://json.cn/
{"@timestamp":"2019-02-
22T08:55:32+08:00","host":"10.0.0.8","clientip":"10.0.0.1","size":162,"responset
ime":0.000,"upstreamtime":"-","upstreamhost":"-
","http_host":"www.magedu.org","uri":"/favicon.ico","xff":"-","referer":"-
","tcp_xff":"","http_user_agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64;
rv:65.0) Gecko/20100101 Firefox/65.0","status":"404"}

json 格式的日志访问统计

#python3
[root@centos8 ~]#dnf -y install python3
[root@centos8 ~]#cat log.py
#!/usr/bin/env python3
#coding:utf-8
status_200= []
status_404= []
with open("access_json.log") as f:
    for line in f.readlines():
        line = eval(line)
        if line.get("status") == "200":
            status_200.append(line.get)
        elif line.get("status") == "404":
            status_404.append(line.get)
        else:
            print("状态码 ERROR")
        print((line.get("clientip")))
f.close()
print("状态码200的有--:",len(status_200))
print("状态码404的有--:",len(status_404))
#python2
[root@centos8 ~]#dnf -y install python2
[root@centos8 ~]#cat log.py
#!/usr/bin/env python
#coding:utf-8
status_200= []
status_404= []
with open("access_json.log") as f:
    for line in f.readlines():
        line = eval(line)
        if line.get("status") == "200":
            status_200.append(line.get)
        elif line.get("status") == "404":
            status_404.append(line.get)
        else:
            print("状态码 ERROR")
        print(line.get("clientip"))
f.close()
print "状态码200的有--:",len(status_200)
print "状态码404的有--:",len(status_404)
#保存日志文件到指定路径并进测试:
[root@centos7 ~]# python nginx_json.py
状态码200的有--: 1910
状态码404的有--: 13
    
    
#转换python2语法到python3
[root@centos8 ~]#pip3 install 2to3
[root@centos8 ~]#2to3 -w log.py         

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;
#预压缩,即直接从磁盘找到对应文件的gz后缀的式的压缩文件返回给用户,无需消耗服务器CPU
#注意: 来自于ngx_http_gzip_static_module模块
gzip_static on | off;
#重启nginx并进行访问测试压缩功能
[root@centos8 ~]# cp /apps/nginx/logs/access.log /data/nginx/html/pc/m.txt
[root@centos8 ~]# echo "test" > /data/nginx/html/pc/test.html #小于1k的文件测试是否
会压缩
[root@centos8 ~]# vim /apps/nginx/conf/nginx.conf
gzip on;
gzip_comp_level 5;
gzip_min_length 1k;
gzip_types text/plain application/javascript application/x-javascript text/css
application/xml text/javascript application/x-httpd-php image/gif image/png;  
gzip_vary on;
#重启Nginx并访问测试:
[root@centos8 ~]# curl --head --compressed http://www.magedu.org/test.html
HTTP/1.1 200 OK
Server: nginx
Date: Fri, 22 Feb 2019 01:52:23 GMT
Content-Type: text/html
Last-Modified: Thu, 21 Feb 2019 10:31:18 GMT
Connection: keep-alive
Keep-Alive: timeout=65
Vary: Accept-Encoding
ETag: W/"5c6e7df6-171109"
Content-Encoding: gzip #压缩传输
#验证不压缩访问的文件大小
压缩功能

 

https 功能

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

https 实现过程如下:
1.客户端发起HTTPS请求:
客户端访问某个web端的https地址,一般都是443端口

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

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

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

5.传送4步骤的加密数据:
就是将用证书加密后的随机值传递给服务器,目的就是为了让服务器得到这个随机值,以后客户端和服务端的
通信就可以通过这个随机值进行加密解密了。

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

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

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

 

https 配置参数

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]替代
listen 443 ssl;
ssl_certificate /path/to/file;
#指向包含当前虚拟主机和CA的两个证书信息的文件,一般是crt文件
ssl_certificate_key /path/to/file;
#当前虚拟主机使用的私钥文件,一般是key文件
ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
#支持ssl协议版本,早期为ssl现在是TLS,默认为后三个
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 

自签名证书

#自签名CA证书
[root@centos8 ~]# cd /apps/nginx/
[root@centos8 nginx]# mkdir certs
[root@centos8 nginx]# cd certs/
[root@centos8 nginx]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout
ca.key -x509 -days 3650 -out ca.crt #自签名CA证书
Generating a 4096 bit RSA private key
.................++
.....
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]:magedu.Ltd #公司名称
Organizational Unit Name (eg, section) []:magedu #部门
Common Name (eg, your name or your server's hostname) []:ca.magedu.org #通用名称
Email Address []: #邮箱
[root@centos8 certs]# ll ca.crt
-rw-r--r-- 1 root root 2118 Feb 22 12:10 ca.crt
#自制key和csr文件
[root@centos8 certs]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout
www.magedu.org.key     -out www.magedu.org.csr
Generating a 4096 bit RSA private key
........................................................................++
......
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]:magedu.org
Organizational Unit Name (eg, section) []:magedu.org
Common Name (eg, your name or your server's hostname) []:www.magedu.org
Email Address []:2973707860@qq.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:      
An optional company name []:
[root@centos8 certs]# ll
total 16
-rw-r--r-- 1 root root 2118 Feb 22 12:10 ca.crt
-rw-r--r-- 1 root root 3272 Feb 22 12:10 ca.key
-rw-r--r-- 1 root root 1760 Feb 22 12:18 www.magedu.org.csr
-rw-r--r-- 1 root root 3272 Feb 22 12:18 www.magedu.org.key
#签发证书
[root@centos8 certs]# openssl x509 -req -days 3650 -in www.magedu.org.csr -CA
ca.crt -CAkey ca.key -CAcreateserial -out www.magedu.org.crt
#验证证书内容
[root@centos8 certs]# openssl x509 -in www.magedu.org.crt -noout -text
Certificate:
   Data:
       Version: 1 (0x0)
       Serial Number:
           bb:76:ea:fe:f4:04:ac:06
   Signature Algorithm: sha256WithRSAEncryption
       Issuer: C=CN, ST=BeiJing, L=Beijing, O=magedu.Ltd, OU=magedu,
CN=magedu.ca/emailAddress=2973707860@qq.com
       Validity
           Not Before: Feb 22 06:14:03 2019 GMT
           Not After : Feb 22 06:14:03 2020 GMT
       Subject: C=CN, ST=BeiJing, L=BeiJing, O=magedu.org, OU=magedu.org,
CN=www.magedu.org/emailAddress=2973707860@qq.com
       Subject Public Key Info:
           Public Key Algorithm: rsaEncryption
               Public-Key: (4096 bit)
                
#合并CA和服务器证书成一个文件,注意服务器证书在前
[root@centos8 certs]#cat www.magedu.org.crt ca.crt > www.magedu.org.pem
自签证书

https 配置

server {
 listen 80;
 listen 443 ssl;
 ssl_certificate /apps/nginx/certs/www.magedu.org.pem;
 ssl_certificate_key /apps/nginx/certs/www.magedu.org.key;
 ssl_session_cache shared:sslcache:20m;
 ssl_session_timeout 10m;
 root /data/nginx/html;
}
#重启Nginx并访问验证

 

升级 OpenSSL 版本

OpenSSL程序库当前广泛用于实现互联网的传输层安全(TLS)协议。心脏出血(Heartbleed),也简 称为心血漏洞,是一个出现在加密程序库OpenSSL的安全漏洞,此漏洞于2012年被引入了软件中, 2014年4月首次向公众披露。只要使用的是存在缺陷的OpenSSL实例,无论是服务器还是客户端,都可 能因此而受到攻击。此问题的原因是在实现TLS的心跳扩展时没有对输入进行适当验证(缺少边界检 查),因此漏洞的名称来源于“心跳”(heartbeat)。该程序错误属于缓冲区过读,即可以读取的数据比 应该允许读取的还多。

 

升级OpenSSL解决安全漏洞

#准备OpenSSL源码包:
[root@centos8 ~]#cd /usr/local/src
[root@centos8 src]#wget https://www.openssl.org/source/openssl-1.1.1h.tar.gz
[root@centos8 src]#tar xvf openssl-1.1.1h.tar.gz
#编译安装Nginx并制定新版本OpenSSL路径:
[root@centos8 ~]#cd /usr/local/src/nginx-1.18.0/
[root@centos8 nginx-1.18.0]#./configure --prefix=/apps/nginx --user=nginx --
group=nginx --with-http_ssl_module --with-http_v2_module --withhttp_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 --withopenssl=/usr/local/src/openssl-1.1.1h

[root@centos8 nginx-1.18.0]#make && make install

#验证并启动Nginx:
[root@centos8 ~]#nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@centos8 ~]#systemctl restart nginx
[root@centos8 ~]#nginx -V
nginx version: wanginx/1.68.9
built by gcc 8.3.1 20191121 (Red Hat 8.3.1-5) (GCC)
built with OpenSSL 1.1.1h  22 Sep 2020
TLS SNI support enabled
configure arguments: --prefix=/apps/nginx --user=nginx --group=nginx --withhttp_ssl_module --with-http_v2_module --with-http_realip_module --withhttp_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream
--with-stream_ssl_module --with-stream_realip_module --addmodule=/usr/local/src/echo-nginx-module --with-openssl=/usr/local/src/openssl1.1.1h
升级OPenssl

 

posted @ 2022-06-04 15:56  goodbay说拜拜  阅读(103)  评论(0编辑  收藏  举报