Nginx(二)

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
$args存放了URL中的所有参数。http://www.wang.com/index.do?id=12345&partner=search则,返回结果为id=12345&partner=search
$is_args如果有参数为? 否则为空
$document_root当前请求资源的根路径
$document_uri和$uri相同,保存了当前请求中不包含参数的URI
$host请求信息中的Host,若请求信息中无Host行,则等于设置的服务器名
$limit_rate显示limit_rate配置的网络速率,若没有配置,则显示0
$remote_port客户端请求Nginx服务器时随机打开的端口,这是每个客户端自己的端口
$remote_user已经经过Auth Basic Module验证的用户名
$request_body_file做反向代理时发给后端服务器的本地资源的名称
$requset_method请求的方法,比如get,post,delete
$request_filename当前请求的资源文件的磁盘路径,由root或alias指令与URI请求生成的文件绝对路径
$request_uri全路径,包含请求参数的原始URI,包含查询字符串,不包含主机名,相当于:documenturi?documentu​ri?args
$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_namename为任意请求报文首部字部cookie的key名
$http_namename为任意请求报文首部字段,表示记录请求报文的首部字段,name的对应的首部字段名需要为小写,如果有横线需要替换为下划线
$sent_http_name#name为响应报文的首部字段,name的对应的首部字段名需要为小写,如果有横线需要替换为下划线,此变量有问题
$arg_name存放了URL中的指定参数,name为请求url中指定的参数
$uri和$document_uri相同
location /main {
	index index.html;
	default_type text/html;
    echo "hello world,main-->";
	echo $remote_addr;
	echo $binary_remote_addr;
	echo $args;
	echo $document_root;
	echo $document_uri;
	echo $host;
	echo $http_user_agent;
	echo $http_cookie;
	echo $cookie_title;
	echo $request_filename;
	echo $scheme;
	echo $scheme://$host$document_uri?$args;
}

curl -b 'title=ceo;user=wang' --output - 'http://www.wang.org/main/index.do?id=20190221&partner=search'
hello world,main-->
10.0.0.6

id=20190221&partner=search
/apps/nginx/html
/main/index.do
www.wang.org
curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
title=ceo
ceo
/apps/nginx/html/main/index.do
http
http://www.wang.org/main/index.do?id=20190221&partner=search

自定义变量

语法:
Syntax: set $variable value;
Default: —
Context: server, location, if

set $name wang;
echo $name;
set $my_port $server_port;
echo $my_port;
echo "$server_name:$server_port";

curl www.wang.org/main
wang
80
www.wang.org:80

日志模块

简介

Nginx有非常灵活的日志记录模式。每个级别的配置可以有各自独立的访问日志;日志格式通过log_format命令定义。

模块:Module ngx_http_log_module

访问日志 是记录客户端的具体请求内容信息,可以在不同的server中定义多个,定义一个日志需要使用access_log指定日志的保存路径,使用log_format指定日志的格式,格式中定义要保存的具体日志信息。

error_log 是记录nginx服务运行时的日志保存路径和记录日志的level,一般只有一个。

模块:http://nginx.org/en/docs/http/ngx_http_log_module.html

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 compression '$remote_addr - $remote_user [$time_local] '
                       '"$request" $status $bytes_sent '
                       '"$http_referer" "$http_user_agent" "$gzip_ratio"';

access_log /spool/logs/nginx-access.log compression buffer=32k;

日志格式常见变量

变量说明
$remote_addr记录客户端IP地址
$remote_user记录客户端用户名
$time_local记录通用的本地时间
$time_iso8601记录ISO8601标准格式下的本地时间
$request记录请求的方法以及请求的http协议
$status记录请求状态码(用于定位错误信息)
$body_bytes_sent发送给客户端的资源字节数,不包括响应头的大小
$bytes_sent发送给客户端的总字节数$msec;表示日志写入时间。单位为秒,精度是毫秒
$http_referer记录从哪个页面链接访问过来的
$http_user_agent记录客户端浏览器相关信息
$http_x_forwarded_for记录客户端IP地址
$request_length请求的长度(包括请求行,请求头和请求正文)
$request_time请求花费的时间,单位为秒,精度毫秒

