目录
引言
一、网络状态页
二、Nginx 第三方模块
三、变量
(一)内置变量
(二)自定义变量
四、自定义日志
(一)有关日志的配置信息
(二)error日志的设置
1.日志的等级
2.自定义日志位置及名称
(三)access日志
1.自定义日志格式
五、Nginx压缩功能
(一)开启压缩功能
(二)设置最小压缩文件大小
(三)设置压缩文件类型
(四)开启压缩头部信息
(五)开启预压缩功能
六、自定义图标
七、https功能
(一)功能概述
(二)设置安全证书
1.获取证书文件
2.添加配置文件
在前文中,对Nginx进行了一些论述和基本的操作方法,本文将继续研究Nginx的一些使用方法,对Nginx有一个更深的了解
基于nginx 模块 ngx_http_stub_status_module 实现,在编译安装nginx的时候需要添加编译参数 --with-http_stub_status_module,否则配置完成之后监测会是提示语法错误注意: 状态页显示的是整个服务器的状态,而非虚拟主机的状态
Module ngx_http_status_module
在配置文件中添加stub_status语句,提供的状态信息接口
当访问/statusL时,Nginx将返回一个简单的纯文本响应
#状态页用于输出nginx的基本状态信息:
#输出信息示例:
Active connections: 2
server accepts handled requests
44 44 68
#上面三个数字分别对应accepts,handled,requests三个值
Reading: 0 Writing: 1 Waiting: 1
Active connections:
#当前处于活动状态的客户端连接数,包括连接等待空闲连接数=reading+writing+waiting
accepts:
#统计总值,Nginx自启动后已经接受的客户端请求的总数。
handled:
#统计总值,Nginx自启动后已经处理完成的客户端请求总数,通常等于accepts,除非有因worker_connections限制等被拒绝的连接
requests:
#统计总值,Nginx自启动后客户端发来的总的请求数。
Reading:
#当前状态,正在读取客户端请求报文首部的连接的连接数,数值越大,说明排队现象严重,性能不足
Writing:
#当前状态,正在向客户端发送响应报文过程中的连接数,数值越大,说明访问量很大
Waiting:
#当前状态,正在等待客户端发出请求的空闲连接数,开启 keep-alive的情况下,这个值等于active – (reading+writing)
为了确保安全,通常需要限制只有特定IP地址或子网才能访问此接口。可以使用allow和deny指令来实现这一目的
只有这两个地址的主机可以访问/status
或者增加验证模块更为安全
验证模块的使用方法在上文中讲解过,可以点击下面的链接进行查看
Nginx因其强大的性能和高度可扩展性而广受欢迎,其中一个重要的特性就是支持第三方模块。这些模块是由社区开发者或者企业为增强Nginx功能而编写的,它们提供了诸如HTTP缓存、负载均衡、访问控制、内容过滤、加密传输、WebSocket支持等功能
以下是一些常用的Nginx第三方模块示例
ngx_http_upstream_check_module | 用于检查后端服务器的健康状态。 |
ngx_cache_purge | 允许清除Nginx缓存中的特定URL内容。 |
nginx-module-vts | 提供可视化的实时Nginx虚拟主机流量统计信息。 |
ngx_pagespeed | Google开发的一个模块,用于自动优化网页内容以加快加载速度。 |
ngx_http_auth_request_module | 实现基于子请求进行认证的功能。 |
ngx_http_realip_module | 处理X-Real-IP头部以识别客户端的真实IP地址。 |
nginx-sticky-module-ng | 提供会话持久化(sticky sessions)功能,常用在负载均衡场景中 保持用户与同一后端服务器建立连接。 |
ngx_http_geoip_module | 根据客户端IP地址提供地理位置信息。 |
lua-nginx-module | 集成Lua脚本语言,允许在Nginx中执行自定义逻辑。 |
echo-nginx-module-master | 为Nginx提供在响应中直接输出字符串的能力 |
开源的echo模块:https://github.com/openresty/echo-nginx-module
使用echo模块需要使用GITHUB工具下载,首先安装工具
首先安装git工具:yum install git -y
下载模块
在安装第三方模块的时候需要使用到add模块
--add-module=PATH 是在编译 Nginx 时使用的命令行参数,它允许用户添加自定义或第三方模块到 Nginx 的源码中进行编译。当你要集成像 echo 这样的非标准模块到 Nginx 服务器时,需要使用这个参数指定模块的源代码路径。
在编译之前最好将服务先关闭,防止编译时出现错误,或者不生效
system管理服务使用:systemctl stop nginx关闭服务
使用路径开启服务的使用:killall nginx关闭服务
使用--add-module=模块路径,与已指定的模块一起重新进行编译
这里 --add-module=/path/to/ngx_echo_module 就是将 echo 模块包含进 Nginx 编译过程中的指令。之后执行 make 和 make install 完成编译和安装,新安装的 Nginx 将会包含 echo 模块的功能,并且可以在 Nginx 配置文件中启用和使用该模块提供的指令。
重新编译安装后,会在安装目录下生成新的执行文件,再次开启服务时会自动开启新的程序
执行完make和make install命令后使用nginx -t命令检查以下文件是否有误,而后启动服务
重启服务后就可以使用echo模块了
注意:echo语句只能写在location语句块中,不能写在server语句块中
server {
listen 80;
#指示服务器在标准HTTP端口(80)上监听客户端请求。
server_name www.number.com;
#指定服务器的主机名
root /data/html;
#设置网站的根目录为 /data/html,Nginx将会在这个目录下查找与请求相对应的静态资源文件
location /ip {
#定义了一个特定的location块,匹配所有以/ip结尾的URL路径,如果在下面的location语句块
#中指定root(网站的根目录)。则匹配该目录下的/ip。如果不指定则匹配/data/html/ip/下的URL
echo "welcome to nginx";
#使用了第三方模块ngx_echo_module提供的echo指令,当访问/ip路径时,会在响应中输出字符串
echo "your ip is:$remote_addr";
#使用echo指令,但这次输出的内容包含了变量$remote_addr的值,代表了发起请求的客户端IP地址。
}
}
nginx -t
#检测配置文件格式是否正确,正确会显示syntax is ok
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
nginx -s reload
#重新加载配置文件
使用客户机进行访问
Nginx服务支持变量,可以更好的为服务提供帮助
Nginx提供了一系列内置变量,这些变量可以在配置文件中使用,用于动态生成内容、进行条件判断以及在日志记录、访问控制等场景中发挥作用。以下是一些常用的Nginx变量及其含义:
$remote_addr | 客户端IP地址。 |
$remote_port | 客户端请求Nginx服务器时随机打开的端口,这是每个客户端自己的端口 |
$remote_user | 已经经过Auth_Basic_Module验证的用户名 |
$server_name | 请求的服务器名(域名)。 |
$server_addr | 服务器的IP地址 |
$server_port | 请求的服务器的端口号 |
$request_body_file | 做反向代理时发给后端服务器的本地资源的名称 |
$request_method | HTTP请求方法,如GET、POST等。 |
$request_filename | 当前请求的资源文件的磁盘路径,由root或alias指令与URI请求生成的文件 绝对路径 |
$request_uri | 完整的原始请求URI(不包括主机名和协议头)。 |
$document_root | 当前请求对应的文档根目录路径。 |
$document_uri | 保存了当前请求中不包含参数的URI |
$http_user_agent | 客户端浏览器信息,来自User-Agent头部。 |
$http_referer | 请求来源页面的URL,来自Referer头部。 |
$args | 变量中存放了URL中的参数, 如:http://www.kgc.org/main/index.do?id=20190221&partner=search |
$host | 请求中的Host头部字段值。 |
$status | 响应状态码。 |
$scheme | 请求的协议,例如:http,https,ftp等 |
$server_protocol | 保存了客户端请求资源使用的协议的版本,例如:HTTP/1.1,HTTP/2.0等 |
$content_length | 请求主体内容的长度(如果有)。 |
$request_body | 请求主体的内容。 |
$proxy_add_x_forwarded_for | 此变量表示将客户端IP追加请求报文中X-Forwarded-For首部字段,多个IP之 间用逗号分隔 |
$http_<name> | name为任意请求报文首部字段,表示记录请求报文的首部字段 |
更多的变量使用可以去查看nginx的官方文档:Alphabetical index of variables
使用echo第三方模块将这些变量打印出来
echo $remote_addr; #客户端IP地址为:192.168.83.30
echo $remote_port; #客户端请求Nginx服务器时随机打开的端口为:59184
echo $server_name; #请求的服务器名(域名)为:www.number.com
echo $args; #请求URL中的查询字符串部分,不包括问号“?”:user=china&title=cto
echo $arg_user; #如果请求中包含名为"user"的查询参数,显示其值;否则为空:china
echo $server_addr; #服务器的IP地址为:192.168.83.40
echo $document_root; #当前请求对应的文档根目录路径为:/data/html
echo $document_uri; #当前请求中不包含参数的URI为:/ip
echo $host; #请求中的Host头部字段值为:192.168.83.40(通过域名访问则显示域名)
echo $http_user_agent; #客户端浏览器信息:curl/7.29.0
echo $request_filename;#当前请求的资源文件的磁盘路径:/data/html/ip
echo $scheme; #请求的协议为:http
echo $scheme://$host$document_uri;
#变量集合显示http://192.168.83.40/ipuser=china&title=cto
echo $status; #响应状态码200
Nginx还支持自定义变量,可以通过set指令创建,并且可以结合第三方模块提供更多丰富的变量
其语法为:set $变量名 变量值
使用客户端进行访问
在nginx中可以自定义日志的等级与格式来获取自己想要的信息,加强对日志判断和提取信息的效率,大大减少工作量。
首先打开的nginx服务的主配置文件,看看关于日志的配置信息有哪些
关于非正常日志
logs/表示安装目录下的logs/,在安装nginx时执行的./config --prefix=(安装路径)。
关于正常访问的日志
日志的等级按0-7分为8级,数值越小,等级越高
0 | EMERG(紧急):会导致主机系统不可用的情况 |
1 | ALERT(警告):必须马上采取措施解决的问题 |
2 | CRIT(严重):比较严重的情况 |
3 | ERROR(错误):运行出现错误 |
4 | WARNING(提醒):可能影响系统功能,需要提醒用户的重要事件。 |
5 | NOTICE(注意):不会影响正常功能,但是需要注意的事件 |
6 | INFO(信息):一般信息 |
7 | DEBUG(调试):程序或系统i调试信息等 |
非正常日志默认开启的是第七行:所有级别的非正常日志全部记录,存放目录为相对路径下的logs目录下,文件名称为error.log
当其它用户来访问时,错误的访问信息就会存放在该文件中,通过分析文件内容,来判断错误信息的种类
比如最后一条日志信息
2024/02/24 16:01:43 #日志时间
[error] #错误的日志
117981 #进程PID号,表示访问的是哪一个worker进程
#0 #该工作进程属于第0号工作进程池。Nginx可以配置多个工作进程池,这里"#0"通常意味
#着默认的或者仅有的一个工作进程池。
*16 #﹡代表上下文连接符;16为请求ID
open() "/data/html/xxxxxx" failed #服务器尝试打开路径为/data/html/xxxxxx的文件失败
(2: No such file or directory) #返回状态码为2,即没有这样的文件或目录
client: 192.168.83.30 #请求来自IP地址为192.168.83.30
server: www.number.com #服务器域名
request: "GET /xxxxxx HTTP/1.1" #请求报文
host: "192.168.83.40" #表示客户端在发送HTTP请求时提供的主机头值
可以通过修改该行的信息来修改日志的存放位置级名称
建立日志文件
当有非正常访问时,日志信息就会存到该文件中
也可以在自定义记录日志等级,在文件名后面加上日志等级即可
首先分析一下默认的日志格式
可以看到,日志的格式都是一些变量,结合日志信息,分析一下这些变量
$remote_addr
#记录发起请求的客户端IP地址 (192.168.83.100)。
-
#无特殊含义,直接显示“-”: (-)
$remote_user
#启用了HTTP认证,并且用户成功通过认证,则记录已认证用户的名称;否则为空或- (-)
[$time_local]
#表示请求处理发生的具体时间,用方括号包围。格式为 [日/月(英文)/年:时:分:秒 时区:+0800,即
#东八区(北京时间) ( [21/Feb/2024:11:10:03 +0800] )
$request
#记录完整的HTTP请求行 (GET / HTTP/1.1)
$status
#状态码 (200)
$body_bytes_sent
#服务器向客户端发送的响应主体内容字节数 (612)
$http_referer
#记录请求的来源URL,即referrer字段,表示用户是从哪个页面跳转过来的如果存在,则显示其值,
#不存在显示“-” (-)
$http_user_agent
#记录发起请求的客户端的浏览器信息,即User-Agent头部的值。 ( curl/7.29.0 )
$http_x_forwarded_for
#记录客户端IP地址链,当请求经过了多个代理时,这个头部会记录所有代理服务器的IP地址,从最
#开始的客户端到当前服务器。如果请求直接来自客户端,则值为空或“-”
可以自定义日志格式,在原本的日志格式上加上
$server_name:服务器域名
$server_port :服务器端口
重新加载配置文件后,会自动生成日志文件
使用客户端访问后查看日志信息
可以看到,比默认的日志多了一些信息
自定义json 格式日志
日志格式可以设定多个,但只能调用一个
下面来分析以下该日志格式的含义
"@timestamp":"$time_iso8601"
#请求发生的时间戳,格式为ISO 8601 ( "@timestamp":"2024-02-24T17:18:26+08:00" )
"host":"$server_addr"
#host: 服务器本身的IP地址 ( "host":"192.168.83.40" )
"clientip":"$remote_addr"
#clientip: 客户端IP地址 ( "clientip":"192.168.83.30" )
"size":"$body_bytes_sent"
#size:服务器发送给客户端的响应体字节数 ( "size":"11" )
"responsetime":"$request_time"
#responsetime: Nginx处理整个请求所花费的时间,包括连接建立、等待后端响应等)
# ( "responsetime":"0.000" )
"upstreamtime":"$upstream_response_time"
#upstreamtime: 后端服务器响应请求所需的时间,仅在使用proxy_pass时有效。其它则显示为 “-”
# ( "upstreamtime":"-" )
"upstreamhost":"$upstream_addr"
#upstreamhost: 后端服务器的地址和端口,仅在使用proxy_pass时有效。其它则显示为 “-”
# ( "upstreamhost":"-" )
"http_host":"$host"
#http_host: 请求中的Host头部值。 ( "http_host":"192.168.83.40" )
"uri":"$uri"
#uri: 请求的URI部分,不包含协议、主机名或查询字符串 ( "uri":"/index.html" )
"xff":"$http_x_forwarded_for"
#xff: 如果存在,则是HTTP头部X-Forwarded-For的值,用于记录请求经过的所有代理IP地址。
#不存在,则不显示或显示“-” ( "xff":"-" )
"referer":"$http_referer"
#referer: 请求的来源URL,如果存在则显示其值。不存在,则不显示或“-” ( "referer":"-" )
"tcp_xff":"$proxy_protocol_addr"
#tcp_xff: 在启用proxy_protocol时,该字段记录TCP层的原始客户端IP地址,适用于在负载
#均衡器或其他前端设备之后使用proxy_protocol协议的情况 ( tcp_xff":"-" )
"http_user_agent":"$http_user_agent"
#客户端的浏览器信息发送 ( "http_user_agent":"curl/7.29.0" )
"status":"$status}"
#status":"返回状态码 ( "status":"200" )
这样可以通过脚本或直接使用命令提取日志中的状态信息,从而分析日志中可能存在的问题
支持对指定类型的文件进行压缩然后再传输给客户端,而且压缩还可以设置压缩比例,压缩后的文件大小将比源文件显著变小,这样有助于降低出口带宽的利用率,降低企业的IT支出,不过会占用相应的CPU资源。Nginx对文件的压缩功能是依赖于模块 ngx_http_gzip_module
官方文档: Module 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;
#预压缩,先压缩好,不用临时压缩,消耗cpu
gzip_static on | off;
开启压缩功能并设置压缩等级
在站点目录下建立稍大一点的文件
linux中的curl浏览器是文字版的浏览器,并不支持压缩功能,所以需要谷歌,360图形界面的浏览器
使用谷歌浏览器访问页面时,按F12查看访问信息,如果没有出现,或状态码为非200时,
按 ctrl + 刷新键,强制刷新
调高压缩等级再次查看
等级越高,压缩后的文件越小
小于1k的文件,可能压缩后会变大,所以需要设置最小的压缩值
原文件大小为1.1K,压缩后文件大小为1.3K
设置配置文件:gzip_min_length 限制压缩最小文件大小
默认只压缩test//html类型的文件,其它文件不压缩
在站点目录下新建一个test/css类型的文件
使用浏览器访问时并不会压缩
需要手动添加压缩文件类型
需要注意的是,nginx的压缩功能并不支持图片压缩,即使添加完压缩类型后也不可以
可以看到,文件还是其本身大小,并没有进行压缩
作用是指示Nginx在响应头中添加 Vary: Accept-Encoding 字段。
当浏览器或其他HTTP客户端向服务器发送请求时,它们可能会在请求头中包含 Accept-Encoding 字段,以告知服务器它们支持哪些内容编码方式,如gzip、deflate等。
启用 gzip_vary on; 可以帮助优化具有代理缓存机制的Web应用性能,并确保不同类型的客户端都能获得最佳体验
当使用浏览器访问时就会看到该头部信息
在Nginx中,可以启用静态资源的预压缩功能以进一步提高网站性能。预压缩是指在文件被请求之前就预先对其压缩并存储在服务器上,这样当客户端请求时,可以直接发送已压缩的内容,无需在处理请求时实时进行压缩,这样会减少每次访问时,对CPU的消耗。
在配置文件中添加:gzip_static on 表示开启预先压缩功能
手动将文件进行压缩
这时候再去访问的话,就会显示压缩好的文件大小,
favicon.ico 文件是浏览器收藏网址时显示的图标,当客户端使用浏览器问页面时,浏览器会自己主动发起请求获取页面的favicon.ico文件,但是当浏览器请求的favicon.ico文件不存在时,服务器会记录404日志,而且浏览器也会显示404报错
Nginx配置中不需要专门针对favicon.ico做特殊配置,因为浏览器会自动请求该资源。但为了确保Nginx能够正确处理对/favicon.ico的请求,你需要确认对应的location块已经允许了静态文件的访问
将需要设置为图标的图片名更改为favicon.ico
再去访问的时候就会看到自定义的图标信息
Web网站的登录页面都是使用https加密传输的,加密数据以保障数据的安全,HTTPS能够加密信息,以免敏感信息被第三方获取,所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用HTTPS协议,因为HTTP协议是明文传输协议,可以通过抓包工具,获取登录的用户名和密码信息,非常不安全。
HTTPS其实是有两部分组成:HTTP + SSL / TLS,也就是在HTTP上又加了一层处理加密信息的模块。服务端和客户端的信息传输都会通过TLS进行加密,所以传输的数据都是加密后的数据。
1.客户端发起HTTPS请求
用户在浏览器里输入一个https网址,然后连接到服务器的443端口
2.服务端的配置
采用HTTPS协议的服务器必须要有一套数字证书,可以自己制作,也可以向组织申请。区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面。这套证书其实就是一对公钥和私钥
3.传送服务器的证书给客户端
证书里其实就是公钥,并且还包含了很多信息,如证书的颁发机构,过期时间等等
4.客户端解析验证服务器证书
这部分工作是由客户端的TLS来完成的,首先会验证公钥是否有效,比如:颁发机构,过期时间等等,如果发现异常,则会弹出一个警告框提示证书存在问题。如果证书没有问题,那么就生成一个随机值。然后用证书中公钥对该随机值进行非对称加密
5.客户端将加密信息传送服务器
这部分传送的是用证书加密后的随机值,目的就是让服务端得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值来进行加密解密了
6.服务端解密信息
服务端将客户端发送过来的加密信息用服务器私钥解密后,得到了客户端传过来的随机值
7.服务器加密信息并发送信息
服务器将数据利用随机值进行对称加密,再发送给客户端
8.客户端接收并解密信息
客户端用之前生成的随机值解密服务段传过来的数据,于是获取了解密后的内容
查看百度的SSL证书
查看自己的web服务时,因为没有获取SSL证书,所以会显示自己的网址是不安全的
nginx 的https 功能基于模块ngx_http_ssl_module实现,因此如果是编译安装的nginx要使用参数ngx_http_ssl_module开启ssl功能,但是作为nginx的核心功能,yum安装的nginx默认就是开启的,编译安装的nginx需要指定编译参数--with-http_ssl_module开启
官方文档:Module ngx_http_ssl_module
SSL证书获取方式
获取SSL证书:可以从权威的CA(证书颁发机构)购买或获取免费的SSL证书(如Let's Encrypt)。
生成私钥和CSR(证书签名请求),并提交给CA以获取证书。
新建一个目录用于存放证书文件
ca.crt
#这是一个根证书或中级证书颁发机构(CA)的证书文件。
ca.key
#相应于ca.crt的私钥文件,通常不用于服务器配置,除非特定场景需要验证中间CA。
certificate.sh
#脚本文件,用于生成或更新证书。
china.com.crt
#这是为中国域名china.com签发的SSL证书文件。
china.com.csr
#这是China.com域名的证书签名请求(CSR)文件,它在申请证书时创建。
china.com.key
#对应于china.com域名的私钥文件。
cat china.com.crt ca.crt > www.china.com.crt
#使用cat命令将china.com.crt和ca.crt两个文件的内容合并到一个新文件www.china.com.crt中
#这样做的目的是为了组合服务器证书和CA证书,使得Nginx或任何其他Web服务器能够通过单一文件
#提供完整的证书链给客户端,以便正确验证服务器证书。
mv china.com.key www.china.com.key
#使用 mv 命令重命名china.com.key为www.china.com.key。
#为了与上面合并后的证书文件保持名称一致性,或者准备为www.china.com子域名服务使用同一密钥对。
listen 443 ssl;
#这行指定Nginx监听443端口,并启用SSL支持。Web浏览器默认通过443端口建立HTTPS连接
ssl_certificate /apps/nginx/conf.d/SSL/www.china.com.crt;
#指定SSL证书文件的路径,这个路径指向合并了服务器证书和CA证书链的文件(如果适用),以
#便客户端在验证服务器身份时使用。
ssl_certificate_key /apps/nginx/conf.d/SSL/www.china.com.key;
#指定与上述证书匹配的私钥文件路径。此私钥用于加密和解密服务器与客户端之间的通信内容
ssl_session_cache shared:sslcache:20m;
#配置一个共享的SSL会话缓存,大小为20MB。该缓存可以提高性能,通过复用已存在的SSL会话
#信息来减少重新协商和加密操作的开销
ssl_session_timeout 10m;
#设置SSL会话超时时间为10分钟。这意味着,在无活动期间达到这个时间长度后,客户端必须与
#服务器重新建立新的SSL会话或者恢复先前的会话(如果仍然有效)。这个值可以根据实际需求调
#整以平衡安全性与性能。
使用https协议进行访问
可以看到,它会提示不是私密连接,因为ssl证书是自己生成的,没有经过组织认证
如果想要继续访问,可以点击高级,而后继续浏览该网页,就可以进入查看信息了