4

I have a website hosted on Firebase, using static html, no server-side function is used to deliver the result.

When running curl -X PURGE https://mywebsite.com -v -L the result is:

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

I need a way to restrict this action to specific IPs so that not anybody can reset my cache which might result in extra costs.

Also it seems that Firebase uses Varnish to manage cache (which is something am null at).

My client's security consultant sent us this recommendation on how to handle this issue, I'm not sure exactly if this is .htaccess syntax or what:

# 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);
 }
}

I don't know how to apply this in Firebase Hosting, again am not using Server Functions, just the regular firebase.json with the following headers:

      "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": "*"
            }
          ]
        }
      ]
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Ribal
  • 146
  • 1
  • 5

3 Answers3

0

The following code is VCL code:

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);
 }
}

This code allows you to extend the behavior of Varnish. This code has to be added to your /etc/varnish/default.vcl file.

After adding this code to your VCL file, you have to reload your varnishd process to activate this VCL configuration.

If reloading varnishd is not an option, you can also activate the new VCL file using the following commands:

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

For more information about Varnish and the VCL programming language, please have look at http://varnish-cache.org/docs/6.0/reference/index.html

Thijs Feryn
  • 3,982
  • 1
  • 5
  • 10
  • Thank you Thijs. This clarifies a lot, however as node/js developer am still struggling on how to apply this in a Firebase project. the `/etc/varnish/default.vcl` folder structure looks like a standard linux hosting, can this be applied in Firebase hosting by creating and `etc` folder on the root? Also how can i remotely connect to the Firebase hosting to perform the sudo commands u mentioned to activate the new VCL? – Ribal May 07 '21 at 07:37
  • @Ribal Sorry, but I'm unfamiliar with Firebase. I can only advise on Varnish related topics. However, I'm still willing to help. Does your Firebase hosting actually support Varnish? And if so, is Varnish hosted on the same machine as your deployed codebase? – Thijs Feryn May 07 '21 at 08:05
  • There's no place in Firebase Console or GCloud that mention Varnish, however when i run the PURGE command i get the following in the response `X-Varnish: 2860902786 Via: 1.1 varnish` which made tag Varnish in this question, but other than that there is no other reference (and honestly this is the first time i learn about varnish).. am still trying to research this topic. Meanwhile do you think there is anyone in your company who might be more familiar with Firebase and can maybe help us with this? – Ribal May 07 '21 at 08:11
  • Could it be that Varnish is just installed in front of your Firebase application? Can you do an IP WHOIS of the IP address that is accepting the PURGE requests? I'd like to know if this is a Firebase IP or an IP address of some third-party hosting provider that offers Varnish. – Thijs Feryn May 08 '21 at 07:13
  • is this where i can perform the IP WHOIS https://www.site24x7.com/find-ip-address-of-web-site.html? if yes, i did and the result looks weird to me.. the client name is confidential so am gonna replace with 'abcdef'. the weird part is that the website is `abcdef.om` and the ip result removes the first letter and returns the following: `bcdef.om./23.6.99.23`, does this look normal to u? – Ribal May 10 '21 at 09:00
  • Just do a ping of the domain that you use and find an IP WHOIS site. Here's an example for `23.6.99.23`: https://whatismyipaddress.com/ip/23.6.99.23. I'm not sure this is your actual IP, but if it is, the IP points to Akamai, which is a CDN provider. In that case Akamai does the caching and they don't use Varnish but their own technology. Once you've found the IP and you know who hosts it, I can't really help anymore. It's up to you to figure how to get on their Varnish platform. – Thijs Feryn May 10 '21 at 11:18
0

There is no solution for the moment. This is the answer I received from the firebase support :

Hi Damien,

My name is Sergei, thanks for reaching out. I'll be assisting you.

The first thing to be addressed here is the fact that Varnish services fall outside of our scope, so our information about its implementations with our hosting services are not the most abundant.

Unfortunately, right now we can only control the caching behavior with our existing tools.

I am sorry we cannot provide the functionality you need at the time, if you would like to, we can submit the feature request so this is visible to our engineering team.

Damien Romito
  • 9,801
  • 13
  • 66
  • 84
0

If no solution with Firebase Hosting or if Varnish isn't available, maybe try a different solution, for example with a cloud function.

Maybe need to adapt content of "function" configuration part in some cases.

firebase.json (Hosting behavior)

...
 "rewrites": [
   {
     "source": "**/*.@(json|eot|otf|ttf|ttc|woff|font.css)",
     "function": "no_purge"
   }
 ]
...

/functions/index.js (Cloud Function)

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>');
  }
});

I know Varnish is more suitable if you want a simple dynamic solution.

Hope this will help as I currently don't have the infrastructure to test this.