使用Firebase Hosting,如何限制PURGE请求只针对特定IP?

5

我有一个托管在Firebase上的网站,使用静态HTML,没有使用服务器端功能来提供结果。

运行curl -X PURGE https://mywebsite.com -v -L时,结果是:

{ "status": "ok", "id": "20755-1619059392-3560756" }

我需要一种方法来限制此操作只允许特定的IP进行,以防止任何人重置我的缓存导致额外的费用。

此外,似乎Firebase使用Varnish来管理缓存(这是我不懂的东西)。

我的客户安全顾问向我们发送了以下建议来处理此问题,我不确定这是否是.htaccess语法或其他:

# Varnish recommends to using PURGE method only by valid user,
# for example by ip limiting and for other return 405 Not allowed:


acl purge { 
 "localhost";
 "192.168.55.0"/24;
}

sub vcl_recv {
 # allow PURGE from localhost and 192.168.55...
 if (req.method == "PURGE") { 
  if (!client.ip ~ purge) {
   return(synth(405,"Not allowed."));
  }
  return (purge);
 }
}

我不知道如何在Firebase Hosting中应用此方法,我没有使用服务器函数,只是使用以下标头的普通firebase.json

      "headers": [
        {
          "source": "*.[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].+(css|js)",
          "headers": [
            {
              "key": "Cache-Control",
              "value": "public,max-age=31536000,immutable"
            }
          ]
        },
        {
          "source": "**/*.@(json|eot|otf|ttf|ttc|woff|font.css)",
          "headers": [
            {
              "key": "Access-Control-Allow-Origin",
              "value": "*"
            }
          ]
        }
      ]

1
最好直接针对Firebase支持,因为它需要关于内部系统和架构的信息。 - samthecodingman
巴,我也遇到了同样的问题。你解决了吗,@Ribal? - odinho - Velmont
同样的问题...@Ribal? - Damien Romito
3个回答

0
以下代码是VCL代码
acl purge { 
 "localhost";
 "192.168.55.0"/24;
}

sub vcl_recv {
 # allow PURGE from localhost and 192.168.55...
 if (req.method == "PURGE") { 
  if (!client.ip ~ purge) {
   return(synth(405,"Not allowed."));
  }
  return (purge);
 }
}

这段代码允许您扩展Varnish的行为。必须将此代码添加到您的/etc/varnish/default.vcl文件中。

在将此代码添加到VCL文件后,您必须重新加载varnishd进程才能激活此VCL配置。

如果无法重新加载varnishd,您可以使用以下命令激活新的VCL文件:

sudo varnishadm vcl.load purge_acl /etc/varnish/default.vcl
sudo varnishadm vcl.use purge_acl

如需了解更多关于VarnishVCL编程语言的信息,请查看http://varnish-cache.org/docs/6.0/reference/index.html


谢谢Thijs。这解释了很多问题,但作为一个Node/JS开发人员,我仍然不知道如何在Firebase项目中应用它。/etc/varnish/default.vcl文件夹结构看起来像是标准的Linux托管,是否可以通过在根目录上创建etc文件夹来应用于Firebase托管?另外,我如何远程连接到Firebase托管以执行您提到的sudo命令来激活新的VCL? - Ribal
@Ribal 抱歉,我不熟悉 Firebase。我只能就 Varnish 相关主题提供建议。但是,我仍然愿意帮助你。你的 Firebase 托管是否实际支持 Varnish?如果是,Varnish 是否托管在部署代码库的同一台机器上? - Thijs Feryn
在Firebase控制台或GCloud中没有提到Varnish的地方,但是当我运行PURGE命令时,响应中会得到以下内容“X-Varnish:2860902786 Via:1.1 varnish”,这使我标记了Varnish,但除此之外没有其他参考(而且老实说,这是我第一次了解Varnish),我仍然在试图研究这个话题。与此同时,您认为贵公司是否有人对Firebase更熟悉,并可能帮助我们解决这个问题? - Ribal
难道您的Firebase应用程序前面只安装了Varnish吗?您能否对接受PURGE请求的IP地址进行IP WHOIS查询?我想知道这是Firebase IP还是某些第三方托管提供商提供的Varnish IP地址。 - Thijs Feryn
这是我可以执行IP WHOIS的地方吗?https://www.site24x7.com/find-ip-address-of-web-site.html?如果是,我已经执行了,结果对我来说看起来很奇怪...客户名称是保密的,所以我将其替换为“abcdef”。奇怪的部分是网站是`abcdef.om`,而IP结果删除了第一个字母并返回以下内容:`bcdef.om./23.6.99.23`,您觉得这正常吗? - Ribal
只需对您使用的域名进行ping测试,并找到一个IP WHOIS网站。这里有一个23.6.99.23的示例:https://whatismyipaddress.com/ip/23.6.99.23。我不确定这是否是您实际的IP地址,但如果是,则该IP指向Akamai,这是CDN提供商。在这种情况下,Akamai执行缓存,他们不使用Varnish而是使用自己的技术。一旦您找到了IP并知道谁托管它,我就无法再提供更多帮助了。如何进入他们的Varnish平台取决于您自己。 - Thijs Feryn

0

目前还没有解决方案。这是我从 Firebase 支持团队那里收到的答复:

嗨,Damien,

我是 Sergei,感谢您的联系。我将为您提供协助。

首先需要解决的问题是 Varnish 服务不在我们范围内,因此我们关于其与我们的托管服务实现的信息并不是最丰富的。

不幸的是,目前我们只能通过现有的工具来控制缓存行为。

很抱歉我们不能在此时提供您所需的功能,如果您愿意,我们可以提交特性请求,以便我们的工程团队了解此需求。


0
如果在使用Firebase Hosting时没有解决方案,或者Varnish不可用,可以尝试其他解决方案,例如使用云函数。
也许需要根据某些情况调整"function"配置部分的内容。
firebase.json (Hosting行为)
...
 "rewrites": [
   {
     "source": "**/*.@(json|eot|otf|ttf|ttc|woff|font.css)",
     "function": "no_purge"
   }
 ]
...

/functions/index.js (云函数)

const functions = require('firebase-functions');

exports.no_purge = functions.https.onRequest((req, res) => {

 if(req.method == 'PURGE') {    /* complete this condition to allow specific IPs */
   res.status(405).send('<!doctype html>
     <head>
       <title>PURGE Not allowed</title>
     </head>
     <body>
       PURGE Not allowed
     </body>
   </html>');
  }
});

我知道如果你想要一个简单的动态解决方案,Varnish更适合。
希望这能帮到你,因为我目前没有测试这个的基础设施。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接