目录
1 NGINX的指令及其应用
1.1 if指令
1.2 set 指令 - 实现变量定义
1.3 break 指令
1.4 return 指令
1.5 rewrite 指令
1.5.1 Nginx rewrite 介绍
1.5.2 Nginx rewrite 语法
1.5.3 rewrite 指令结尾的 flag 标记说明
2 域名永久与临时重定向
2.1 永久重定向301
2.2 临时重定向302
2.3 break 与 last
3 NGINX实现https
3.1 创建证书
3.2 rewrite实现全站加密
3.3 错误重定向到主页
4 防盗链
4.1 防盗链的介绍
4.2 实现盗链
1 NGINX的指令及其应用
if (条件匹配) {action}
ngx_http_if_module
模块提供了 if
语句,用于根据请求的属性来决定是否执行某些配置。例如,可以根据请求的方法、URI、协议等来决定是否执行某个location块中的配置
可以使用正则表达式对变量进行匹配,匹配成功时if指令认为条件为true,否则认为false
使用以下符号链接:
符号 | 功能说明 |
---|---|
= | 比较变量和字符串是否相等,相等时 if 指令认为该条件为 true,反之为 false |
!= | 比较变量和字符串是否不相等,不相等时 if 指令认为条件为 true,反之为 false |
~ | 区分大小写字母,可以通过正则表达式匹配,满足匹配条件为 true,不满足匹配条件为 false |
!~ | 区分大小写字母,判断是否匹配,不满足匹配条件为 true,满足匹配条件为 false |
~* | 不区分大小写字母,可以通过正则表达式匹配,满足匹配条件为 true,不满足匹配条件为 false |
!~* | 不区分大小写字母,判断是否匹配,满足匹配条件为 false,不满足匹配条件为 true |
-f 和 !-f | 判断请求的文件是否存在和是否不存在 |
-d 和 !-d | 判断请求的目录是否存在和是否不存在 |
-x 和 !-x | 判断文件是否可执行和是否不可执行 |
-e 和 !-e | 判断请求的文件或目录是否存在和是否不存在(包括文件、目录、软链接) |
这张表格总结了 Nginx 中 if
语句常用的比较运算符及其功能。请注意,这些符号主要用于判断变量或字符串之间的关系以及文件系统的状态。
1.1 if指令
相关例子
实现目录是否存在判断
[root@RHEL-9 conf.d]# vim /usr/local/nginx/conf.d/var.conf
server {
listen 80;
server_name var.shuyan.com;
root /data/web/html;
index index.html;
location /test {
if ( $scheme = http ) {
echo "if ----> $scheme";
}
}
location /test2 {
if ( !-e $request_filename ) {
echo "$request_filename is not exist";
}
}
}
客户端测试
[root@docker-rocky ~]# curl var.shuyan.com/test
if ----> http
[root@docker-rocky ~]# curl var.shuyan.com/test2
/data/web/html/test2 is not exist
1.2 set 指令 - 实现变量定义
在NGINX中除了本来的内置变量外,可以自己自定义一些变量,set 就可以实现定义
server {
listen 80;
server_name var.shuyan.com;
root /data/web/html;
index index.html;
location /test {
if ( $scheme = http ) {
echo "if ----> $scheme";
}
}
location /test2 {
if ( !-e $request_filename ) {
echo "$request_filename is not exist";
}
}
location /test3 {
set $wawa 12345;
echo wawa=$wawa;
}
}
客户端实现效果
[root@docker-rocky ~]# curl var.shuyan.com/test3
wawa=12345
1.3 break 指令
该指令用于中断当前作用域内的其他 Nginx 配置,使其不再生效。在遇到该指令后,位于其后面的同作用域内的其他配置将不会被执行。当 Nginx 在处理请求的过程中遇到该指令时,它会回到上一层作用域继续向下读取配置。
该指令适用于 server
块、location
块以及 if
块中,可用于控制 Nginx 处理请求的过程。它可以用来避免不必要的配置执行,提高效率并简化逻辑。
注意: 如果break指令在location块中后续指令还会继续执行,只是不执行 ngx_http_rewrite_module 模块的指令,其它指令还会执行
首先查看一下自己浏览器的类型与版本
server {
listen 80;
server_name var.shuyan.com;
root /data/web/html;
index index.html;
location /test {
if ( $scheme = http ) {
echo "if ----> $scheme";
}
}
location /test2 {
if ( !-e $request_filename ) {
echo "$request_filename is not exist";
}
}
location /test3 {
set $wawa 12345;
echo wawa=$wawa;
}
location /break {
default_type text/html;
set $name shuyan;
echo $name;
# 浏览器假如是curl
if ( $http_user_agent = "curl/7.76.1" ) {
break;
}
set $id 666;
echo $id;
}
}
测试效果
[root@docker-rocky ~]# curl var.shuyan.com/break
shuyan
[root@docker-rocky ~]# curl -A "edge" var.shuyan.com/break
shuyan
666
[root@docker-rocky ~]# curl -A "firefox" var.shuyan.com/break
shuyan
666
1.4 return 指令
return
指令在 Nginx 中用于立即终止处理请求,并直接向客户端返回指定的状态码和可选的内容或重定向。这意味着一旦 return
被执行,后续的所有配置都不会被处理。它可以在 server、location 和 if 块内使用。
用途
- 状态码返回:可以直接返回特定 HTTP 状态码(如 403、500 等)给客户端。
- 重定向:可以用于 HTTP 重定向,如 301 或 302 状态码,将客户端重定向到另一个 URL。
语法
return
指令的基本语法如下:
return [code] [url|text];
code
: HTTP 状态码。url
: 可选,用于重定向的新 URL。text
: 可选,用于返回给客户端的文本。
重定向实例
location /return {
if ( !-e $request_filename ) {
return 301 http://baidu.com;
}
echo "$request_filename is exist";
}
# return: 立即停止处理当前配置块中的后续指令,并返回给客户端指定的状态码及可选的内容或重定向。
# 301: 表示永久重定向(Permanent Redirect)的状态码。
# 这告诉浏览器或其他客户端该资源已永久移动到新位置。
# http://www.baidu.com;: 指定重定向的目标 URL,
# 即所有匹配当前配置块条件的请求都会被重定向到 http://www.baidu.com
实现效果
发现重定向到百度去了
1.5 rewrite 指令
1.5.1 Nginx rewrite 介绍
1、什么是 Nginx rewrite ? 和 Apache 等 Web 服务软件一样, Nginx rewrite 的主要功能也是实现 URL 地址重写。 Nginx 的 rewrite 规则需要 PCRE 软件的支持, 即通过 Perl 兼容正则表达式语法进行规则匹配。 前文在安装 Nginx 软件时就已经安装了这个 PCRE 软件, 同时也让 Nginx 支持了 rewrite 的功能, 默认参数编译时, Nginx 就会安装支持 rewrite 的模块, 但是, 也必须要有 PCRE 软件的支持。
-
Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求
-
此功能依靠 PCRE(perl compatible regular expression),因此编译之前要安装PCRE库
-
rewrite是nginx服务器的重要功能之一,用于实现URL的重写,URL的重写是非常有用的功能
-
它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的 链接,就可以设置为访问
-
另外还可以在一定程度上提高网站的安全性。
源码安装的时候能明显发现缺少PCRE
ngx_http_rewrite_module 模块教程--参照官方文档
Rewrite 官方手册https://nginx.org/en/docs/http/ngx_http_rewrite_module.html
1.5.2 Nginx rewrite 语法
1)rewrite 指令语法 指令语法: rewrite regex replacement [flag]; 默认值:none 应用位置: server、 location、 if rewrite 是实现 URL 重写的关键指令, 根据 regex (正则表达式) 部分的内容, 重定向到 replacement 部分, 结尾是 flag 标记。 下面是一个简单的 URL rewrite 跳转的例子:
rewrite ^/(.* ) http://www.test.org/$1 permanent;
在上述指令中, rewrite 为固定关键字, 表示开启一条 rewrite 匹配规则,部分是 ^/(.*), 这是一个正则表达式, 表示匹配所有, 匹配成功后跳转到 http://www.test.org/$1。 这里的 $1 是取前面 regex 部分括号里的内容, 结尾的 permanent; 是永久 301 重定向标记, 即跳转到后面的http://www.test.org/$1地址上。
1.5.3 rewrite 指令结尾的 flag 标记说明
flag 标记符号 | 说明 |
---|---|
last | 本条规则匹配完成后, 继续向下匹配新的 location URI 规则 |
break | 本条规则匹配完成即终止, 不再匹配后面的任何规则 |
redirect | 返回 302 临时重定向, 浏览器地址栏会显示跳转后的 URL 地址 |
permanent | 返回 301 永久重定向, 浏览器地址栏会显示跳转后的 URL 地址 |
rewrite regex replacement [flag];
rewrite将用户请求的URI基于regex所描述的模式进行检查,匹配到时将其替换为表达式指定的新的URI
注意:如果在同一级配置块中存在多个rewrite规则,那么会自下而下逐个检查;被某条件规则替换完成 后,会重新一轮的替换检查,隐含有循环机制,但不超过10次;如果超过,提示500响应码,[flag]所表示的 标志位用于控制此循环机制
如果替换后的URL是以http://或https://开头,则替换结果会直接以重定向返回给客户端, 即永久重定向 301
正则表达式格式
正则表达式元字符 | 描述 |
---|---|
. | 匹配除换行符以外的任意字符 |
\w | 匹配字母、数字、下划线或汉字 |
\s | 匹配任意空白符 |
\d | 匹配数字 |
\b | 匹配单词的开始或结束 |
^ | 匹配字串的开始 |
$ | 匹配字串的结束 |
* | 匹配重复零次或多次 |
+ | 匹配重复一次或多次 |
? | 匹配重复零次或一次 |
(n) | 匹配重复 n 次 |
{n,} | 匹配重复 n 次或更多次 |
{n,m} | 匹配重复 n 到 m 次 |
*? | 匹配重复任意次,但尽可能少重复 |
+? | 匹配重复 1 次或多次,但尽可能少重复 |
flag 说明
flag | 功能描述 |
---|---|
redirect | 临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新 URL 给客户端。由客户端重新发起请求;使用相对路径,或者 http:// 或 https:// 开头,状态码:302。 |
permanent | 重写完成后以永久重定向方式直接返回重写后生成的新 URL 给客户端。由客户端重新发起请求,状态码:301。 |
break | 重写完成后,停止对当前 URL 在当前 location 中后续的其他重写操作,然后直接跳转至重写规则配置块之后的其他配置,结束循环。建议在 location 中使用。 |
last | 重写完成后,停止对前 URI 在当前 location 中后续的其他重写操作,然后对新的 URL 启动新一轮重写检查。适用于一个 URL 多次重写,要注意避免出现超过十次以及 URL 重写后返回错误给用户。 |
2 域名永久与临时重定向
域名的临时的调整,后期可能会变,之前的域名或者URL可能还用、或者跳转的目的域名和URL还会跳 转,这种情况浏览器不会缓存跳转,临时重定向不会缓存域名解析记录(A记录),但是永久重定向会缓存。
2.1 永久重定向301
域名永久型调整,即域名永远跳转至另外一个新的域名,之前的域名再也不使用,跳转记录可以缓存到 客户端浏览器
永久重定向会缓存DNS解析记录, 浏览器中有 from disk cache 信息,即使nginx服务器无法访问,浏览器也 会利用缓存进行重定向
比如: 京东早期的域名 www.360buy.com 由于与360公司类似,于是后期永久重定向到了 www.jd.com
示例
[root@RHEL-9 conf.d]# mkdir /data/web/cn
[root@RHEL-9 conf.d]# echo this is shuyan.cn > /data/web/cn/index.html
[root@RHEL-9 conf.d]# vim var.conf
server {
listen 80;
server_name var.shuyan.com;
location / {
root /data/web/html/pc;
index index.html;
rewrite / http://www.shuyan.cn permanent;
}
}
2.2 临时重定向302
域名临时重定向,告诉浏览器域名不是固定重定向到当前目标域名,后期可能随时会更改,因此浏览器 不会缓存当前域名的解析记录,而浏览器会缓存永久重定向的DNS解析记录,这也是临时重定向与永久 重定向最大的本质区别。
即当nginx服务器无法访问时,浏览器不能利用缓存,而导致重定向失败
2.3 break 与 last
server {
listen 80;
server_name var.shuyan.com;
root /data/web/html;
index index.html;
location /break {
rewrite ^/break/(.*) /test1/$1;
rewrite ^/test1/(.*) /test2/$1;
}
location /last {
rewrite ^/last/(.*) /test1/$1;
rewrite ^/test1/(.*) /test2/$1;
}
location /test1 {
return 666 "this is test1";
}
location /test2 {
return 666 "this is test2";
}
}
测试效果
[root@docker-rocky ~]# curl var.shuyan.com/break/
this is test2
[root@docker-rocky ~]# curl var.shuyan.com/last/
this is test2
[root@RHEL-9 conf.d]# mkdir /data/web/html/test{1..2} -p
[root@RHEL-9 conf.d]# echo this is test1 not return > /data/web/html/test1/index.html
[root@RHEL-9 conf.d]# nginx -s reload
# 测试
[root@docker-rocky ~]# curl var.shuyan.com/break/index.html
this is test1 not return
[root@docker-rocky ~]# curl var.shuyan.com/last/index.html
this is test1
3 NGINX实现https
3.1 创建证书
[root@RHEL-9 conf.d]# mkdir /usr/local/nginx/certs
[root@RHEL-9 conf.d]# openssl req -newkey rsa:2048 -nodes -keyout /usr/local/nginx/certs/shuyan.key \
-x509 -days 365 -out /usr/local/nginx/certs/shuyan.crt
[root@RHEL-9 conf.d]# vim rewrite.conf
server {
listen 80;
listen 443 ssl;
server_name www.shuyan.com;
root /data/web/html;
index index.html;
ssl_certificate /usr/local/nginx/certs/shuyan.crt;
ssl_certificate_key /usr/local/nginx/certs/shuyan.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
}
[root@RHEL-9 conf.d]# nginx -s reload
3.2 rewrite实现全站加密
server {
listen 80;
listen 443 ssl;
server_name www.shuyan.com;
root /data/web/html;
index index.html;
ssl_certificate /usr/local/nginx/certs/shuyan.crt;
ssl_certificate_key /usr/local/nginx/certs/shuyan.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
location / {
if ( $scheme = http ) {
# redirect 关键字告诉Nginx返回一个临时重定向状态码(通常是302)
rewrite /(.*) https://$host/$1 redirect;
}
}
}
3.3 错误重定向到主页
server {
listen 80;
server_name var.shuyan.com;
root /data/web/html;
index index.html;
location / {
root /data/web/html;
if ( !-e $request_filename ) {
# 将var.shuyan.com/所有东西 都转到网站主页 并且临时重定向
rewrite /(.*) http://www.shuyan.com/index.html redirect;
}
}
4 防盗链
4.1 防盗链的介绍
防盗链基于客户端携带的referer实现,referer是记录打开一个页面之前记录是从哪个页面跳转过来的标 记信息,如果别人只链接了自己网站图片或某个单独的资源,而不是打开了网站的整个页面,这就是盗链,referer就是之前的那个网站域名,正常的referer信息有以下几种:
referer_hash_value | 描述 |
---|---|
none | 请求报文首部没有 referer 首部,比如用户直接在浏览器输入域名访问网站就没有 referer 信息。 |
blocked | 请求报文有 referer 首部,但无有效值,比如为空。 |
server_names | referer 首部中包含本主机名及 Nginx 监听的 server_name 。 |
arbitrary_string | 自定义指定字符串,但可使用 * 作通配符。示例:*.timinglee.org |
regular_expression | 被指定的正则表达式模式匹配到的字符串,要使用 ~ 开头,例如:~.*\.timinglee\.com |
4.2 实现盗链
[root@docker-rocky ~]# yum install httpd
[root@docker-rocky ~]# cd /var/www/html/
[root@docker-rocky html]# vim index.html
以下图片的连接是别人的网站
<html>
5.3.2 实现防盗链
基于访问安全考虑,nginx支持通过ngx_http_referer_module模块,检查访问
请求的referer信息是否有效
实现防盗链功能
官方文档:
示例: 定义防盗链:
<head>
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
<title>盗链</title>
</head>
<body>
<img src="http://www.shuyan.com/images/yourname.png" >
<h1 style="color:red">欢迎大家</h1>
<p><a href=http://www.shuyan.com>点开有惊喜</a></p>
</body>
</html>
[root@docker-rocky html]# systemctl start httpd
查看www.shuyan.com 中的访问日志,发现在referer字段中有关于192.168.239.60的网页访问,
直接访问的referer 为空的
实现防止盗链
location / {
valid_referers none blocked server_names *.shuyan.com ~\.baidu\.;
if ($invalid_referer) {
return 404;
}
}
再次访问发现已经使用不了图片了,并且点击已经访问不到网站的了