加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 运营中心 > Nginx > 正文

Nginx重写规则403错误

发布时间:2020-12-13 21:14:28 所属栏目:Nginx 来源:网络整理
导读:我将.htaccess文件转换为nginx时遇到问题.我有3个.htaccess文件.第一个.htaccess文件位于文档根目录中,如下所示: Options +FollowSymLinksRewriteEngine OnRewriteRule ^img-(.*).html img.php?id=$1 [L]RewriteRule ^slide-(.*).html slider.php?id=$1 [

我将.htaccess文件转换为nginx时遇到问题.我有3个.htaccess文件.第一个.htaccess文件位于文档根目录中,如下所示:

Options +FollowSymLinks
RewriteEngine On
RewriteRule ^img-(.*).html img.php?id=$1 [L]
RewriteRule ^slide-(.*).html slider.php?id=$1 [L]
RewriteRule ^page-(.*).html page.php?name=$1 [L]
RewriteRule ^contact.html$contact.php [QSA,L,NC]

第二个.htaccess文件位于名为upload的文件夹中:

RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://(.+.)?foo.com/ [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteRule .*.(jpe?g|gif|bmp|png)$nohotlink.gif [L]

第三个也是最后一个.htaccess文件位于名为“small”的上传文件夹的子目录中:

RewriteEngine Off

现在我在/ etc / nginx中创建了一个名为includes的文件夹,并使用这些重写规则制作了3个单独的.access文件:

对于位于文档根目录中的第一个.htaccess文件,我在/ etc / nginx / includes中创建了一个名为root.access的文件.在这个文件中我有:

# nginx configuration 

location /img { 
rewrite ^/img-(.*).html /img.php?id=$1 break; 
} 
location /slide { 
    rewrite ^/slide-(.*).html /slider.php?id=$1 break; 
} 
location /page { 
    rewrite ^/page-(.*).html /page.php?name=$1 break; 
} 
location /contact { 
    rewrite ^/contact.html$/contact.php break; 
}

对于位于“upload”文件夹中的第二个文件,我在/ etc / nginx /包含了一个名为upload.access的文件.该文件包含以下内容:

# nginx configuration 

location /upload { 
if ($http_referer !~ "^http://(.+.)?foo.com/"){ 
rewrite .*.(jpe?g|gif|bmp|png)$/nohotlink.gif break; 
} 
} 
location ~ .(php|sql|php3|php4|phtml|pl|py|jsp|asp|htm|shtml|sh|cgi)${ 
deny all; 
}

对于第三个也是最后一个文件,我在/ etc / nginx /中创建了一个包含名称small.access的文件.该文件的内容如下:

# nginx configuration 

location /upload/small { 
}

在服务器块配置文件中,我有:

 location / {
              try_files $uri $uri/ /index.php;
              include /etc/nginx/includes/root.access;
     }

 location /upload {
              include /etc/nginx/includes/upload.access;
     }

 location /upload/small {
              include /etc/nginx/includes/small.access;
     }

现在使用此配置尝试网站时,我收到403错误. Nginx错误日志报告:

[error] 18156#0: *7 access forbidden by rule,client: 111.**.**.**,server: foo.com,request: "POST /upload.php HTTP/1.1",host: "foo.com",referrer: "http://foo.com/"

现在在apache下,一切都没有问题.但我不明白为什么我会收到403错误.我也担心我所说的重写规则,除了403错误之外根本无法正常工作.谁能帮我这个?我看不出这里有什么问题.

最佳答案
这是此部分配置的标准nginx行为:

location /upload { 

    if ($http_referer !~ "^http://(.+.)?foo.com/"){ 
        rewrite .*.(jpe?g|gif|bmp|png)$/nohotlink.gif break; 
    } 

    location ~ .(php|sql|php3|php4|phtml|pl|py|jsp|asp|htm|shtml|sh|cgi)${ 
        deny all; 
    }

}

为什么?

让我澄清一下位置是如何工作的:当nginx读取配置文件时,它会对3种类型的位置块进行排序:

>确切的位置块,例如location = / upload {}
>前缀位置块,例如位置/上传{}
>包含正则表达式的位置块location~ / upload {}

一旦请求到达nginx,位置选择过程如下:

>如果找到与URI匹配的确切位置块,nginx将停止搜索其他位置块并提供此请求.
>如果没有,nginx将搜索最长匹配的前缀位置块,并在进入下一步之前记住它.
>然后nginx按顺序检查包含正则表达式的位置块.第一个匹配的将用于提供请求.
>如果在上一步中未找到任何内容,则nginx将使用步骤2的前缀位置块来提供请求.如果没有发现任何事情可能发生,但它是偏离主题的.

因此,在您的情况下,匹配.php扩展名的位置块优先于匹配URI的/ upload部分的位置块.

编辑:澄清解决方案,添加替代解决方案.

使用^?你可以告诉nginx改变他在第2步的行为,这样它就会立即使用匹配的前缀位置,绕过正则表达式位置查找.所以你有2个解决方案:

解决方案1:

upload.access:

if ($http_referer !~ '^http://(.+.)?foo.com/') { 
    rewrite '.*.(jpe?g|gif|bmp|png)$' '/upload/nohotlink.gif' break; 
} 

if ($uri ~ '.(php|sql|php3|php4|phtml|pl|py|jsp|asp|htm|shtml|sh|cgi)$') {
    return 403; 
}

相同的服务器块

解决方案2:

upload.access:

if ($http_referer !~ '^http://(.+.)?foo.com/') { 
    rewrite '.*.(jpe?g|gif|bmp|png)$' '/upload/nohotlink.gif' break; 
} 

location ~ .(php|sql|php3|php4|phtml|pl|py|jsp|asp|htm|shtml|sh|cgi)${
    deny all;
}

服务器块:

 location ^~ /upload {
     include /etc/nginx/includes/upload.access;
 }

现在,如果你没有设置转发php文件处理的位置,你当前的配置将不会导致任何事情:检查nginx fastcgi module.然后你需要在root.access文件中更改你的重写规则,这样它们就不会被解析在当前位置上下文中(即创建一个唯一的回退位置并将更改中断更改为最后一次,以告知nginx在重写后再次运行位置选择过程).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读