如何使用 Apache 2.4 拒绝除一个 IP 之外的所有 IP 的访问,并允许所有 IP 访问特定的 URI

如何使用 Apache 2.4 拒绝除一个 IP 之外的所有 IP 的访问,并允许所有 IP 访问特定的 URI

我需要阻止公众访问网站,但允许一个 IP 地址访问。我需要向公众授予几个 URI 的访问权限。但没有任何效果 - 要么全部被阻止,要么全部开放。

Apache conf 的简化摘录:

<Directory /site/dir>
    Require ip 1.2.3.4
</Directory>

<Location "/open/for/public1">
    Require all granted
</Location>
<Location "/open/for/public2">
    Require all granted
</Location>

现在一切都被封锁了。

还尝试使用旧语法:

<Location "/open/for/public1">
    Order allow,deny
    allow from all
</Location>

还是一样。

我尝试使用 <Location "/"> 指令(而不是 <Directory> 指令)来阻止站点,但 public1 和 public2 也被阻止了。

我尝试过:

SetEnvIf Request_URI "^/open/for/public1$" NO_AUTH_NEEDED=1
<Directory /site/dir>
    Order Deny,Allow
    Deny from all
    Allow from env=NO_AUTH_NEEDED
    Allow from 1.2.3.4
</Directory>

不起作用,全部被阻塞。

欢迎提出任何建议

答案1

最终帮助我的是 Apache Rewrite 规则和日志级别警报重写:trace6。在这种情况下,除了一些 .htaccess 文件(我认为没有任何效果)之外,代码中还有一些内部重定向。所以我最终在 VirtualHost 部分使用了类似以下内容:

RewriteCond %{REMOTE_ADDR} !1.2.3.4
RewriteCond %{REQUEST_URI} !^/open/for/public(.*) [NC]
RewriteRule .* - [F]

在.htaccess 中:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [END]

我补充说[结尾]并且它似乎非常重要,因为如果没有它,Rewrite 引擎将继续运行,并且由于某种原因,会出现一些内部重定向(来自 Apache 日志:...使用 /index.php 进行内部重定向 [内部重定向])URL 被破坏,并且重写规则。- [F]* 每次都会触发。

答案2

在第一个例子中,我认为您被阻止是因为该Directory指令接管了Location指令:

<Directory /site/dir>
    Require ip 1.2.3.4
</Directory>

<Location "/open/for/public1">
    Require all granted
</Location>

<Location "/open/for/public2">
    Require all granted
</Location>

有很多方法可以实现你的愿望。

  • 对我来说,第一种可行的方法是Location仅使用指令(使用真实和虚假的 IP 进行测试,公共 URL 是我的系统上的真实文件):

      DocumentRoot /site/dir
    
      <Location />
          Require ip 1.2.3.4
      </Location
    
      <Location "/open/for/public1">
          Require all granted
      </Location>
    
      <Location "/open/for/public2">
          Require all granted
      </Location>
    

    根据Location指令,秩序很重要在以下示例中,我到处都会被阻止,因为最后一个块覆盖了其他块:

      <Location "/open/for/public1">
          Require all granted
      </Location>
    
      <Location "/open/for/public2">
          Require all granted
      </Location>
    
      <Location />
          Require ip 1.2.3.4
      </Location
    
  • 我还测试了使用Directory指令。在这种情况下,顺序无所谓指令按照最短匹配优先的顺序应用

      <Directory /site/dir>
          Require ip 1.2.3.4
      </Directory>
    
      <Directory "/site/dir/open/for/public1">
          Require all granted
      </Location>
    
     <Directory "/site/dir/open/for/public2">
         Require all granted
     </Directory >
    

    要在DirectoryLocation指令之间进行选择,请参阅Apache 建议

  • 下面是另一个使用以下方法测试的示例mod_rewrite

      <Directory /var/www/site/>
    
          # first, allow all 
          Require all granted
    
          # Then enable rewrite engine   
          RewriteEngine On
    
          # Requests that: 
          # do not start with 'test' (test is a real folder supposed open to public)
          RewriteCond %{REQUEST_URI} !^/test
    
          # AND that do not start with 'another_test'
          RewriteCond %{REQUEST_URI} !^/another_test
    
          # AND ...
    
          # AND that do not come from given IP
          RewriteCond "%{REMOTE_ADDR}"  !1.2.3.4
    
          # are blocked (403 Forbidden)
          RewriteRule .* - [F]
      </Directory>
    

相关内容