有没有办法在 VCL *varnish 中动态引用 IP 地址的子网,而无需根据请求创建 ACL?

有没有办法在 VCL *varnish 中动态引用 IP 地址的子网,而无需根据请求创建 ACL?

比如说 72.72.72.72 是客户端 IP,我想将它与具有 IP 72.72.73.72 的令牌或标头进行比较。基本上,我想比较 72.72.72.72 和 72.72.73.72,但动态地比较而没有 ACL。

所以基本上,如果我发出一个令牌作为后端 HTTP 服务并使用带有某些参数(如 IP 地址)的秘密对其进行签名,我希望能够只允许某些 IP 成功使用该令牌。比如,我想允许所有 IP 的 IP 地址为 /20 左右,或者我给出的令牌中的 IP 地址成功使用该令牌。这有意义吗 @djdomi?我知道我可以拆分令牌字符串并获取 IP,然后比较前 3 个八位字节以进行简单的 /24 比较,但有没有更简单的方法比如 /20。您可以使用 ACL 执行此操作,但 ACL 中的所有 IP 都必须在其中。比如,是否可以在不使用 ACL 功能的情况下检查 client.ip ~ client.ip/20。

答案1

我非常困扰,因为我们没有办法解决这个问题开源 varnish 缓存因为这看起来可以在几个小时内完成,所以我写了libvmod-acltools现在。目前,它仅支持将单个转换<ip>/<mask>为 ACL,并且我注意到 Varnish-Cache 的一些限制我们可能想要解决这一问题。

由于 Thijs 为 Varnish-Software 的闭源产品做了广告,所以我想提一下,也有一些像我和 phk 这样的独立开源开发者:

答案2

目前唯一能做到这一点的方法是通过vmod_aclplus,这是一个 Varnish Enterprise VMOD。请参阅https://docs.varnish-software.com/varnish-cache-plus/vmods/aclplus/更多细节。

VCL 代码

下面是一些从标题获取子网的简化代码token

在您的用例中,令牌可能会涉及一些加密技术,并且会使用一些regsub()魔法来从令牌中提取子网。

vcl 4.1;

import aclplus;

sub vcl_recv {
    if (aclplus.match(client.ip, req.http.token) {
        return(synth(403));
    }
}

基本上,该aclplus.match(IP, STRING)函数允许您将 ACL 作为字符串动态传递并将其与 IP 地址匹配。

以下是可以存储在token标题内的潜在值的示例:

127.0.0.1, !192.168.0.1, 192.168.0.0/16, ::1, !::2, fe00::1/16

这意味着您可以在一行中存储多个值。

购买 Varnish Enterprise 许可证

Varnish Enterprise 是 Varnish 的商业版本,需要许可证。请参阅https://www.varnish-software.com/solutions/varnish-enterprise/了解有关许可证的信息。

按使用付费

如果您不想预先购买许可证但仍想使用 Varnish Enterprise vmod_aclplus,您可以在云中运行 Varnish Enterprise 并按“按使用付费”的方式付费。

AWS、Azure 和 GCP 市场上有官方的 Varnish Enterprise 机器映像。

https://www.varnish-software.com/developers/downloads/#cloud-images了解更多信息。

相关内容