如果Nginx位于负载均衡器,nginx反向代理之后,web服务器无法直接获取到客户端真实的IP地址。$remote_addr获取的是反向代理的IP地址,反向代理服务器在转发请求的http头信息中增加X-Forwarded-For信息,用来记录客户端IP地址和客户端请求的服务器地址。

自定义默认日志格式

#此指令支持http{},不支持server{}
log_format  cs_log  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"'
                  '$server_name:$server_port';


access_log  logs/access.log  cs_log;	#此指令必须位于log_format后面

[root@wenzi conf.d]#tail -f /apps/nginx/logs/access.log
192.168.28.1 - - [19/Feb/2024:02:42:06 +0800] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0" "-"www.wenzi.com:80

自定义json格式日志

生产中常将nginx日志转换为json日志,配合ELK做日志收集,统计分析

[root@wenzi conf.d]#vim ../nginx.conf
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  logs/access_json.log  access_json;


[root@wenzi conf.d]#tail -f /apps/nginx/logs/access_json.log
{"@timestamp":"2024-02-19T02:56:14+08:00","host":"192.168.28.60","clientip":"192.168.28.1",  "size":0,"responsetime":0.000,"upstreamtime":"-","upstreamhost":"-", "http_host":"www.wenzi.com","uri":"/index.html","xff":"-","referer":"-","tcp_xff":"-",  "http_user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0","status":"304"}

利用工具更改下json显示方式
{
  "@timestamp": "2024-02-19T02:56:14+08:00", #记录请求的ISO 8601格式的时间戳。
  "host": "192.168.28.60",					 #记录处理请求的服务器地址。
  "clientip": "192.168.28.1",				 #记录发出请求的客户端的IP地址。
  "size": 0,								 #记录发送给客户端的响应体的大小(以字节为单位)。
  "responsetime": 0.000,					 #记录从接收请求到发送完响应所花费的时间(以秒为单位)。
  "upstreamtime": "-",						 #若请求被代理到后端服务器,记录后端服务器处理请求所花的时间(以秒为单位)。
  "upstreamhost": "-",						 #如果请求被代理到后端服务器,记录后端服务器的地址。
  "http_host": "www.wenzi.com",				 #录请求头中的Host字段		
  "uri": "/index.html",						 #记录请求的URI。
  "xff": "-",								 #当请求经过代理或负载均衡器,通常用于标识原始客户端的IP地址。
  "referer": "-",							 #记录请求头中的Referer字段,表示发出请求的页面的URL。
  "tcp_xff": "-",							 #如果使用了PROXY协议,记录PROXY协议中的客户端地址。
  #记录请求头中的User-Agent字段,表示发出请求的客户端的类型和版本
  "http_user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0",
  "status": "304"							 #记录HTTP响应的状态码,例如200、404等
}

json格式日志访问统计

#python3
[root@centos8 ~]#dnf -y install python3
[root@centos8 ~]#cat log.py
#!/usr/bin/env python3
#coding:utf-8
#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)

运行Python
[root@centos7 ~]# python nginx_json.py
状态码200的有--: 1910
状态码404的有--: 13

#转换python2语法到python3
[root@centos8 ~]#pip3 install 2to3
[root@centos8 ~]#2to3 -w log.py

不记录访问日志

一个网站会包含很多元素,尤其是有大量的images、js、css等静态资源。这样的请求可以不用记录日志

# ~* 包含正则表达式,不区分大小写。
location ~* .*\.(gif|jpg|png|css|js)$ {
   access_log /dev/null;
}

日志缓存

简介

大量访问到来时,对于每一条日志记录,都将是先打开文件,再写入日志,然后关闭.占用了系统的IO,与业务无关。可以使用open_log_file_cache来设。

默认是关闭日志缓存的。

示例

open_log_file_cache max=1000 inactive=20s min_uses=3 valid=1m;

