Linux Nginx——地址重写Rewrite、Rewrite 指令、last,break详解、Nginx https 、Apache https、location详解

Nginx 地址重写 rewrite

  • 什么是Rewrite

Rewrite对称URL Rewrite,可理解为URL重写,是把传入Web的请求重定向到其他URL。

URL Rewrite最常见的应用是URL伪静态化,是将动态页面显示为静态页面方式的一种技术。
从安全角度上看,如果在URL中暴露太多的参数,会导致信息泄露,会被一些***利用对系统造成一定的破坏,故静态化的URL地址可以带来更高的安全性。

  • Rewrite 相关指令

Nginx Rewrite 相关指令有:if、rewrite、set、return

if 语句
应用环境

server,location

语法:

if (condition) { … }if 支持的条件判断匹配符号
~ 					正则匹配 (区分大小写)    ~* 				    正则匹配 (不区分大小写)!~                  正则不匹配 (区分大小写)!~*		            正则不匹配  (不区分大小写)-f 和!-f 		    用来判断是否存在文件
-d 和!-d 		    用来判断是否存在目录
-e 和!-e 		    用来判断是否存在文件或目录
-x 和!-x 		    用来判断文件是否可执行#在匹配过程中可以引用一些Nginx的全局变量$args				请求中的参数$document_root	    针对当前请求的根路径设置值$host				请求信息中的"Host",如果请求中没有Host行,则等于设置的服务器名$limit_rate			对连接速率的限制$request_method		请求的方法,比如"GET"、"POST"等$remote_addr		客户端地址$remote_port		客户端端口号$remote_user		客户端用户名,认证用$request_filename   当前请求的文件路径名$request_uri		当前请求的文件路径名$query_string		与$args相同$scheme				用的协议,比如http或者是https$server_protocol	请求的协议版本,"HTTP/1.0"或"HTTP/1.1"$server_addr 		服务器地址,若没有指明服务器地址,使用这个变量将发起一次系统调用以取得地址$server_name		请求到达的服务器名$document_uri 		URI地址$server_port 		请求到达的服务器端口号

Rewrite flag
rewrite 指令根据表达式来重定向URI、或者修改字符串,可应用于server,location, if环境下每行rewrite指令最后跟一个flag标记。

支持的flag标记:

last 		相当于Apache里的[L]标记,表示完成rewrite默认为lastbreak 		本条规则匹配完成后,终止匹配,不再匹配后面的规则
redirect 	返回302浏览器地址会显示跳转后的URL地址
permanent 	返回301浏览器地址会显示跳转后URL地址

www.vc.com --> www.jd.com

redirect 和 permanent区别是返回的不同方式的重定向,对于客户端一般状态下是无区别的;而对于搜索引擎,相对来看301的重定向更加友好,如果把一个地址采用301跳转方式跳转,搜索引擎会把老地址的相关信息带到新地址,同时在搜索引擎索引库中彻底废弃掉原先的老地址。使用302重定向时,搜索引擎有时会判断跳转前后哪个网址更直观,然后显示哪个,如果它判断跳转前的URL更好,也许地址栏不会更改。

  • Rewrite匹配参考示例
#本地解析hosts文件(windows)192.168.62.153 www.testpm.com[root@nginx html]# pwd/html[root@nginx html]# lsa  b[root@nginx html]# cat a/1.html 1.html[root@nginx html]# cat b/2.html 22# http://www.testpm.com/a/1.html ==> http://www.testpm.com/b/2.htmlserver {
    listen       80;
    server_name  www.testpm.com;

        location /a {
        root /html;
        index   1.html index.htm;
        rewrite .* /b/2.html permanent;
        }

        location /b {
        root    /html;
        index   2.html index.htm;
        }}---------------------[root@mycat html]# pwd/var/www/html 
