Nginx(三)

自定义错误页面

模块:Module ngx_http_core_module

Syntax:error_page code ... [=[response]] uri;
Default:
Context:http, server, location, if in location

自定义错误页面样式

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

    location = /404.html {
        root /apps/nginx/html;
    }
}

访问一个不存在的页面

如果404就跳转到网站首页

[root@wenzi conf.d]#cat wenzi.com.conf
server {
    listen 80 default_server;
    server_name www.wenzi.com;
    #302是临时重定向
    error_page 404 =302 /index.html;
    location / {
        root /apps/nginx/html;
        index index.html;
    }
}

自定义错误日志

模块:Core functionality

Syntax:error_log file [level];
Default:
error_log logs/error.log error;
Context:main, http, mail, stream, server, location

自定义错误日志路径

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

[root@wenzi conf.d]#cat /apps/nginx/logs/wenzi.com_error.log
2024/02/17 06:18:07 [error] 83330#0: *18 open() "/apps/nginx/html/xxx" failed (2: No such file or directory), client: 192.168.28.1, server: www.wenzi.com, request: "GET /xxx HTTP/1.1", host: "www.wenzi.com"

不记录特定目录的错误日志

[root@wenzi conf.d]#cat wenzi.com.conf
server {
    listen 80 default_server;
    server_name www.wenzi.com;
    error_log /apps/nginx/logs/wenzi.com_error.log;
    location / {
        root /apps/nginx/html;
        index index.html;
    }
    location /data {
        error_log /dev/null;
    }
}

错误日志记录不会新增

检测文件是否存在

模块:https://nginx.org/en/docs/http/ngx_http_core_module.html#try_files

Syntax:try_files file … uri; try_files file … =code;
Default:
Context:server, location

try_files 会按顺序检查文件是否存在,返回第一个找到的文件或文件夹(结尾加斜线表示为文件夹),如果所有文件或文件夹都找不到,会进行一个内部重定向到最后一个参数。只有最后一个参数可以引起一个内部重定向,之前的参数只设置内部URI的指向。最后一个参数是回退URI且必须存在,否则会出现内部500错误

访问资源不存在时,返回备选页面

[root@wenzi conf.d]#echo "This try_files last access page" > /apps/nginx/html/default.html

[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 /tryfile.html {
        root /apps/nginx/html;
        try_files $uri $uri.html $uri/index.html /default.html;
    }
}

在这里插入图片描述

访问资源不存在时,返回指定响应码

[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 /tryfile {
        root /apps/nginx/html;
        try_files $uri $uri.html $uri/index.html =345;
    }
}


