Block Unauthorized Requests at Varnish [Code Optimization]

Guillaume Quintard guillaume.quintard at gmail.com
Thu Oct 12 19:05:36 UTC 2023


> In the above example, if the request URL is source=tablet [for which
condition is present at the end], still I have to check all the above
conditions.

That's mainly how computers work, processing will be linear. You *could*
create a vmod that packs ACLs into a hashmap to simplify the apparent
logic, but you will pay that price developing the vmod, and for a very
modest performance gain. If you have less than 50 sources, or even less
than a 100, I don't think it's worth agonizing over that kind of
optimization (unless you've actually measured and you did see a
performance drop).

> One thing I would do though is to generate the VCL from a source file,
like a YAML one:

All I'm saying is that you should focus on increasing the maintainability
of the project before worrying about performance. I assume that the VCL is
currently committed in a repo somewhere and gets edited every time you need
to add a new IP or source. If so, it's not great because editing such
repetitive code is error-prone, and therefore you should use templating to
create the VCL from a simpler, more maintainable source.

Tools like go templates or jinja can provide that feature and save you from
repeating yourself when writing configuration.

-- 
Guillaume Quintard


On Thu, Oct 12, 2023 at 11:46 AM Uday Kumar <uday.polu at indiamart.com> wrote:

> Hi Guillaume,
>
> I don't think those are redundant checks, from what you are showing, they
> are all justified. Sure, there may be a bunch of them, but you have to go
> through to them.
>
> By redundant I meant, I have to write multiple checks for each source and
> list of IPs associated with it. [which would be *worse *if the number of
> sources are huge]
>
> *Example:*
>
> If(
>
> (req.url ~ "source=mobile" && client.ip != mobile_source) ||
>
> (req.url ~ "source=desktop" && client.ip != desktop_source) ||
>
> (req.url ~ "source=laptop" && client.ip != laptop_source) ||
>
> (req.url ~ "source=tablet" && client.ip != tablet_source)
>
> ){
>
>            return(Synth(403, "access denied!"))
>
> }
>
>
> In the above example, if the request URL is source=tablet *[for which
> condition is present at the end]*, still I have to check all the above
> conditions.
>
>
>
>
>
> One thing I would do though is to generate the VCL from a source file,
> like a YAML one:
>
> Didn't understand, can you please elaborate?
>
> Thanks & Regards
> Uday Kumar
>
>
> On Thu, Oct 12, 2023 at 11:11 PM Guillaume Quintard <
> guillaume.quintard at gmail.com> wrote:
>
>> Hi Uday,
>>
>> I don't think those are redundant checks, from what you are showing, they
>> are all justified. Sure, there may be a bunch of them, but you have to go
>> through to them.
>>
>> One thing I would do though is to generate the VCL from a source file,
>> like a YAML one:
>>
>> mobile:
>>   - IP1
>>   - IP2
>>   - IP3
>> desktop:
>>   - IP4
>>   - IP5
>>   - IP6
>>
>>
>> From that, you can build the VCL without having to manually write
>> "client.ip" or "(req.url ~ "source=" every time.
>>
>> --
>> Guillaume Quintard
>>
>>
>> On Thu, Oct 12, 2023 at 10:17 AM Uday Kumar <uday.polu at indiamart.com>
>> wrote:
>>
>>> Hello everyone,
>>>
>>> We use varnish in our production environment for caching content.
>>>
>>> Our Requirement:
>>>
>>> We are trying to block unauthorized requests at varnish based on the
>>> source parameter in the URL and the client IP in the request header.
>>>
>>> For example:
>>>
>>> Sample URL:
>>>
>>> www.hostname:port/path?source=mobile&keyword= bags
>>>
>>> Let's assume there are 3 IPs [which are allowed to access varnish]
>>> associated with the above request of mobile source.
>>>
>>> i.e *IP1, IP2, IP3*
>>>
>>> So if any request comes with the source as *mobile *and client-ip as
>>> *IP4*, it's treated as an unauthorized request and should be blocked at
>>> varnish.
>>>
>>>
>>> What we have done for blocking?
>>>
>>> *Sample URL:*
>>> www.hostname:port/path?source=mobile&keyword= bags
>>>
>>> Created a map using ACL as below:
>>>
>>> acl mobile_source{
>>>
>>>               "IP1";
>>>
>>>               "IP2";
>>>
>>>               "IP3";
>>>
>>> }
>>>
>>> If(req.url ~ "source=mobile" && client.ip !~ mobile_source) {
>>>
>>>            return(Synth(403, "varnish access denied!"))
>>>
>>> }
>>>
>>>
>>> The problem we are facing:
>>>
>>> The source parameter can have different values like mobile, desktop,
>>> laptop, tablet, etc. and each value can have different IPs associated with
>>> it.
>>>
>>> ACL Rules will be as below:
>>>
>>> acl mobile_source{
>>>
>>>               "IP1";
>>>
>>>               "IP2";
>>>
>>>               "IP3";
>>>
>>> }
>>>
>>> acl desktop_source{
>>>
>>>               "IP4";
>>>
>>>               "IP5";
>>>
>>>               "IP6";
>>>
>>> }
>>>
>>> and so on,
>>>
>>>
>>> If we wanted to block unauthorized access from different source vs IP
>>> combinations, we would have to add that many conditions as below.
>>>
>>> If(
>>>
>>> (req.url ~ "source=mobile" && client.ip != mobile_source) ||
>>>
>>> (req.url ~ "source=desktop" && client.ip != desktop_source) ||
>>>
>>> (req.url ~ "source=laptop" && client.ip != laptop_source) ||
>>>
>>> (req.url ~ "source=tablet" && client.ip != tablet_source)
>>>
>>> ){
>>>
>>>            return(Synth(403, "access denied!"))
>>>
>>> }
>>>
>>> This becomes worse, if we have 10's or 20's of source values.
>>>
>>> Our question:
>>>
>>> We would like to know if there is any way to optimize the code by
>>> removing redundant checks so that we can scale it even if we have many
>>> sources vs IP combinations.
>>>
>>>
>>> Thanks & Regards
>>> Uday Kumar
>>> _______________________________________________
>>> varnish-misc mailing list
>>> varnish-misc at varnish-cache.org
>>> https://www.varnish-cache.org/lists/mailman/listinfo/varnish-misc
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.varnish-cache.org/lists/pipermail/varnish-misc/attachments/20231012/02fbfcd5/attachment-0001.html>


More information about the varnish-misc mailing list