黑帽联盟

 找回密码
 会员注册
查看: 54|回复: 0
打印 上一主题 下一主题

[资源教程] Nginx06-rewrite模块详解与实验

[复制链接]

883

主题

38

听众

3276

积分

管理员

Rank: 9Rank: 9Rank: 9

  • TA的每日心情

    2 小时前
  • 签到天数: 1606 天

    [LV.Master]伴坛终老

    nginx rewrite
    官网:https://nginx.org/en/docs/http/ngx_http_rewrite_module.html


    重定向,也叫url重定向、url改写


    • 网站URL重定向(80->443)
    • 客户端类型跳转

    • - 默认访问www.baidu.com
    • - ios、android等,访问m.baidu.com

    • 新老域名跳转

    • - www.360buy.com -> jd.com

    • 伪静态


    rewrite 模块
    相关的指令        说明
    return        实现对URL的改写,一般与ngx变量一起使用。可以用来直接返回指定的HTTP状态码给客户端。
    rewrite        实现对URL的改写,使用正则匹配URI,进行改写。支持各种标记,如last、break、redirect和permanent,用于控制重写后的行为。
    set        创建或修改ngx变量。用于在Nginx配置中设置变量值,这些变量可以在后续的配置中使用。
    if        用于条件判断,一般与ngx变量一起使用。根据指定的条件判断是否执行后面的配置指令。

    return
    格式        说明
    格式1        return code URL; 返回状态码+新的URL地址。这种格式用于重定向用户到新的URL,并返回指定的HTTP状态码。
    格式2        return code; 返回指定状态码。这种格式用于直接返回一个HTTP状态码给客户端,而不进行重定向。
    放哪        这些return指令可以放在Nginx配置文件中的server块、location块或if语句中。

    案例01 访问/admin/ 返回403
    编写子配置文件
    [root@front conf.d]# cat rewrite.test.com.conf
    server {
            listen 80;
            server_name rewrite.test.com;
            root /app/code/rewrite;
            location / {
                    index index.html;
            }
            location /admin/ {
                    return 403;
            }
    }




    测试
    C:\Users\14765>curl -H Host:rewrite.test.com http://192.168.100.148/admin/
    <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
    <html>
    <head><title>403 Forbidden</title></head>
    <body>
    <center><h1>403 Forbidden</h1></center>

    案例02 域名间跳转
    编写子配置文件


    [root@front conf.d]# cat tiaozhuan.test.com.conf
    server {
            listen 80;
            server_name tiaozhuan.test.com;
            return 301 http://rewrite.test.com;
    }




    测试
    curl -L --location 跟随跳转,响应是301,302跳转的时候使用.


    [root@front conf.d]# curl -Lv -H Host:tiaozhuan.test.com 192.168.100.148
    * Rebuilt URL to: 192.168.100.148/
    *   Trying 192.168.100.148...
    * TCP_NODELAY set
    * Connected to 192.168.100.148 (192.168.100.148) port 80 (#0)
    > GET / HTTP/1.1
    > Host:tiaozhuan.test.com #访问第一个url
    > User-Agent: curl/7.61.1
    > Accept: */*
    >
    < HTTP/1.1 301 Moved Permanently
    < Server: Tengine/2.4.1
    < Date: Wed, 12 Jun 2024 14:20:04 GMT
    < Content-Type: text/html
    < Content-Length: 245
    < Connection: keep-alive
    < Location: http://rewrite.test.com  # 301重定向的url
    <
    * Ignoring the response-body
    * Connection #0 to host 192.168.100.148 left intact
    * Issue another request to this URL: 'http://rewrite.test.com'
    * Rebuilt URL to: http://rewrite.test.com/
    *   Trying 127.0.0.1...
    * TCP_NODELAY set
    * Connected to rewrite.test.com (127.0.0.1) port 80 (#1)
    > GET / HTTP/1.1
    > Host: rewrite.test.com # 访问重定向的url
    > User-Agent: curl/7.61.1
    > Accept: */*
    >
    < HTTP/1.1 200 OK # 访问成功
    < Server: Tengine/2.4.1
    < Date: Wed, 12 Jun 2024 14:20:04 GMT
    < Content-Type: text/html
    < Content-Length: 8
    < Last-Modified: Tue, 11 Jun 2024 15:29:42 GMT
    < Connection: keep-alive
    < ETag: "66686d66-8"
    < Accept-Ranges: bytes
    <
    rewrite   # 跳转成功
    * Connection #1 to host rewrite.test.com left intact


    if
    通过nginx变量进行判断、比大小、匹配、过滤
    nginx中的取反操作,只能if进行


    格式
    if (condition) {
            action1;
            action2;
            ...
    }


    位置
    - server模块内
    - location模块内
    符号
    | 条件类型 | 说明 |
    | -------- | ---- |
    | 变量比较 | 如果变量值为空字符串或“0”,则为假。在Nginx 1.0.1版本之前,任何以“0”开头的字符串都被视为假值。 |
    | 字符串比较 | 使用“=”和“!=”运算符比较变量与字符串。 |
    | 正则匹配 | 使用“”进行大小写敏感匹配,使用“”进行大小写不敏感匹配。正则表达式可以包含捕获组,这些捕获组在后续的配置中可以使用。负运算符“!”和“!”也支持。如果正则表达式包含“}”或“;”字符,整个表达式应被单引号或双引号包围。 |
    | 文件存在性检查 | 使用“-f”和“!-f”运算符检查文件是否存在。 |
    | 目录存在性检查 | 使用“-d”和“!-d”运算符检查目录是否存在。 |
    | 文件、目录或符号链接存在性检查 | 使用“-e”和“!-e”运算符检查文件、目录或符号链接是否存在。 |
    | 可执行文件检查 | 使用“-x”和“!-x”运算符检查文件是否可执行。 |


    案例03 只允许GET、POST请求,其他禁止访问
    官网:https://nginx.org/en/docs/varindex.html
    使用到的变量: $request_method 取出请求方法


    子配置文件
    [root@front conf.d]# cat rewrite.test.com.conf
    server {
            listen 80;
            server_name rewrite.test.com;
            root /app/code/rewrite;
            location / {
                    index index.html;
            }
            location /admin/ {
                    return 403;
            }
            if ($request_method !~ "GET|POST"){
                    return 403;
            }
    }


    测试
    # GET,请求成功
    [root@front conf.d]# curl -H Host:rewrite.test.com 192.168.100.148
    rewrite




    # HEAD,请求失败
    #  -I, --head          Show document info only

    [root@front conf.d]# curl -I -H Host:rewrite.test.com 192.168.100.148
    HTTP/1.1 403 Forbidden
    Server: Tengine/2.4.1
    Date: Wed, 12 Jun 2024 14:59:10 GMT
    Content-Type: text/html
    Content-Length: 557
    Connection: keep-alive




    set
    用于创建或修改nginx自定义变量,一般和if一起用
    nginx变量进行赋值和使用都需要加$,这点和shell不一样


    格式
    # nginx
    set 变量 值;
    set $test key;


    # shell
    test=key


    案例04 设置是否处于维护状态,是则返回503,否则正常访问
    设置变量f l a g ,默认 0 判断 flag,默认0 判断flag,默认0判断flag是否为1,是则503


    子配置文件
    [root@front conf.d]# cat rewrite.test.com.conf
    server {
            listen 80;
            server_name rewrite.test.com;
            root /app/code/rewrite;
            set $flag 0; # 添加,测试时会修改为0或1用于模拟是否处于维护状态
            # 添加以下3行判断
            if ($flag = 1) {
                    return 503;
            }


            location / {
                    index index.html;
            }
            location /admin/ {
                    return 403;
            }
            if ($request_method !~ "GET|POST"){
                    return 403;
            }
    }




    测试
    # $flag 为0
    [root@front conf.d]# curl -H Host:rewrite.test.com 192.168.100.148
    rewrite


    # $flag 为1
    ## 替换0 为1
    ## sed -i "/set/s|0|1|g" rewrite.test.com.conf   筛选包含set的行进行修改

    [root@front conf.d]# curl -H Host:rewrite.test.com 192.168.100.148
    <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
    <html>
    <head><title>503 Service Temporarily Unavailable</title></head>
    <body>
    <center><h1>503 Service Temporarily Unavailable</h1></center>



    rewrite
    rewrite正则用于匹配用户请求的uri
    支持普通正则、扩展正则、过滤、perl正则等
    命令的格式与sed ‘s|||g’ 类似,实现替换功能,rewrite替换url内容.(改写)


    格式
    - rewrite 找什么(具体内容/正则/保护分组) ->替换成什么(具体内容/后向引用) [标记];
    - 标记可以省略,默认使用redirect标记(302)
    - redirect 302
    - permanent 301
    位置
    - server、location、if
    标记
    | 标记 | 说明 | 补充 |
    | ---------- | ------- | ------- |
    | redirect | 302 临时 用户访问的时候,收到302提示及新的位置Location(响应头),用户根据Location新的位置进行访问(让用户重新发出http请求) | 新旧地址都可以用。 |
    | permanent | 301 永久 用户访问的时候,收到302提示及新的位置Location(响应头),用户根据Location新的位置进行访问(让用户重新发出http请求) | 旧的地址排名取消,旧地旧的不用了,只用新的网站。 |
    | break | 用户的请求匹配到包含break指令或rewrite规则后,即使后面还有location规则,也不会继续运行。终止运行。 | 表示在当前rewrite规则执行后停止后续的rewrite规则和location匹配。 |
    | last | 用户请求匹配到包含last标记的rewrite规则后,停止继续执行,Nginx会重新发出内部请求,请求与location规则进行匹配。 | 表示在当前rewrite规则执行后,不再执行后续的rewrite规则,而是重新发起请求。 |


    案例05 域名跳转
    子配置文件
    # nginx配置文件不是#注释,使用时需要把注释删掉
    [root@front conf.d]# vim rewrite.test.com.conf
    server {
            listen 80;
            server_name rewrite.test.com;
            #return 301 http://www.baidu.com$request_uri;
            rewrite ^(.*)$ http://www.baidu.com$1 permanent;
            # 匹配rewrite.test.com/xxx/yyy的/xxx/yyy部分(uri),通过反向引用,重定向baidu.com之后
            # rewrite.test.com/xxx/yyy -> www.baidu.com/xxx/yyy
            # permanent 永久重定向 301,不写默认302
    }




    测试
    浏览器访问 https://rewrite.test.com/test.com
    自动rewrite,重定向到baidu.com,携带uri

    23.png

    案例06 rewrite break和last小测试
    子配置文件
    [root@front conf.d]# cat flag.test.com.conf
    server {
            listen 80;
            server_name flag.test.com;
            root /app/code/flag;
            error_log /var/log/nginx/flag-error.log notice;
            rewrite_log on;


            location / {
                    rewrite /1.html /2.html;
                    rewrite /2.html /3.html;
            }
            location /2.html {
                    rewrite /2.html /3.html;
            }
            location /3.html {
                    rewrite /3.html /a.html;
            }
    }




    # 测试文件
    [root@front conf.d]# mkdir -p /app/code/flag
    [root@front conf.d]# echo 1.html url > /app/code/flag/1.html
    [root@front conf.d]# echo 2.html url > /app/code/flag/2.html
    [root@front conf.d]# echo 4.html url > /app/code/flag/3.html
    [root@front conf.d]# echo 3.html url > /app/code/flag/3.html
    [root@front conf.d]# echo a.html url > /app/code/flag/a.html
    [root@front conf.d]# echo b.html url > /app/code/flag/b.html






    正常访问
    [root@front conf.d]# curl -H Host:flag.test.com 192.168.100.148/1.html
    a.html url
    [root@front conf.d]# curl -H Host:flag.test.com 192.168.100.148/2.html
    a.html url


    # 匹配默认location/ loc/:1->2 2->3 loc3:3->a


    break测试
    # 在第一个rewrite处增加break
    [root@front conf.d]# cat flag.test.com.conf
    server {
            listen 80;
            server_name flag.test.com;
            root /app/code/flag;
            error_log /var/log/nginx/flag-error.log notice;
            rewrite_log on;


            location / {
                    rewrite /1.html /2.html break; # 修改
                    rewrite /2.html /3.html;
            }
            location /2.html {
                    rewrite /2.html /3.html;
            }
            location /3.html {
                    rewrite /3.html /a.html;
            }
    }


    # 测试
    [root@front conf.d]# curl -H Host:flag.test.com 192.168.100.148/1.html
    2.html url
    [root@front conf.d]# curl -H Host:flag.test.com 192.168.100.148/2.html
    a.html url


    # loc/:1->2 break打断,不再执行,后续location也不执行




    last测试
    # 在第一个rewrite处加last;在第二个location的rewrite处将/3.html修改为/b.html
    [root@front conf.d]# cat flag.test.com.conf
    server {
            listen 80;
            server_name flag.test.com;
            root /app/code/flag;
            error_log /var/log/nginx/flag-error.log notice;
            rewrite_log on;


            location / {
                    rewrite /1.html /2.html last; # 修改
                    rewrite /2.html /3.html;
            }
            location /2.html {
                    rewrite /2.html /b.html; # 修改
            }
            location /3.html {
                    rewrite /3.html /a.html;
            }
    }




    # 测试
    [root@front conf.d]# curl -H Host:flag.test.com 192.168.100.148/1.html
    b.html url
    [root@front conf.d]# curl -H Host:flag.test.com 192.168.100.148/2.html
    b.html url


    # loc/:1->2 last打断,执行下一个location  loc2:2->b


    文章转载自:https://blog.csdn.net/Tassel_YUE/article/details/139639477
    帖子永久地址: 

    黑帽联盟 - 论坛版权1、本主题所有言论和图片纯属会员个人意见,与本论坛立场无关
    2、本站所有主题由该帖子作者发表,该帖子作者与黑帽联盟享有帖子相关版权
    3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和黑帽联盟的同意
    4、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任
    5、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
    6、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
    7、黑帽联盟管理员和版主有权不事先通知发贴者而删除本文

    勿忘初心,方得始终!
    您需要登录后才可以回帖 登录 | 会员注册

    发布主题 !fastreply! 收藏帖子 返回列表 搜索
    回顶部