[root@wenzi ~]#curl -v www.wenzi.com/tryfile
*   Trying 192.168.28.60:80...
* Connected to www.wenzi.com (192.168.28.60) port 80 (#0)
> GET /tryfile HTTP/1.1
> Host: www.wenzi.com
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 345			#此处响应码变为指定的345
< Server: nginx/1.22.1
< Date: Fri, 16 Feb 2024 23:08:45 GMT
< Content-Length: 0
< Connection: keep-alive
<
* Connection #0 to host www.wenzi.com left intact

长连接

长连接:keepalive

模块:https://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_requests

限制了一个长连接上可以处理的请求数量 或 在一次长连接上所允许请求的资源的最大数量,默认为1000次

Syntax:keepalive_requests number;
Default:keepalive_requests 1000;
Context:http, server, location

模块:https://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_time

限制对一个连接中请求处理的最长时间,到时间后续的再有新的请求会断开连接,默认1h

Syntax:keepalive_time time;
Default:keepalive_time 1h;
Context:http, server, location

模块:https://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_timeout

设置保持空闲的连接超时时长,0表示禁止长连接,默认为75s;通常配置在http块作为站点全局配置

Syntax:keepalive_timeout timeout [header_timeout];
Default:keepalive_timeout 75s;
Context:http, server, location
[root@wenzi conf]#vim nginx.conf
http {
	...
    keepalive_requests 3;
    #keepalive_timeout  0;
    keepalive_timeout  15 30;	#15表示空闲的连接超时时长;30表示客户端看到的响应信息中keep-Alive:timeout=xx
	...
}

测试
[root@wenzi ~]#telnet www.wenzi.com 80
Trying 192.168.28.60...
Connected to www.wenzi.com.
Escape character is '^]'.
GET / HTTP/1.1		#手动输入
HOST: www.wenzi.com #手动输入

HTTP/1.1 200 OK
Server: nginx/1.22.1
Date: Fri, 16 Feb 2024 23:59:53 GMT
Content-Type: text/html
Content-Length: 615
Last-Modified: Fri, 16 Feb 2024 19:18:26 GMT
Connection: keep-alive	#当keepalive_timeout  0;时,此处显示Connection:close
Keep-Alive: timeout=30	#keepalive_timeout  15 30,中30的设定
ETag: "65cfb502-267"
Accept-Ranges: bytes

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
#等待15秒后nginx会自动断开连接
Connection closed by foreign host.

作为下载服务器

模块:https://nginx.org/en/docs/http/ngx_http_autoindex_module.html

处理以斜杠字符 “/” 结尾的请求,并生成目录列表,可以做为下载服务配置使用。

自动文件索引功能,默认off

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

计算文件大小,默认on;on为精确显示,单位bytes,off为估计大小,单位K,M

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

索引界面显示风格,默认html

Syntax:autoindex_format html | xml | json | jsonp;
Default:autoindex_format html;
Context:http, server, location

on显示本机时间,而非GMT格林威治时间,默认off

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

相关参数

autoindex on | off;
autoindex_exact_size on | off;
autoindex_localtime on | off;
charset charset | off;
autoindex_format html | xml | json | jsonp;
limit_rate rate; #限制响应客户端传输速率(除GET和HEAD以外的所有方法),单位B/s,即bytes/second,默认值0,表示无限制,此指令由ngx_http_core_module提供
set $limit_rate 4k; #也可以通变量限速,单位B/s,同时设置,此项优级高
[root@wenzi conf.d]#mkdir /apps/nginx/html/download
[root@wenzi conf.d]#echo 123 > /apps/nginx/html/download/1.txt
[root@wenzi conf.d]#echo 123 > /apps/nginx/html/download/2.txt
[root@wenzi conf.d]#echo 123 > /apps/nginx/html/download/3.txt
[root@wenzi conf.d]#vim wenzi.com.conf
server {
    listen 80 default_server;
    server_name www.wenzi.com;
    location / {
        root /apps/nginx/html;
        index index.html;
    }
    location /download {
        root /apps/nginx/html;
        autoindex on;
        autoindex_exact_size on;
        autoindex_localtime on;
        charset utf8;
        limit_rate 1024k;
    }
}

在这里插入图片描述

作为上传服务器

模块:http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size

Syntax:client_max_body_size size;
Default:client_max_body_size 1m;
Context:http, server, location

模块:http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size

Syntax:client_body_buffer_size size;
Default:client_body_buffer_size 8k|16k;
Context:http, server, location

模块:http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_temp_path

Syntax:client_body_temp_path path [level1 [level2 [level3]]];
Default:client_body_temp_path client_body_temp;
Context:http, server, location
client_max_body_size 1m; #设置允许客户端上传单个文件的最大值,默认值为1m,上传文件超过此值会出413错误
client_body_buffer_size size; #用于接收每个客户端请求报文的body部分的缓冲区大小;默认16k;超出此大小时,其将被暂存到磁盘上的由client_body_temp_path指令所定义的位置
client_body_temp_path path [level1 [level2 [level3]]];#设定存储客户端请求报文的body部分的临时存储路径及子目录结构和数量,目录名为16进制的数字,使用hash之后的值从后往前截取1位、2位、2位作为目录名

[root@centos8 ~]# md5sum /data/nginx/html/pc/index.html 
95f6f65f498c74938064851b1bb963d4 /data/nginx/html/pc/index.html
单个16进制数可以表示的范围是0 1 2 3 4 5 6 7 8 9 A B C D E F ,一共16个
1级目录 即 4 ,占1位16进制,范围 0 ~ f,即16个目录,2^4=16
2级目录 即 3d ,占2位16进制,范围 00 ~ ff,即16*16=256个目录,2^8=256
3级目录 即 96 ,占2位16进制,范围 00 ~ ff,即16*16=256个目录,2^8=256
所以整个三级文件目录结构可以容纳16 * 256 * 256 = 1048576 (2^24) 个唯一的文件或目录。

示例
client_max_body_size 100m;  #如果太大,上传时会出现413 Request Entity Too Large错误,注意:如果php上传,还需要修改php.ini的相关配置
client_body_buffer_size 1024k;
client_body_temp_path /apps/nginx/client_body_temp/ 1 2 2; #上传时,Nginx会自动创建相关目录

限流限速

限制某个用户在一定时间内能产生的http请求或限制某个用户的下载速度,防止个别用户对资源消耗过多,导致其它用户受影响。

启用限速后,如果超过指定的阈值,则默认提示503过载保护

下载限速

限制用户下载资源的速度

模块:http://nginx.org/en/docs/http/ngx_http_core_module.html#limit_rate

Syntax:limit_rate rate;
Default:limit_rate 0;
Context:http, server, location, if in location

模块:http://nginx.org/en/docs/http/ngx_http_core_module.html#limit_rate_after

Syntax:limit_rate_after size;
Default:limit_rate_after 0;
Context:http, server, location, if in 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 /download {
        root /apps/nginx/html;
        autoindex on;
        autoindex_exact_size on;
        autoindex_localtime on;
        charset utf8;
        limit_rate_after 1m;	#下载达到1M数据后开始限速
        limit_rate 10k;			#达到阈值后,限速为10k
    }
}