[root@mycat html]# ls2020  2021[root@mycat html]# cat 2020/a/1.html 2020[root@mycat html]# cat 2021/a/1.html 2021# http://www.testpm.com/2021/a/1.html ==> http://www.testpm.com/2020/a/1.htmlserver {
    listen       80;
    server_name  www.testpm.com;

    location /2021/a {
        root    /var/www/html;
        index   1.html index.hml;
        rewrite ^/2021/(.*)$ /2020/$1 permanent;
    }

    location /2020/a {
        root    /var/www/html;
        index   1.html index.htl;
    }}---------------------# http://www.vc.com/a/1.html ==> http://jd.comlocation /a {
        root    /html;
        if ($host ~* vc.com ) {
        rewrite .* http://jd.com permanent;
        }}---------------------# http://www.youngfit.com/a/1.html ==> http://jd.com/a/1.htmllocation /a {
        root /html;
        if ( $host ~* youngfit.com ){
        rewrite .* http://jd.com$request_uri permanent;
        }}---------------------# 在访问目录后添加/  (如果目录后已有/,则不加/)[root@nginx-server c]# pwd/usr/share/nginx/html/a/b/c

http://www.vc.com/a/b/c--->http://www.vc.com/a/b/c/# http://www.vc.com/a/b/c# $1: /a/b/# $2: c# http://$host$1$2/location /a/b/c {
        root    /usr/share/nginx/html;
        index   index.html index.hml;
        if (-d $request_filename) {
        rewrite ^(.*)([^/])$ http://$host$1$2/ permanent;
        }}---------------------[root@nginx html]# pwd/usr/share/nginx/html[root@nginx html]# ls50x.html  index.html  index.html.bak1  reg[root@nginx html]# cat reg/login.html login# http://www.vc.com/login/qf.html ==>  http://www.vc.com/reg/login.html?user=qf
    location /login {
        root   /usr/share/nginx/html;
        rewrite ^/login/(.*)\.html$ http://$host/reg/login.html?user=$1;
        }
    location /reg {
        root /usr/share/nginx/html;
        index login.html;
        }---------------------[root@nginx-server 33]# pwd/html/qf/11/22/33[root@nginx-server 33]# cat 1.html hello nginx#http://www.vc.com/qf/11-22-33/1.html  ==>  http://www.vc.com/qf/11/22/33/1.htmllocation /qf {
            rewrite ^/qf/([0-9]+)-([0-9]+)-([0-9]+)(.*)$ /qf/$1/$2/$3$4 permanent;
        }

        location /qf/11/22/33 {
                root /html;
                index   1.html;
        }

  • set 指令

set 指令是用于定义一个变量,并且赋值

应用环境:

server,location,if

  • 应用示例
#http://alice.testpm.com ==> http://www.testpm.com/alice#http://jack.testpm.com ==> http://www.testpm.com/jack[root@nginx-server conf.d]# cd /usr/share/nginx/html/[root@nginx-server html]# mkdir jack alice[root@nginx-server html]# echo "jack.." >> jack/index.html[root@nginx-server html]# echo "alice.." >> alice/index.html本地解析域名host文件
192.168.62.153 www.testpm.com
192.168.62.153 alice.testpm.com
192.168.62.153 jack.testpm.com
编辑配置文件:
server {
    listen       80;
    server_name  www.testpm.com;

    location / {
         root   /usr/share/nginx/html;
         index  index.html index.htm;
         if ( $host ~* ^www.testpm.com$) {
                break;
                }

         if ( $host ~* "^(.*)\.testpm\.com$" ) {
                set $user $1;
                rewrite .* http://www.testpm.com/$user permanent;
                }
        }
    location /jack {
         root /usr/share/nginx/html;
         index  index.html index.hml;
        }
    location /alice {
         root /usr/share/nginx/html;
         index index.html index.hml;
        }}

  • return 指令

return 指令用于返回状态码给客户端

server,location,if

  • 应用示例:
