使用 Varnish 缓存后面的 Apache 来保护对某些页面/目录的访问?

使用 Varnish 缓存后面的 Apache 来保护对某些页面/目录的访问?

我有一个公共网站,其中包含一些仅供私人/内部使用的 URL/目录。这些私人区域只能通过某些 IP 地址或已知的用户名/密码访问。

目前我通过这样的 .htaccess 文件实现此目的:

AuthType     Basic
AuthName     "Protected Area"
AuthUserFile /path/to/.htpasswd

SetEnvIf Remote_Addr     1.2.3.4 trusted
SetEnvIf X-Forwarded-For 1.2.3.4 trusted
# (Note I am aware X-Forwarded-For can be spoofed)

<RequireAny>
    Require env trusted
    Require valid-user
</RequireAny>

问题是我想在服务器前面添加 Varnish 来提供缓存。显然现有设置不适用于 Varnish,因为它无法以这种方式缓存受 .htaccess 文件限制的内容。

有没有什么方法可以让我继续使用我的 .htaccess 文件来保护我的内部页面,或者有没有类似的方法可以将安全责任放在 Varnish 本身上,而不需要每次我想要添加或修改限制时都更改 Varnish 的 VCL 文件?

答案1

您可以通过编写以下 VCL 在 Varnish 中完成此操作:

vcl 4.0;

acl allowed {
  "1.2.3.4";
}

sub vcl_recv {
    if(!client.ip ~ allowed && req.http.Authorization != "YWRtaW46YWRtaW4K") {
        return (synth(401, "Restricted"));
    }
    return (hash);
}

sub vcl_synth {
    if (resp.status == 401) {
        set resp.http.WWW-Authenticate =
            {"Basic realm="Restricted area""};
    }
}

限制

虽然这可以正常工作,但用户名/密码检查是手动完成的。如果您有多个用户名/密码,则必须在 if 语句中添加每个用户。

确保绕过默认的 VCL 行为

在 Varnish 中处理Authorization标题时,重要的是不要回到默认行为。Authorization默认情况下,当存在标头时,Varnish 不会在缓存中查找项目。

因此,在您的逻辑中,您必须执行return (hash);,正如我在示例中所做的那样。否则,您将回到默认行为,并且不会在缓存中查找项目。

Vmod_basicauth 作为替代方案

如果这成为一个交易破坏者,您可以编译以下 Varnish 模块,该模块允许您加载文件.htpasswd并为您执行身份验证。

仍然在 Apache 中完成所有工作

如果您决定继续在 Apache 中执行此操作,您还需要更改 VCL。我解释说,当Authorization存在标头时,默认行为将阻止 Varnish 在缓存中查找项目。

如果你再看看默认行为再次强调,你必须确保return (hash);在达到默认行为之前执行,否则你必须自己重新实现其中的一部分,添加必要的if 语句

相关内容