通过wget下载文件可以观察到当已下载1M时,速率开始猛降,直至稳定10k速率

限制请求数

限制同一个IP同时发起的最大请求数

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

Syntax:limit_req_zone key zone=name:size rate=rate [sync];
Default:
Context:http
Syntax:limit_req zone=name [burst=number] [nodelay | delay=number];
Default:
Context:http, server, location
Syntax:limit_req_status code;
Default:limit_req_status 503;
Context:http, server, location
[root@wenzi conf.d]#vim /apps/nginx/conf/nginx.conf
...
http {
	...
	limit_req_zone $binary_remote_addr zone=req_cs:10m rate=1r/s;
	...
	}
	
[root@wenzi conf.d]#cat wenzi.com.conf
server {
    listen 80 default_server;
    server_name www.wenzi.com;
    limit_req zone=req_cs burst=5 nodelay;
    #limit_req_status 555;	#可自行设定响应码,默认503
    location / {
        root /apps/nginx/html;
        index index.html;
    }
}

limit_req_zone 定义在http块中
$binary_remote_addr 表示以客户端IP地址的二进制形式为限流依据的key
zone=区域名字:区域大小,Zone为存放IP及URL访问频率的共享内存区域。8000个IP地址的状态信息约占用内存空间1MB。10m即8万个ip地址
rate=最大请求速率;上述配置速率不能超过每秒1个请求。超过此速率的请求放入burst队列做延迟处理
burst=队列大小,当此队列满后,会中断请求报错
nodelay表示超过请求速率并且缓存区满后不延迟处理,立即返回503错误,不设置此项则所有请求会排队

其它用法:限制来自单个IP地址($binary_remote_addr)且限制访问某个虚拟主机($server_name)的请求频率。
http {
	limit_req_zone $binary_remote_addr zone=perip:10m rate=1r/s;
	limit_req_zone $server_name zone=perserver:10m rate=10r/s;
	
	server {
		limit_req zone=perip burst=5 nodelay;
		limit_req zone=perserver burst=10;
	}
}

当快速刷新www.wenzi.com时,会报错503

在这里插入图片描述

限制并发连接数

限制同一个IP的同时发起的最大并发连接数

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

Syntax:limit_conn_zone key zone=name:size;
Default:
Context:http
Syntax:limit_conn zone number;
Default:
Context:http, server, location
[root@wenzi conf.d]#vim /apps/nginx/conf/nginx.conf
...
http {
	...
    limit_conn_zone $binary_remote_addr zone=conn_cs:10m;
	...
}
	
[root@wenzi conf.d]#cat wenzi.com.conf
server {
    listen 80 default_server;
    server_name www.wenzi.com;
    limit_conn conn_cs 2;	#限制并发两个连接
    location / {
        root /apps/nginx/html;
        index index.html;
    }
}

模拟百度云网盘非会员限速限流功能

  • 当下载超过100M则限制下载速度为500k
  • 限制web服务器请求数处理为1秒一个,触发值为5、限制用户仅可同时下载2个文件。
  • 如果同时下载超过2个资源,则返回提示 “请联系管理员进行会员充值” 并跳转到其他页面
[root@wenzi conf.d]#vim /apps/nginx/conf/nginx.conf
...
http {
	...
    limit_req_zone $binary_remote_addr zone=req_zone:10m rate=1r/s;
	limit_conn_zone $binary_remote_addr zone=conn_zone:10m;
	...
}
[root@wenzi conf.d]#cat wenzi.com.conf
server {
    listen 80 default_server;
    server_name www.wenzi.com;
    error_page 503 @error_page;
    location / {
        root /apps/nginx/html;
        index index.html;
    }
    location /download {
        root /apps/nginx/html;
        charset utf8;
        autoindex on;
        autoindex_exact_size off;
        autoindex_localtime on;
        limit_req zone=req_zone burst=5 nodelay;
        limit_conn conn_zone 2;
        limit_rate_after 2m;
        limit_rate 10k;
    }
    location @error_page {
        default_type text/html;
        charset utf8;
        return 200 "please use money" ;
    }
}

在同一台机器上多开shell窗口依次进行下载文件
在这里插入图片描述在这里插入图片描述在这里插入图片描述

favicon.ico

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

#方法一:服务器不记录访问日志:
location = /favicon.ico {
    log_not_found off;   
	access_log off;
}

#方法二:将图标保存到指定目录访问:
#location ~ ^/favicon\.ico$ {
location = /favicon.ico {    
	root   /apps/nginx/html/images;
    expires 365d;  #设置文件过期时间
	access_log off;
}

Rewrite模块

此功能依靠PCRE,编译之前要安装PCRE库;

可实现常用网站的URL重写,但客户端无需修改书签、链接,仍可正常访问;

隐藏源网站链接信息,实现跳转,提高安全;

URL伪静态化,将动态页面显示为静态页面的一种技术;

if

用于条件匹配判断,根据判断结果选择不同的nginx配置;