#如果访问的.sh结尾的文件则返回403操作拒绝错误http://www.testpm.com/1.sh     返回403
server {
    listen       80;
    server_name  www.testpm.com;
    #access_log  /var/log/nginx/http_access.log  main;

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

    location ~* \.sh$ {
        return 403;
        }}---------------------#80 ======> 443:80转443端口server {
    listen       80;
    server_name  www.testpm.cn;
    access_log  /var/log/nginx/http_access.log  main;
    return 301 https://www.testpm.cn$request_uri;}server {
    listen 443 ssl;
    server_name www.testpm.cn;
    access_log  /var/log/nginx/https_access.log  main;

    #ssl on;
    ssl_certificate   /etc/nginx/cert/2447549_www.testpm.cn.pem;
    ssl_certificate_key  /etc/nginx/cert/2447549_www.testpm.cn.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
    ssl_prefer_server_ciphers on;

    location / {
        root  /usr/share/nginx/html;
        index index.html index.htm;
    }}[root@nginx-server ~]# curl -I http://www.testpm.cnHTTP/1.1 301 Moved Permanently
Server: nginx/1.16.0
Date: Wed, 03 Jul 2021 13:52:30 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: https://www.testpm.cn/

  • ast,break详解

Linux Nginx——地址重写Rewrite、Rewrite 指令、last,break详解、Nginx https  、Apache https、location详解

[root@localhost test]# cat  /etc/nginx/conf.d/last_break.conf server {
    listen       80;
    server_name  localhost;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
 
    location /break/ {
        root /usr/share/nginx/html;
        rewrite .* /test/break.html break;
    }

    location /last/ {
        root /usr/share/nginx/html;
        rewrite .* /test/last.html last;
    }

    location /test/ {
        root /usr/share/nginx/html;
        rewrite .* /test/test.html break;
    }}[root@localhost conf.d]# cd /usr/share/nginx/html/[root@localhost html]# mkdir test[root@localhost html]# echo "last" > test/last.html[root@localhost html]# echo "break" > test/break.html[root@localhost html]# echo "test" > test/test.htmlhttp://192.168.62.159/break/break.html
http://192.168.62.159/last/last.html

  • 注意:

last 标记在本条 rewrite 规则执行完后,会对其所在的 server { … } 标签重新发起请求;
break 标记则在本条规则匹配完成后停止匹配,不再做后续的匹配。

  • Nginx 的 https ( rewrite )
server {
        listen       80;
        server_name  *.vip9999.top vip9999.top;

        if ($host ~* "^www.vip9999.top$|^vip9999.top$" ) {
                return 301 https://www.vip9999.top$request_uri;
        }

        if ($host ~* "^(.*).vip9999.top$" ) {
                set $user $1;
                return 301 https://www.vip9999.top/$user;
        }

    }

    # Settings for a TLS enabled server.
    server {
        listen       443 ssl;
        server_name  www.vip9999.top;

        location / {
                root      /usr/share/nginx/html;
                index     index.php index.html;
        }

        #pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        location ~ \.php$ {
            root           /usr/share/nginx/html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }
        ssl on;
        ssl_certificate cert/214025315060640.pem;
        ssl_certificate_key cert/214025315060640.key;
        ssl_session_cache shared:SSL:1m;
        ssl_session_timeout  10m;
        ssl_ciphers HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;
        }

  • Apache 的 https ( rewrite )拓展
[root@localhost ~]# yum -y install httpd mod_ssl[root@localhost ~]# vim /etc/httpd/conf.d/vip9999.conf

Linux Nginx——地址重写Rewrite、Rewrite 指令、last,break详解、Nginx https  、Apache https、location详解

  • nginx的location指令详解

Nginx 的 HTTP 配置主要包括三个区块,结构如下:

http {                      # 这个是协议级别
  include mime.types;
  default_type application/octet-stream;
  keepalive_timeout 65;
  gzip on;
    server {             # 这个是服务级别
      listen 80;
      server_name localhost;
        location / {  # 这个是请求级别
          root html;
          index index.html index.htm;
        }
      }}

  • location详解

1、location 区段
location 在 server 模块中配置,根据不同的 URl使用不同的配置,处理不同的请求。
location 安装顺序匹配,会被第一个匹配的location 处理。

语法如下:

location [=|~|~*|^~|@] pattern{……}

2、location 前缀

