Nginx 如何防止拒绝后重写

Nginx 如何防止拒绝后重写,nginx,nginx-location,Nginx,Nginx Location,我在“/directory/”中有一个网站,在“/directory/subdirectory/”中有一个特殊的网站变体,它应该只能通过几个特定的IP地址访问。然而,子目录是一个虚拟URL,在本例中,网站代码仍然位于名为“directory”的父目录中。所以我需要重写 这是我当前nginx配置文件的相关部分: location /directory { # here are various rewrites for my website location /directory/

我在“/directory/”中有一个网站,在“/directory/subdirectory/”中有一个特殊的网站变体,它应该只能通过几个特定的IP地址访问。然而,子目录是一个虚拟URL,在本例中,网站代码仍然位于名为“directory”的父目录中。所以我需要重写

这是我当前nginx配置文件的相关部分:

location /directory {
    # here are various rewrites for my website

    location /directory/subdirectory/ {
        allow 10.0.0.0/8; # example range of IP addresses allowed 
        deny all; # disable access for others
        rewrite ^/directory/subdirectory/(.*)$ /directory/$1 last; # the website location is still in the parent folder but the PHP code knows this specific version is to be used when the user surfs into subdirectory, which is why there is this rewrite
    }

    try_files $uri $uri/ /directory/index.php?q=$uri&$args;
}

location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_index index.php;
    include fastcgi.conf;
    fastcgi_read_timeout 43200; 
}
我面临的问题是:我不知道如何在“拒绝所有”点击时立即停止执行。如果您正在浏览子目录,无论上面的指令是否允许您的IP,重写都会执行。因此,使用不允许的IP地址浏览子目录的人可以看到子目录内的网站,这当然不是我想要的。如果我注释掉重写,那么allow/deny指令将按预期工作

因此:如何指定只有在访问者未被拒绝的情况下才执行此重写? 尝试将“error_page 403/403.html;”添加到“deny all;”指令之后的该位置,但它只会更改403页(并且只能在注释子目录中的重写规则时再次看到)。为了实现这一点,我们已经在网上搜索了好几天,使用了各种各样的搜索词,并不断修改配置,但都没有用

另外:只要我浏览到子目录中的URL,以“.php”结尾,“拒绝所有”就不再起作用了。我假设这是因为“location~.php$”指令,出于某种原因,它获得了高于上面嵌套的location指令的优先级。我可以通过以下方式解决这个问题:

location ^~ /directory/subdirectory/ {
    allow 10.0.0.0/8; # example range of IP addresses allowed 
    deny all; # disable access for others
    rewrite ^/directory/subdirectory/(.*)$ /directory/$1 last;
}

location /directory {
    # here are various rewrites for my website

    try_files $uri $uri/ /directory/index.php?q=$uri&$args;
}

location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_index index.php;
    include fastcgi.conf;
    fastcgi_read_timeout 43200; 
}
现在,“location^~/directory/subdirectory/”指令的优先级高于“location~.php$”指令,这使得“deny all”起作用,但我不知道这是否是一种方法,因为它似乎不是最“清晰易读”的解决方案,因为我将“directory/”位置中的某些内容从该位置块中移出。而且,这仍然不能解决我的主要问题(只会使“rewrite^/directory/subdirectory/(.*)$/directory/$1”最后一次执行;“rewrite^/directory/$1”针对允许的IP地址执行,而不是针对那些被“deny all”拒绝的IP地址执行)


谢谢。

您面临的问题与nginx处理其指令的优先级/顺序有关。详细说明如下:

在它们的执行顺序中,阶段是后期读取、服务器重写、, 查找配置、重写、重写后、预访问、访问、访问后、, 尝试文件、内容,最后登录

由于“rewrite”在“access”之前,所以“rewrite”指令首先处理

由于“如果”也是在“重写”阶段处理的,因此可以写:

location ~ \.php$ {
 if ($remote_addr != "172.17.0.1") {
  return 403;
 }
 rewrite ^ /your-redirect last;
}