仅支持单次判断,不支持if else 或 if elif 多重判断

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

变量与表达式之间符号

使用正则表达式对变量进行匹配,匹配成功true,匹配失败为false;

若 $变量 的值为空字符串或0,则if认为条件判断结果为false,其它情况为true;

=变量和字符串是否相等,相等true,不等false
!=变量和字符串是否 不 相等,不相等true,相等false
~正则匹配,区分大小写,满足条件true,不满足条件false
!~正则匹配,区分大小写,不 满足条件true,满足条件false
~*正则匹配,不 区分大小写,满足条件true,不满足条件false
!~*正则匹配,不 区分大小写,不 满足条件true,满足条件false
-e存在(包含文件、目录、软链接)
!-e不存在(包含文件、目录、软链接)
-f文件存在
!-f文件不存在
-d目录存在
!-d目录不存在
-x可执行
!-x不可执行
-----------------------------------------官方示例
if ($http_user_agent ~ MSIE) {					#是否为IE浏览器
    rewrite ^(.*)$ /msie/$1 break;
}

if ($http_cookie ~* "id=([^;]+)(?:;|$)") {		#cookie头是否包含 id= 后跟一些值
    set $id $1;
}

if ($request_method = POST) {					#请求方法是否为POST
    return 405;									#405 Method Not Allowed,不允许使用post方法
}

if ($slow) {									#此变量若为0,表示不限速,则true
    limit_rate 10k;
}

if ($invalid_referer) {							#请求的 `Referer` 头不符合指定的条件
    return 403;									#返回HTTP状态码 `403 Forbidden`
}
-----------------------------------------拒绝curl的访问
[root@wenzi conf.d]#cat wenzi.com.conf
server {
    listen 80 default_server;
    server_name www.wenzi.com;
    location / {
        if ($http_user_agent ~ curl) {
            return 403;		#403 Forbidden 服务器拒绝请求(即使有授权)。
        }
        root /apps/nginx/html;
        index index.html;
    }
}

[root@wenzi ~]#curl www.wenzi.com
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.22.1</center>
</body>
</html>

set

指定key并给其定义一个变量,变量可以调用Nginx内置变量赋值给key。

value可以是text + variable 两者结合

Syntax:set $variable value;
Default:
Context:server, location, if
location /set { 
	root /data/nginx/html/pc;
    index index.html;
    default_type text/html;  
	set $name wang;				# $name的值为wang
	echo $name;
	set $my_port $server_port;	# $my_port的值为$server_port
	echo $my_port;
}

break

中断当前相同作用域(location)中的其它nginx配置,与break处于同一作用域的nginx配置中,位于break前面的配置生效,位于后面的 ngx_http_rewrite_module 模块中的指令将不再执行;

nginx服务器根据配置处理请求过程中遇到break时,回到上一层作用域继续向下读取配置;

如果break指令在location块中,break后面的指令还会继续执行,只是不执行 ngx_http_rewrite_module 模块的指令,其它指令还会执行

Syntax:break;
Default:
Context:server, location, if
location /break {
	default_type text/html;
	set $name wang;
	echo "break_before:name=$name" ;       
	break;   #location块中break后面指令还会执行
    set $my_port $server_port;
	echo "break_after:my_port=$my_port" ;
	echo "break_after:name=$name" ;
}

测试
curl http://www.wang.org/break/
break_before:name=wang
break_after:my_port=
break_after:name=wang

return

return用于完成对请求的处理,并直接向客户端返回响应状态码。

可使用 301/302 + 新URL 实现重定向;403/500等 + 提示文本 实现指定提示文本内容

处于此指令后的所有配置都不被执行

Syntax:return code [text]; return code URL; return URL;
Default:
Context:server, location, if
return code;		#返回给客户端指定的http状态码
return code [text];	#返回给客户端的状态码及响应报文的实体内容,可调用变量,若text中含空格,需要用单/双引号
return code URL;	#返回给客户端的url地址
return URL;			#302跳转返回给客户端的完整url地址;如 http://www.xxx.com/index.html
禁止压力测试工具访问
[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;
    }
    if ( $http_user_agent ~* "wget|apachebench" ) {
        set $user_agent_deny = 1;
   }
    if { $user_agent_deny = 1 }{
        return 403;
    }
}

[root@wenzi ~]#wget www.wenzi.com
--2024-02-19 06:20:34--  http://www.wenzi.com/
Resolving www.wenzi.com (www.wenzi.com)... 192.168.28.60
Connecting to www.wenzi.com (www.wenzi.com)|192.168.28.60|:80... connected.
HTTP request sent, awaiting response... 403 Forbidden
2024-02-19 06:20:34 ERROR 403: Forbidden.