=    表示精确匹配,优先级也是最高的 
^~   表示url以某个常规字符串开头,理解为匹配url路径即可 
~    表示区分大小写的正则匹配  
~*   表示不区分大小写的正则匹配!~   表示区分大小写不匹配的正则!~*  表示不区分大小写不匹配的正则
/    通用匹配,任何请求都会匹配到

3、location 配置示例

本地解析域名host
1、没有修饰符 表示:必须以指定模式开始

[root@nginx-server nginx]# pwd/home/www/nginx[root@nginx-server nginx]# cat abc/2.html 2.html

server {
    listen       80;
    server_name  www.vc.com;

    location  /abc {
        root    /home/www/nginx;
        index   2.html;
        }}

以下是对的:
http://www.vc.com/abc

2、=表示:必须与指定的模式精确匹配

server {
    listen       80;
    server_name  www.testpm.cn;
    access_log  /var/log/nginx/http_access.log  main;

    location / {
        root /usr/share/nginx/html;
        index a.html index.htm;
    }
    
    location = / {
        root /usr/share/nginx/html;
        index b.html index.htm;
    }}

进行测试:
http://www.testpm.cn
http://www.testpm.cn/a.html

3、~ 表示:指定的正则表达式要区分大小写

[root@nginx-server nginx]# pwd/home/www/nginx[root@nginx-server nginx]# lsabc  ABC[root@nginx-server nginx]# cat abc/2.html abc[root@nginx-server nginx]# cat ABC/2.html ABC

server {
        server_name localhost;
        location ~ /abc {
                root /home/www/nginx;
                index 2.html index.html;
        }}

http://192.168.62.153/abc/

4、~* 表示:指定的正则表达式不区分大小写

[root@nginx-server nginx]# pwd/home/www/nginx[root@nginx-server nginx]# lsabc  ABC[root@nginx-server nginx]# cat abc/2.html abc[root@nginx-server nginx]# cat ABC/2.html ABC

server {
        server_name localhost;
        location ~* /abc {
                root /home/www/nginx;
                index 2.html index.html;
        }}

http://192.168.62.153/ABC/

5、^~ :类似于无修饰符的行为,也是以指定模式开始。
查找顺序和优先级

#  = 大于 ^~  大于 ~|~*|!~|!~* 大于 /#  location配置的情况下匹配顺序:首先匹配 =,其次匹配^~, 其次正则匹配,最后是 / 通用匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。-------------------------------------------(1) =:表示完全匹配;(2) ^~:匹配URI的前缀,如果一个URI同时满足两个规则的话,匹配最长的规则;(3) ~:匹配正则表达式,大小写敏感;(4) ~*:匹配正则表达式,大小写不敏感;
优先级:(1)> (2) > (3) = (4)---------------------------
location 区段匹配示例

location = / {
  # 只匹配 / 的查询.
  [ configuration A ]}location / {
  # 匹配任何以 / 开始的查询,但是正则表达式与一些较长的字符串将被首先匹配。
  [ configuration B ]}location ^~ /images/ {
  # 匹配任何以 /images/ 开始的查询并且停止搜索,不检查正则表达式。
  [ configuration C ]}location ~* \.(gif|jpg|jpeg)$ {
  # 匹配任何以gif, jpg, or jpeg结尾的文件,但是所有 /images/ 目录的请求将在Configuration C中处理。
  [ configuration D ]} 各请求的处理如下例:
    / → configuration A
    /documents/document.html → configuration B
    /images/1.gif → configuration C
    /documents/1.jpg → configuration D

4、root 、alias 指令区别

location /img {
    alias /var/www/image;}#若按照上述配置的话,则访问/img/目录里面的文件时,ningx会自动去/var/www/image/目录找文件location /img {
    root /var/www/image;} #若按照这种配置的话,则访问/img/目录下的文件时,nginx会去/var/www/image/img/目录下找文件。

alias 是一个目录别名(自定义名称)的定义;

root 则是最上层目录的定义。

另一个重要的区别是alias后面必须要用“/”结束,否则会找不到文件的,而root有无都可。

上一篇:php-Apache重写规则混乱


下一篇:java-Prettyfaces:在观察特定的url模式时,将Bean属性设置为某个恒定值