禁止通过直接 URL 调用 cgi,但允许通过 RewriteRule 调用

禁止通过直接 URL 调用 cgi,但允许通过 RewriteRule 调用

我想允许匿名客户端通过特殊 URL 执行脚本,但不能直接执行。其他一切都需要身份验证。

<Directory "/srv/http">
    Require all granted
</Directory>

<Directory "/srv/http/html">
    RewriteRule ^hello/dostuff/(.*)$ /cgi-bin/hello.sh?anon=1&x=$1 [B]
</Directory>

# require auth for everything with one exception below
<Location />
    AuthType Basic
    AuthName intranet
    AuthUserFile "conf/passwd"
    Require user test
</Location>

# allow anonymous access inside /hello/
<Location /hello/>
    Require all granted
</Location>

/hello/foobar按照预期给了我 404,但/hello/dostuff/foobar要求输入密码。似乎<Location />检查进行了两次:重写之前和之后:

访问日志:

192.168.65.1 - - [22/Oct/2015:12:49:04 +0300] "GET /hello/dostuff/foobar HTTP/1.1" 401 381

错误日志:

[Thu Oct 22 12:49:04 2015] AH01626: authorization result of Require all granted: granted URI:/hello/dostuff/foobar
[Thu Oct 22 12:49:04 2015] AH01626: authorization result of <RequireAny>: granted URI:/hello/dostuff/foobar
[Thu Oct 22 12:49:04 2015] AH01626: authorization result of Require user test: denied (no authenticated user yet) URI:/cgi-bin/hello.sh
[Thu Oct 22 12:49:04 2015] AH01626: authorization result of <RequireAny>: denied (no authenticated user yet) URI:/cgi-bin/hello.sh

完整会议:

ServerRoot "/etc/httpd"
Listen 80
LoadModule cgi_module modules/mod_cgi.so
LoadModule alias_module modules/mod_alias.so
LoadModule unixd_module modules/mod_unixd.so
LoadModule rewrite_module modules/mod_rewrite.so

LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authn_core_module modules/mod_authn_core.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule access_compat_module modules/mod_access_compat.so
LoadModule auth_basic_module modules/mod_auth_basic.so
LoadModule reqtimeout_module modules/mod_reqtimeout.so
LoadModule include_module modules/mod_include.so
LoadModule filter_module modules/mod_filter.so
LoadModule mime_module modules/mod_mime.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule env_module modules/mod_env.so
LoadModule headers_module modules/mod_headers.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule version_module modules/mod_version.so
LoadModule mpm_event_module modules/mod_mpm_event.so

User http
Group http

DocumentRoot "/srv/http/html"

RewriteEngine On

<Directory />
    AllowOverride none
    Require all denied
</Directory>

<Directory "/srv/http">
    Require all granted
</Directory>

<Directory "/srv/http/html">
    RewriteRule ^hello/dostuff/(.*)$ /cgi-bin/hello.sh?anon=1&x=$1 [B]
</Directory>

<Files ".ht*">
    Require all denied
</Files>
<IfModule log_config_module>
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common
    <IfModule logio_module>
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
    </IfModule>
    CustomLog "/var/log/httpd/access_log" common
</IfModule>

SetEnvIf Request_URI "(^.*$)" RURI=$1

ErrorLog "/var/log/httpd/error_log"
LogLevel debug
#ErrorLogFormat "[%t] [%l] [pid %P] %F: %E: [client %a] %M URI:%{RURI}e"
ErrorLogFormat "[%t] %M URI:%{RURI}e"

<IfModule alias_module>
    ScriptAlias /cgi-bin/ "/srv/http/cgi-bin/"
</IfModule>
<Directory "/srv/http/cgi-bin">
    AllowOverride None
    Options None
    Require all granted
</Directory>
<IfModule mime_module>
    TypesConfig conf/mime.types
    AddType application/x-compress .Z
    AddType application/x-gzip .gz .tgz
</IfModule>

# require auth for everything with one exception below
<Location />
    AuthType Basic
    AuthName intranet
    AuthUserFile "conf/passwd"
    Require user test
</Location>

# allow anonymous access inside /hello/
<Location /hello/>
    Require all granted
</Location>

答案1

为您的 httpd启用LogLevel debug。在生成的日志条目中,您可能会发现,即使用旧语法访问规则(如Allow from ...Satisfy ...)会产生意外结果,尤其是与新样式(<RequireAny><RequireAll>等)混合使用时。使用 httpd 2.4 时,您应该只使用新语法以避免此类问题。

除此之外,我相信您想要匹配^/hello/dostuff/...- 注意您的配置中缺少的前导斜杠。

答案2

设置一个变量let_me_inRewriteRule不仅在用户授权时授予访问权限,而且在设置此变量时也授予访问权限:

<Directory "/srv/http/html">
    RewriteRule ^hello/dostuff/(.*)$ /cgi-bin/hello.sh?anon=1&x=$1 [B,E=let_me_in]
</Directory>

<Location />
    AuthType Basic
    AuthName intranet
    AuthUserFile "conf/passwd"
    Require user test
    Require env REDIRECT_let_me_in
</Location>

相关内容