http跳转https
方法一
server {
	listen 80;
	server_name www.wenzi.com;
	return 302 https://$server_name$request_uri;
}
server {
	listen 443 ssl http2;
	server_name www.wenzi.com;
	ssl_certificate /etc/nginx/ssl/www.wenzi.com.crt;
	ssl_certificate_key /etc/nginx/ssl/www.wenzi.com.key;
	location / {
		root /apps/nginx/html;
	}
}
方法二
server {  
	listen 80 ;  
	listen 443 ssl; 
	ssl_certificate /apps/nginx/ssl/www.wenzi.com.crt; 
	ssl_certificate_key /apps/nginx/ssl/www.wenzi.com.key;
	ssl_session_cache shared:sslcache:20m; 
	ssl_session_timeout 10m;   
	server_name www.wenzi.com;  
	root /apps/nginx/html;
    if ($scheme = http) {      
		return https://$server_name$request_uri;
   	}
   
	location = /nginx_status {      
		stub_status;
	}
}

rewrite

rewrite将用户请求的URI基于regex所描述的模式进行检查,匹配到时将其替换为表达式指定的新的URI

如果在同一级配置块中存在多个rewrite规则,那么会自下而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查,隐含有循环机制,但不超过10次;如果超过,提示500响应码,[flag]所表示的标志位用于控制此循环机制

如果替换后的URL是以http://或https://开头,则替换结果会直接以重定向返回给客户端, 即永久重定向301

分组机制(.*)只会捕获URI

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

正则表达式格式

.			#匹配除换行符以外的任意字符
\w			#匹配字母或数字或下划线或汉字
\s			#匹配任意的空白符
\d			#匹配数字,相当于[0-9]
\b			#匹配单词的开始或结束
^			#匹配字付串的开始
$			#匹配字符串的结束
*	  		#匹配重复零次或更多次
+			#匹配重复一次或更多次
?			#匹配重复零次或一次
(n) 		#匹配重复n次
{n,} 		#匹配重复n次或更多次
{n,m} 		#匹配重复n到m次
*? 			#匹配重复任意次,但尽可能少重复
+? 			#匹配重复1次或更多次,但尽可能少重复
?? 			#匹配重复0次或1次,但尽可能少重复
{n,m}? 		#匹配重复n到m次,但尽可能少重复
{n,}? 		#匹配重复n次以上,但尽可能少重复
\W  		#匹配任意不是字母,数字,下划线,汉字的字符
\S 			#匹配任意不是空白符的字符
\D 			#匹配任意非数字的字符
\B 			#匹配不是单词开头或结束的位置
[^x] 		#匹配除了x以外的任意字符
[^wang] 	#匹配除了wang 这几个字母以外的任意字符

flag

redirect;
#302 临时重定向,匹配到redirect时,不再执行redirect后面的所有代码,立即中断。重写完成后以临时重定向方式直接返回重写后的新URL给客户端,由客户端重新发起请求。使用相对路径,或http:// 或 https:// 开头。

permanent;
#301 永久重定向,重写完成后以永久重定向方式直接返回重写后生成的新URL给客户端,由客户端重新发起请求。

break;
#建议在location中用,重写完成后,停止对当前URL在当前location中后续的其它重写操作,然后直接跳转至重写规则配置块之后的其它配置,然后结束循环。适合一个URL一次重写

last;
#不建议在location中使用,重写完成后,停止对当前URI在当前location中后续的其它所有操作,然后对新URL在server块中搜索匹配的location,直至没有location可匹配后,将最后一次location的数据返回客户端。适合一个URL多次重写,同时注意避免出现超过10次以上以及URL重写后返回错误给用户
官方示例
server {
    ...
    #若请求的URI是/download/somepath/media/example.mp4,将被重写为 /download/somepath/mp3/example.mp3
    rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;
    #若请求的URI是/download/anotherpath/audio/sample.wav,将被重写为 /download/anotherpath/mp3/sample.ra
    rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra  last;
    return  403;
    ...
}

location /download/ {
    rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
    rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra  break;
    return  403;
}

rewrite ^/users/(.*)$ /show?user=$1? last;

测试

构建结构,index.html内容为This is redirect/permanent/... 类似内容
[root@wenzi html]#tree /apps/nginx/html/
/apps/nginx/html/
├── break
│   └── index.html
├── default
│   └── index.html
├── last
│   └── index.html
├── noflag
│   └── index.html
├── permanent
│   └── index.html
└── redirect
    └── index.html

---------------------------------------没有flag
[root@wenzi conf.d]#cat wenzi.com.conf
server {
    listen 80 default_server;
    server_name www.wenzi.com;
    root /apps/nginx/html;
    location / {
        rewrite ^/noflagpath(.*)$ /noflag/index.html;	#在此处重写规则
        try_files $uri $uri/ =404;						#执行此处
    }
	
    location /noflag/ {		#此location未匹配,不执行							
        try_files $uri $uri/ =404;
    }
}

访问/noflagpath
[root@wenzi ~]#curl http://www.wenzi.com/noflagpath
This is noflag