max=1000指日志文件的FD,最大缓存数量为1000

inactive=20s min_uses=3指20秒内小于3次访问的FD就清除

vaild 1m指检查周期为1分钟

总结:缓存最多1000个,到了极限,每分钟开始清除掉  20秒内小于3次的文件FD

日志轮转

nginx安装后默认启动日志轮转。路径:/etc/logrotate.d/nginx

查看日志轮转设置

[root@wzy ~]#cat /etc/logrotate.d/nginx 
/var/log/nginx/*.log {  #待切割的日志,以.log结尾的日志都切割
        daily  #天
        missingok  #丢失不提示
        rotate 52  #保存日志数量
        compress  #压缩
        delaycompress  #解压
        notifempty   #空文件的话不保存
        create 640 nginx adm  #新创建的日志文件属主属组
        sharedscripts  #轮转后执行的脚本
        postrotate
                if [ -f /var/run/nginx.pid ]; then
                        kill -USR1 `cat /var/run/nginx.pid`  #USR1通常来告知应用程序重载配置文件
                fi
        endscript
}

WEB模块

连接状态页——stub_status_module

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

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

模块:http://nginx.org/en/docs/http/ngx_http_stub_status_module.html

Syntax:stub_status;
Default:
Context:server, location
[root@wenzi conf.d]#cat wenzi.com.conf
server {
    listen 80 default_server;
    server_name www.wenzi.com;
    location / {
        root /apps/nginx/html;
        index index.html;
    }
    location /status {
        stub_status;
    }
}

[root@wenzi ~]#curl http://www.wenzi.com/status
Active connections: 1
server accepts handled requests
 370 370 495	#这三个数分别对应 accepts handled requests
Reading: 0 Writing: 1 Waiting: 0

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

第三方模块

第三模块是对nginx 的功能扩展,第三方模块需要在编译安装Nginx 的时候使用参数–addmodule=PATH指定路径添加。

nginx的第三方模块需要从源码重新编译进行支持

nginx-modules-vts模块实现流量监控

地址:https://github.com/vozlt/nginx-module-vts

[root@wenzi conf.d]#cd /usr/local/src/
[root@wenzi src]#git clone git://github.com/vozlt/nginx-module-vts.git
[root@wenzi src]#cd nginx-1.22.1/
[root@wenzi nginx-1.22.1]#./configure --prefix=/apps/nginx --addmodule=/usr/local/src/nginx-module-vts
[root@wenzi nginx-1.22.1]#make && make install
[root@wenzi nginx-1.22.1]#vim /apps/nginx/conf/nginx.conf
http {
	......
	vhost_traffic_status_zone;
	......
	server {
		......
		location /status {
			vhost_traffic_status_display;
 			vhost_traffic_status_display_format html; #默认不加此行,是Json格式
		}
		......
	}
}

必须重启nginx服务,不支持reload;浏览器访问 http://<nginx_ip>/status 可见

在这里插入图片描述

echo-nginx-module实现信息打印

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

[root@centos8 ~]#cd /usr/local/src
#github网站国内访问不稳定,可能无法下载
[root@centos8 src]#git clone https://github.com/openresty/echo-nginx-module.git
#如果上面链接无法下载,可以用下面链接
#[root@centos8 src]#git clone https://github.com.cnpmjs.org/openresty/echonginx-module.git
[root@centos8 src]#cd nginx-1.22.1/
[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服务,不支持reload
[root@centos7 ~]#curl http://www.wang.org/main
hello world,main-->
10.0.0.7
sub1
sub2
took 2.003 sec for total.

随机主页——random_index_module

作用:将主页设置为随机页面,是一种微调机制

实验

启动随机主页

#编辑/wzy/2.html和/wzy/.3.html
[root@wzy ~]#vim /wzy/2.html 
2.html is me!
[root@wzy ~]#vim /wzy/.3.html 
This is 3.html
#修改wzy.com配置文件
[root@wzy ~]#vim /etc/nginx/conf.d/wzy.conf 
server {
	listen 80;
	server_name wzy.com;
#去掉重复的无意义日志
	location = /favicon.ico {
		log_not_found off;
		access_log off;
	}

	location / {
		root /wzy;
#		index index.html;
#随机主页
		random_index on;
	}
#自定义错误页面
	error_page 404 /404.html;
	location = /404.html {
		root /wzy;	
	}
}

#重启nginx
[root@wzy ~]#systemctl restart nginx

重启nginx后多次访问wzy.com,会出现随机主页,但.3.html不会出现,隐藏文件不会被随机读取。

  

替换模块——sub_module

作用:网页内容替换

实验

修改nginx默认页面配置文件

[root@wzy ~]#vim /etc/nginx/conf.d/default.conf

server {
    listen       80;
    server_name  localhost;

    #access_log  /var/log/nginx/host.access.log  main;

    sub_filter nginx 'WWZZYY';  #替换内容
    sub_filter_once on;  #on为单次替换;off为全文替换
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
...

 重启nginx,访问nginx默认主页,只有网页title变化

 再次修改默认主页配置文件,将sub_filter_once on 改为 off,重启nginx,访问默认主页,全部都被替换

文件读取模块——ngx_http_core_module

语法

Syntax:sendfile on | off;
Default:
sendfile off;
Context:httpserverlocationif in location

解析

未使用sendfile()的传统网络传输过程:

 

硬盘>kernel buffer>user buffer>kernel buffer>socket buffer>协议栈

使用sendfile()的网络传输过程:

硬盘>kernel buffer(快速拷贝到kernel或socketbuffer)>协议栈

sendfile()不但能减少切换次数还能较少拷贝次数

语法

Syntax:tcp_nopush on | off;
Default:
tcp_nopush off;
Context:httpserverlocation

 解析

未使用tcp_nopush()网络资源浪费:

应用程序每产生一次操作就会发送一个包,而典型情况下一个包会拥有一个字节的数据以及40个字节长的包头,于是产生4000%的过载,很轻易地就能令网络发生拥塞。同时也浪费资源。

使用tcp_nopush()网络传输效率提升:

当包累计到一定大小后再发送。

语法

Syntax:tcp_nodelay on | off;
Default:
tcp_nodelay on;
Context:httpserverlocation

解析

开启或关闭nginx使用TCP_NODELAY选项的功能。 这个选项仅在将连接转变为长连接的时候才被启用。
TCP_NODELAY是禁用Nagle算法,即数据包立即发送出去。
由于Nagle和DelayedACK的原因,数据包的确认信息需要积攒到两个时才发送,长连接情况下,奇数包会造成延时40ms,所以tcp_nodelay会将ack立刻发出去。 如果不在长连接时,可以关闭此模块,因为ack会被立刻发出去。

关于location匹配规则

符号说明
/通用匹配,任何请求都会匹配
=对URI精确匹配
^~对URI最左边部分匹配,不区分大小写
~对URI正则表达式匹配,区分大小写
~*对URI正则表达式匹配不区分大小写

优先级从高到低:

=   ^~   ~~*!~!~*   /

重定向——ngx_http_rewrite_module

作用:URL伪静态化,将动态页面显示为静态页面的一种技术。隐藏源网站链接信息,实现跳转,提高安全。

语法

Syntax:rewrite regex replacement [flag];
Default:
Context:serverlocationif

解析

将用户请求的URI基于regex所设定的模式进行检查,匹配到时将其替换为replacement指定新的URI。

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

[flag]:

last:重写完成后停止对当前URI在当前location中后续的其它重写操作,而后对新的URI启动新一轮重写检查;提前重启新一轮循环,不建议在location中使用

break:重写完成后停止对当前URI在当前location中后续的其它重写操作,而后直接跳转至重写规则配置块之后的其它配置;结束循环,建议在location中使用

redirect:临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求;使用相对路径,或者http://或https://开头,状态码:302

permanent:重写完成后以永久重定向方式直接返回重写后生成的新URI给客户端,由客户端重新发起请求,状态码:301

Syntax:if (condition) { ... }
Default:
Context:serverlocation

解析

 满足条件时执行配置块中的指令。

condition:

=相同
!=不同
~正则匹配,区分大小写
~*正则匹配,不区分大小写
!~非正则匹配,区分大小写
!~*

非正则匹配,不区分大小写

-e存在(包含文件、目录、软链接)
!-e不存在(包含文件、目录、软链接)
-f文件存在
!-f文件不存在
-d目录存在
!-d目录不存在
-x可执行
!-x不可执行

文件压缩——ngx_http_gzip_module

作用:文件传输前进行压缩,提升传输效率

语法

Syntax:gzip on | off;
Default:
gzip off;
Context:httpserverlocationif in location
Syntax:gzip_comp_level level;
Default:
gzip_comp_level 1;
Context:httpserverlocation
Syntax:gzip_http_version 1.0 | 1.1;
Default:
gzip_http_version 1.1;
Context:httpserverlocation
#启用或禁用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;

 实验

创建文本文件/wzy/11.txt,打开浏览器观察压缩前后大小

#创建11.txt文件
[root@wzy ~]#cat /var/log/messages > /wzy/11.txt
[root@wzy ~]#ll /wzy/11.txt 
-rw-r--r-- 1 root root 1867803 May 11 05:29 /wzy/11.txt
#修改配置http{}部分
[root@wzy wzy]#vim /etc/nginx/nginx.conf
...
    keepalive_timeout  65;
    #启用压缩
    gzip  on;
    #设置压缩响应所需的请求的最低 HTTP 版本
    gzip_http_version 1.1;
    #压缩级别
    gzip_comp_level 9;
    #压缩的类型
    gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg;
    #静态文件处理模块
    gzip_static on;
    include /etc/nginx/conf.d/*.conf;
...

重启nginx,打开浏览器F12观察11.txt文件大小

 页面缓存模块——ngx_http_headers_module

Module ngx_http_headers_module官方文档:Module ngx_http_headers_module

作用:合理的控制缓存可以减少服务器压力

语法

Syntax:expires [modifiedtime;
expires epoch | max | off;
Default:
expires off;
Context:httpserverlocationif in location

 解析

无缓存时,每次访问服务器都是全文传输。开启缓存可以加速浏览网站

开启缓存,第一次访问某网页时,返回状态码200,页面对象全文传输;第二次访问返回状态码304,页面对象部分传输;禁用缓存,每次访问状态码都是200。

实验

开启nginx服务器缓存

[root@wzy ~]#vim /etc/nginx/conf.d/default.conf

...

location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        expires 1m;
    }

...

重启nginx,访问默认主页,观察状态码 

 

防盗链——ngx_http_referer_moudle

介绍

日志格式中的$http_referer是记录访问点引用的URL,即超链接的上一级地址。通过这段地址可以发现一种网络行为:盗链。非法盗链会影响站点的正常访问,通过此模块可以控制。

语法

Syntax:valid_referers none | blocked | server_names | string ...;
Default:
Context:serverlocation
none    #请求报文首部没有referer首部,比如用户直接在浏览器输入域名访问web网站,就没有referer信息。
blocked    #请求报文有referer首部,但无有效值,比如为空。
server_names    #referer首部中包含本主机名及即nginx 监听的server_name。
arbitrary_string    #自定义指定字符串,但可使用*作通配符。示例: *.wang.org www.wang.*
regular expression    #被指定的正则表达式模式匹配到的字符串,要使用~开头,例如:~.*\.wang\.com

实验

在wzy.com主页显示一张图片pic1.jpg;mzh.com主目录没有图片,通过引用wzy.com主页图片显示图片,形成盗链。

[root@wzy ~]#cat /etc/nginx/nginx.conf 
...
    keepalive_timeout  65;
    gzip  on;
    gzip_static on;  #nginx加载静态资源模块
...
#设置wzy.com
[root@wzy ~]#cat /etc/nginx/conf.d/wzy.conf 
server {
	listen 80;
	server_name wzy.com;
#将wzy.com网站日志单独存储,名称为wzy.com.access.log
    access_log  /var/log/nginx/wzy.com.access.log  main;
#去掉重复的无意义日志
	location = /favicon.ico {
		log_not_found off;
		access_log off;
	}

	location / {
		root /wzy;
		index index.html;
#随机主页
#		random_index on;
	}
#自定义错误页面
	error_page 404 /404.html;
	location = /404.html {
		root /wzy;	
	}
}

[root@wzy ~]#ls /wzy/
404.html  index.html  index.html.bak  pic1.jpg
[root@wzy ~]#vim /wzy/index.html
hello word
<img src='pic1.jpg' />

#设置mzh.com
[root@wzy ~]#vim /etc/nginx/conf.d/mzh.conf 
server {
	listen 80;
	server_name mzh.com;
#将mzh.com网站日志单独存储,名称为mzh.com.access.log
    access_log  /var/log/nginx/mzh.com.access.log  main;
#去掉重复的无意义日志
	location = /favicon.ico {
		log_not_found off;
		access_log off;
	}

	location / {
		root /mzh;
		index index.html;
#随机主页
#		random_index on;
	}
}

[root@wzy ~]#mkdir /mzh
[root@wzy ~]#vim /mzh/index.html 
<img src='http://wzy.com/pic1.jpg' />


 当访问mzh.com时,mzh.com日志内容如下,正常。

[root@wzy ~]#tail -f /var/log/nginx/mzh.com.access.log 
192.168.29.1 - - [11/May/2023:19:55:31 +0800] "GET / HTTP/1.1" 200 69 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36" "-"

wzy.com日志内容如下,不正常。$http_referer出现其它地址,即用户是从其它网站访问到图片

[root@wzy ~]#tail -f /var/log/nginx/wzy.com.access.log 

192.168.29.1 - - [11/May/2023:19:55:31 +0800] "GET /pic1.jpg HTTP/1.1" 200 151890 "http://mzh.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36" "-"

当访问wzy.com时,wzy.com日志内容如下,正常

[root@wzy ~]#tail -f /var/log/nginx/wzy.com.access.log 

192.168.29.1 - - [11/May/2023:20:04:49 +0800] "GET /pic1.jpg HTTP/1.1" 200 151890 "http://wzy.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36" "-" 

启动wzy.com防盗链功能,再次访问mzh.com,无法显示图片,盗链失败。

[root@wzy ~]#cat /etc/nginx/conf.d/wzy.conf 
...

    location / {
        root /wzy;
        index index.html;

#server_name即白名单,将wzy.com自身设为允许
        valid_referers none blocked *.wzy.com server_name wzy.com;
        if ($invalid_referer) {
            return 403;
        }
    }
...

如希望某些网站可以使用盗链,在server_name写入即可

valid_referers none blocked *.wzy.com server_name wzy.com;

再次访问mzh.com盗链,合法盗链成功

 访问控制

基于主机

模块:Module ngx_http_access_module

尽量在防火墙设备控制,最好不要在nginx配置,节约资源Module ngx_http_access_module

分类

allow——允许某些主机

Syntax:allow address | CIDR | unix: | all;
Default:
Context:httpserverlocationlimit_except

deny——拒绝某些主机

Syntax:deny address | CIDR | unix: | all;
Default:
Context:httpserverlocationlimit_except

实验

允许192.168.29.141访问http://192.168.29.141;禁止192.168.29.1及其它IP访问

[root@wzy ~]#cat /etc/nginx/conf.d/default.conf 
server {
    listen       80;
    server_name  localhost;
    allow 192.168.29.141;
   #allow 192.168.29.1;
    deny all;
    #access_log  /var/log/nginx/host.access.log  main;
...

在192.168.29.141测试,正常

[root@wzy ~]#curl http://192.168.29.141/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

...

在192.168.29.1(真机)浏览器访问,访问拒绝

[root@wenzi conf.d]$cat wenzi.com.conf
server {
    listen 80 default_server;
    server_name www.wenzi.com;
    root /apps/nginx/html;
    index index.html index.htm;
    location /about {
        alias /apps/nginx/html/msg;
        index msg.html;
        deny 192.168.28.61;
        allow 192.168.28.60;
        allow 192.168.28.0/24;
        allow 172.16.0.0/16;
        deny all;
    }
}

写规则时:小范围在前,大范围在后

基于用户username/password

模块:Module ngx_http_auth_basic_module

Syntax:auth_basic string | off;
Default:
auth_basic off;
Context:httpserverlocationlimit_except
Syntax:auth_basic_user_file file;
Default:
Context:httpserverlocationlimit_except

实验

htpasswd是apache生成秘钥的工具。

参数及说明
-b    密码直接写在命令行中,而非使用提示输入的方式
-c    创建密码文件,若文件存在,则覆盖文件重新写入
-n    不更新密码文件,将用户名密码进行标准输出
-m    使用MD5算法对密码进行处理
-d    使用CRYPT算法对密码进行处理
-s    使用SHA算法对密码进行处理
-p    不对密码进行加密处理,使用明文密码
-D    从密码文件中删除指定用户记录

#安装加密工具
[root@wzy ~]#yum -y install httpd-tools

#创建加密文件并创建用户
[root@wzy ~]#htpasswd -cm /etc/nginx/conf.d/passwd user10
New password: 
Re-type new password: 
Adding password for user user10

#向加密文件中添加用户
[root@wzy ~]#htpasswd -m /etc/nginx/conf.d/passwd user20
New password: 
Re-type new password: 
Adding password for user user20


#查看加密文件
[root@wzy ~]#cat /etc/nginx/conf.d/passwd 
user10:$apr1$WZYQq52s$/i/T7D8m0TnOGCLUKfRMS0
user20:$apr1$fhaqcCKt$6WczaJM5Ur6KOvA4swAKK/

#使用加密文件
[root@wzy ~]#vim /etc/nginx/conf.d/wzy.conf 
server {
	listen 80;
	server_name wzy.com;
#输入用户密码弹窗提示文本
	auth_basic "This is wzy.com";
#引用加密文件
	auth_basic_user_file /etc/nginx/conf.d/passwd;
#单独存储wzy.com的日志
    access_log  /var/log/nginx/wzy.com.access.log  main;
#去掉重复的无意义日志
	location = /favicon.ico {
		log_not_found off;
		access_log off;
	}

	location / {
		root /wzy;
		index index.html;
	}
#自定义错误页面
	error_page 404 /404.html;
	location = /404.html {
		root /wzy;	
	}
}

[root@wzy ~]#systemctl restart nginx

访问wyz.com。没有弹出自定义的提示信息,和浏览器有关,老旧的浏览器会提示。

不输入账户密码页面显示

安装工具
[root@wenzi conf.d]#apt -y install apache2-utils

-b:非交互式创建认证文件,
[root@wenzi conf.d]#htpasswd -cb /apps/nginx/conf/.htpasswd user1 123456
Adding password for user user1
[root@wenzi conf.d]#htpasswd -b /apps/nginx/conf/.htpasswd user2 123456
Adding password for user user2
[root@wenzi conf.d]#cat ../.htpasswd
user1:$apr1$KvqhSgKT$9ojLRkFkCetPO/O6DY4u31
user2:$apr1$gsBbdCdb$8vo9d1fTHL6/TLNTFNhnX/

安全加固
[root@wenzi conf.d]#chown -R nginx:nginx /apps/nginx/conf/.htpasswd
[root@wenzi conf.d]#chmod 600 /apps/nginx/conf/.htpasswd

[root@wenzi conf.d]#cat wenzi.com.conf
server {
    listen 80 default_server;
    server_name www.wenzi.com;
    location / {
        root /apps/nginx/html;
        index index.html index.htm;
    }

    location /userauth.html {
        auth_basic           "please input user and pwd";
        auth_basic_user_file /apps/nginx/conf/.htpasswd;
    }
}

 访问指定页面,出现认证提示

不输入账号密码,出现报错

 输入账号密码,访问成功

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值