自定义错误页面
模块:Module ngx_http_core_module
Syntax: | error_page |
---|---|
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;
}
}
自定义错误日志
Syntax: | error_log |
---|---|
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、客户端接收并解密信息
客户端用之前生成的随机值解密服务段传过来的数据,于是获取了解密后的内容
配置参数
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 ,因为是自签名,所以不被浏览器识别。点击高级,继续访问即可正常访问
点击左上方 不安全—证书无效,即可看到证书信息