---------------------------------------仅有redirect
[root@wenzi conf.d]#cat wenzi.com.conf
server {
    listen 80 default_server;
    server_name www.wenzi.com;
    root /apps/nginx/html;
    location / {
        rewrite ^/redirectpath(.*)$ /redirect/index.html redirect;	#执行完此行立即中断,将重写后URL返回给客户端,不执行后面所有代码。
        try_files $uri $uri/ =404;
    }

    location /redirect/ {
        try_files $uri $uri/ =404;
    }
}

访问/redirect,因为有重定向,所以需要加-L选项
[root@wenzi ~]#curl -Lv http://www.wenzi.com/redirect
*   Trying 192.168.28.60:80...
* Connected to www.wenzi.com (192.168.28.60) port 80 (#0)
> GET /redirect HTTP/1.1
> Host: www.wenzi.com
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 301 Moved Permanently
< Server: nginx/1.22.1
< Date: Tue, 20 Feb 2024 13:57:44 GMT
< Content-Type: text/html
< Content-Length: 169
< Location: http://www.wenzi.com/redirect/
< Connection: keep-alive
<
* Ignoring the response-body
* Connection #0 to host www.wenzi.com left intact
* Issue another request to this URL: 'http://www.wenzi.com/redirect/'
* Found bundle for host www.wenzi.com: 0x55a67f5b8ae0 [serially]
* Can not multiplex, even if we wanted to!
* Re-using existing connection! (#0) with host www.wenzi.com
* Connected to www.wenzi.com (192.168.28.60) port 80 (#0)
> GET /redirect/ HTTP/1.1
> Host: www.wenzi.com
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx/1.22.1
< Date: Tue, 20 Feb 2024 13:57:44 GMT
< Content-Type: text/html
< Content-Length: 17
< Last-Modified: Tue, 20 Feb 2024 13:19:31 GMT
< Connection: keep-alive
< ETag: "65d4a6e3-11"
< Accept-Ranges: bytes
<
This is redirect	#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
* Connection #0 to host www.wenzi.com left intact

---------------------------------------仅有permanent
[root@wenzi conf.d]#cat wenzi.com.conf
server {
    listen 80 default_server;
    server_name www.wenzi.com;
    root /apps/nginx/html;
    location / {
        rewrite ^/permanentpath(.*)$ /permanent/index.html permanent;	#执行完此行立即中断,将重写后URL返回给客户端,不执行后面所有代码。
        try_files $uri $uri/ =404;
    }

    location /permanent/ {
        try_files $uri $uri/ =404;
    }
}

访问/permanent,因为有重定向,所以需要加-L选项
[root@wenzi ~]#curl -Lv http://www.wenzi.com/permanent
*   Trying 192.168.28.60:80...
* Connected to www.wenzi.com (192.168.28.60) port 80 (#0)
> GET /permanent HTTP/1.1
> Host: www.wenzi.com
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 301 Moved Permanently
< Server: nginx/1.22.1
< Date: Tue, 20 Feb 2024 14:06:46 GMT
< Content-Type: text/html
< Content-Length: 169
< Location: http://www.wenzi.com/permanent/
< Connection: keep-alive
<
* Ignoring the response-body
* Connection #0 to host www.wenzi.com left intact
* Issue another request to this URL: 'http://www.wenzi.com/permanent/'
* Found bundle for host www.wenzi.com: 0x55fafc17dae0 [serially]
* Can not multiplex, even if we wanted to!
* Re-using existing connection! (#0) with host www.wenzi.com
* Connected to www.wenzi.com (192.168.28.60) port 80 (#0)
> GET /permanent/ HTTP/1.1
> Host: www.wenzi.com
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx/1.22.1
< Date: Tue, 20 Feb 2024 14:06:46 GMT
< Content-Type: text/html
< Content-Length: 18
< Last-Modified: Tue, 20 Feb 2024 13:20:34 GMT
< Connection: keep-alive
< ETag: "65d4a722-12"
< Accept-Ranges: bytes
<
This is permanent		#<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
* Connection #0 to host www.wenzi.com left intact

---------------------------------------仅有break
[root@wenzi conf.d]#cat wenzi.com.conf
server {
    listen 80 default_server;
    server_name www.wenzi.com;
    root /apps/nginx/html;
    location / {
        rewrite ^/breakpath(.*)$ /break/index.html break;	
        rewrite ^/breakpath(.*)$ /default/index.html;	#不执行此行
        try_files $uri $uri/ =404;						#执行此行
    }

    location /break/ {				#此location未匹配,不执行	
        try_files $uri $uri/ =404;
    }

    location /default/ {			#此location未匹配,不执行	
        try_files $uri $uri/ =404;
    }
}

访问/breakpath
[root@wenzi ~]#curl -L  http://www.wenzi.com/breakpath
This is break

---------------------------------------仅有last
[root@wenzi conf.d]#cat wenzi.com.conf
server {
    listen 80 default_server;
    server_name www.wenzi.com;
    root /apps/nginx/html;
    location / {
        rewrite ^/lastpath(.*)$ /last/index.html last;	#执行此行,然后立即从头开始匹配location,包括本location
        rewrite ^/lastpath(.*)$ /default/index.html;	#不执行此行
        try_files $uri $uri/ =404;						#不执行此行
    }
    location /last/ {				#执行此location
        return 200 'This is /last/ return 200 ';
    }
    location /default/ {			#未匹配,不执行
        return 200 'This is /default/ return 200';
    }
}

访问/lastpath
[root@wenzi ~]#curl http://www.wenzi.com/lastpath
This is /last/ return 200 

永久与临时重定向

客户端无需改变保存的旧链接,可实现访问旧链接跳转到新的地址。

都会导致客户端重新发起请求,客户端可以看到链接地址会发生变化。

301 永久重定向

域名永久型调整,即域名永远跳转至另外一个新的域名,之前的域名再也不使用,跳转记录可以缓存到客户端浏览器。

永久重定向会缓存DNS解析记录,浏览器控制台-网络-可看到from disk cache,即使nginx无法访问,浏览器也会利用缓存进行重定向。

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

浏览器访问 http://www.wenzi.com/1.html 时会自动跳转到 http://www.wenzi.com/2.html,浏览器地址栏可看到地址变化为 http://www.wenzi.com/2.html 。当再次访问 http://www.wenzi.com/1.html 时,通过控制台可看到下图

在这里插入图片描述

302 临时重定向

域名临时重定向,告诉浏览器域名不是固定重定向到当前目标域名,后期可能随时会更改,因此浏览器不会缓存当前域名的解析记录。

当nginx服务器无法访问时,浏览器不能利用缓存,而导致重定向失败

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

浏览器访问 http://www.wenzi.com/1.html 时会自动跳转到 http://www.wenzi.com/2.html,浏览器地址栏可看到地址变化为 http://www.wenzi.com/2.html 。当再次访问 http://www.wenzi.com/1.html 时,通过控制台可看到下图

在这里插入图片描述

对比

最大区别:301 永久重定向,浏览器会永久缓存重定向的DNS解析记录,而301 临时重定向,浏览器不会缓存重定向的DNS解析记录。

redirect:302,旧网站无影响,新网站会有排名,跳转不会缓存

permanent:301,旧网站排名会被清空,新跳转网站继承原网站排名,跳转会缓存,主要用于旧域名废弃和新域名启用时使用。

因业务需要,需要将访问旧域名www.wenzi.com的请求永久重定向到www.bai
[root@wenzi conf.d]#cat wenzi.com.conf
server {
    listen 80 default_server;
    server_name www.wenzi.com;
    location / {
        rewrite / https://www.baidu.com;
    }
}

https加密

Web网站的登录页面通常都会使用https加密传输的,加密数据以保障数据的安全,HTTPS能够加密信息,以免敏感信息被第三方获取。

https 由 http + ssl/tls 构成。在http上又加了一层处理加密信息的模块,传输的信息都是经过tls加密后的信息。

工作流程

1、客户端发起HTTPS请求

用户在浏览器里输入一个https网址,然后连接到服务器的443端口

2、服务端的配置

采用HTTPS协议的服务器必须要有一套数字证书,可以自己制作,也可以向组织申请。区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面。这套证书其实就是一对公钥和私钥

3、传送服务器的证书给客户端

证书里其实就是公钥,并且还包含了很多信息,如证书的颁发机构,过期时间等等

4、客户端解析验证服务器证书

这部分工作是由客户端的TLS来完成的,首先会验证公钥是否有效,比如:颁发机构,过期时间等 等,如果发现异常,则会弹出一个警告框,提示证书存在问题。如果证书没有问题,那么就生成一 个随机值。然后用证书中公钥对该随机值进行非对称加密

5、客户端将加密信息传送服务器

这部分传送的是用证书加密后的随机值,目的就是让服务端得到这个随机值,以后客户端和服务端 的通信就可以通过这个随机值来进行加密解密了

6、服务端解密信息

服务端将客户端发送过来的加密信息用服务器私钥解密后,得到了客户端传过来的随机值

7、服务器加密信息并发送信息

服务器将数据利用随机值进行对称加密,再发送给客户端

8、客户端接收并解密信息

客户端用之前生成的随机值解密服务段传过来的数据,于是获取了解密后的内容

配置参数

模块:Module ngx_http_ssl_module

yum安装默认开启;编译安装需要指定编译参数 --with-http-ssl-module开启

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

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,默认为后三个,最新的浏览器已经不再支持TLS1.0和TLS1.1

ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
#配置ssl缓存   
	off: #关闭缓存
	none:  #通知客户端支持ssl session cache,但实际不支持
	builtin[:size]:#使用OpenSSL内建缓存,为每worker进程私有,使用此内置缓存可能会导致内存碎片
	[shared:name:size]:#在各worker之间使用一个共享的缓存,需要定义一个缓存名称和缓存空间大小,1M可以存储4000个会话信息,多个虚拟主机可以使用相同的缓存名称
	ssl_session_timeout time; #客户端连接可以复用ssl session cache中缓存的有效时长,默认5分钟

官方建议优化参数

worker_processes auto;

http {

    ...

    server {
        listen              443 ssl;
        keepalive_timeout   70;

        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
        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;

        ...
    }

实验

------------------------------------准备www.wenzi.com证书
#创建CA所需文件
[root@wenzi ~]#mkdir -p /data/pki/CA
[root@wenzi ~]#mkdir /data/pki/CA/{certs,crl,newcerts,private}
[root@wenzi ~]#touch /data/pki/CA/index.txt
[root@wenzi ~]#echo 01 > /data/pki/CA/serial
[root@wenzi ~]#tree /data/pki/CA/
/data/pki/CA/	#典型PKI(公钥基础设施)证书颁发机构(CA)的目录布局
├── certs		#存放已经签名的证书
├── crl			#存放证书的吊销列表
├── index.txt	#索引文件,记录已签名的证书信息
├── newcerts	#存放新生成的、但未签名的证书请求CSR
├── private		#存放CA的私钥
└── serial		#记录下一个要使用的证书序列号

#创建CA私钥、CA自签名证书
[root@wenzi ~]#openssl req -newkey rsa:4096 -nodes -sha256 -keyout /data/pki/CA/private/ca.key -x509 -days 3650 -out /data/pki/CA/ca.crt
...
Country Name (2 letter code) [AU]:CN	
State or Province Name (full name) [Some-State]:henan
Locality Name (eg, city) []:zhengzhou
Organization Name (eg, company) [Internet Widgits Pty Ltd]:company
Organizational Unit Name (eg, section) []:yunwei
Common Name (e.g. server FQDN or YOUR name) []:www.wenzi.site
Email Address []:123@qq.com

#生成网站www.wenzi.com的私钥、证书申请文件CSR
[root@wenzi ~]#openssl req -newkey rsa:4096 -nodes -sha256 -keyout /data/pki/CA/www.wenzi.com.key -out /data/pki/CA/newcerts/www.wenzi.com.csr
...
Country Name (2 letter code) [AU]:CN	#和CA保持一致
State or Province Name (full name) [Some-State]:henan	#和CA保持一致
Locality Name (eg, city) []:luoyang
Organization Name (eg, company) [Internet Widgits Pty Ltd]:company	#和CA保持一致
Organizational Unit Name (eg, section) []:yunwei
Common Name (e.g. server FQDN or YOUR name) []:www.wenzi.com	#给哪个网站用
Email Address []:222@qq.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:	#不加密直接回车
An optional company name []:

#CA签名网站www.wenzi.com的证书申请文件,生成网站的证书
[root@wenzi ~]#openssl x509 -req -days 3650 -in /data/pki/CA/newcerts/www.wenzi.com.csr -CA /data/pki/CA/ca.crt -CAkey /data/pki/CA/private/ca.key -CAserial /data/pki/CA/serial -out /data/pki/CA/certs/www.wenzi.com.crt
[root@wenzi ~]#tree /data/pki/CA/
/data/pki/CA/
├── ca.crt
├── certs
│   └── www.wenzi.com.crt
├── crl
├── index.txt
├── newcerts
│   └── www.wenzi.com.csr
├── private
│   └── ca.key
├── serial
└── www.wenzi.com.key

#合并网站证书和CA证书为一个文件,网站证书必须在前,CA证书在后
[root@wenzi ~]#cat /data/pki/CA/certs/www.wenzi.com.crt /data/pki/CA/ca.crt > /data/pki/CA/www.wenzi.com.pem
#在nginx下创建存放网站证书的目录
[root@wenzi ~]#mkdir /apps/nginx/certs
#将www.wenzi.com.key 和 www.wenzi.com.pem 复制到 /apps/nginx/certs
[root@wenzi ~]#cp /data/pki/CA/www.wenzi.com.key /apps/nginx/certs/
[root@wenzi ~]#cp /data/pki/CA/www.wenzi.com.pem /apps/nginx/certs/
#修改权限
[root@wenzi ~]#chown -R nginx:nginx /apps/nginx/certs

------------------------------------配置nginx的https
[root@wenzi conf.d]#cat www.wenzi.com.conf
server {
    listen 80;
    listen 443 ssl http2;
    server_name www.wenzi.com;
    ssl_certificate /apps/nginx/certs/www.wenzi.com.pem;
    ssl_certificate_key /apps/nginx/certs/www.wenzi.com.key;
    ssl_session_cache shared:sslcache:20m;
    ssl_session_timeout 10m;
}

测试通过浏览器访问 https://www.wenzi.com ,因为是自签名,所以不被浏览器识别。点击高级,继续访问即可正常访问

点击左上方 不安全—证书无效,即可看到证书信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值