Mailing List Archive

Is there any "try catch" functionality in VCL? If not, how to handle runtime errors in vcl_init?
Hi,

We use the vmod crypto to verify cryptographic signatures for some of our traffic. When testing, the public key was hard coded in the VCL, but before we start using this feature in production we will switch to reading the public key from a file on disk. This file is generated on server startup, by fetching it from an Azure keyvault.

Now, the problem I'm picturing here is that this fetching of the public key can fail, or the key can be corrupt or empty, maybe by user error. Or the key could be valid, but the format of the key happens to be unsupported by the vmod crypto. So, even if we do our best to validate the key, in theory it could pass all our tests but still fail when we give it to the vmod crypto. And if that happens, Varnish won't start because the vmod crypto is initiated with the public key in vcl_init, like this:

sub vcl_init {
new cryptoVerifier = crypto.verifier(sha256, std.fileread("/path/to/public.key"));
}

What I would prefer to happen if the key is rejected, is that vcl_init goes through without failure, and then the requests that use the cryptoVerifier will fail, but all other traffic (like 99%) still works. Can we achieve this somehow? Like some try-catch functionallity? If not, is there some other way to handle this that doesn't cause Varnish to die on startup?
Re: Is there any "try catch" functionality in VCL? If not, how to handle runtime errors in vcl_init? [ In reply to ]
On Wed, Apr 19, 2023 at 4:25?PM Batanun B <batanun@hotmail.com> wrote:
>
> Hi,
>
> We use the vmod crypto to verify cryptographic signatures for some of our traffic. When testing, the public key was hard coded in the VCL, but before we start using this feature in production we will switch to reading the public key from a file on disk. This file is generated on server startup, by fetching it from an Azure keyvault.
>
> Now, the problem I'm picturing here is that this fetching of the public key can fail, or the key can be corrupt or empty, maybe by user error. Or the key could be valid, but the format of the key happens to be unsupported by the vmod crypto. So, even if we do our best to validate the key, in theory it could pass all our tests but still fail when we give it to the vmod crypto. And if that happens, Varnish won't start because the vmod crypto is initiated with the public key in vcl_init, like this:
>
> sub vcl_init {
> new cryptoVerifier = crypto.verifier(sha256, std.fileread("/path/to/public.key"));
> }
>
> What I would prefer to happen if the key is rejected, is that vcl_init goes through without failure, and then the requests that use the cryptoVerifier will fail, but all other traffic (like 99%) still works. Can we achieve this somehow? Like some try-catch functionallity? If not, is there some other way to handle this that doesn't cause Varnish to die on startup?

It's the VMOD author you should ask to have an option to ignore public
key errors.

This is a constructor, and even if we had a try-catch kind of
construct in the language, I don't think we would make this one
recoverable.

Dridi
_______________________________________________
varnish-misc mailing list
varnish-misc@varnish-cache.org
https://www.varnish-cache.org/lists/mailman/listinfo/varnish-misc
Re: Is there any "try catch" functionality in VCL? If not, how to handle runtime errors in vcl_init? [ In reply to ]
> It's the VMOD author you should ask to have an option to ignore public
> key errors.

Well, I'm usually of the mindset that if a problem can be handled in a generic way by the language/platform/framework, then one should avoid requiring each and every custom vmod/plugin/library to handle it individually. And I'm also of the mindset that pretty much any non-trivial code can fail, and the calling code should be able to catch that if needed. :)

> This is a constructor, and even if we had a try-catch kind of
> construct in the language, I don't think we would make this one
> recoverable.

In my mind, with a try-catch I could handle it like this:

try {
new cryptoVerifier = crypto.verifier(sha256, std.fileread("/path/to/public.key"));
} catch (error) {
// log error...
// then try with with a hard coded known safe key, but that will fail when checking the signature
new cryptoVerifier = crypto.verifier(sha256, (sha256, {"
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
"});
}

With this approach, Varnish will start like normal. And the only requests failing will be the ones using the cryptoVerifier.
Re: Is there any "try catch" functionality in VCL? If not, how to handle runtime errors in vcl_init? [ In reply to ]
Just to explain my concern a bit. The worst case?scenario in production, that I very much would like to avoid, could look something like this:

1. Something happens with our public key, so that Varnish won't be able to start after getting the new faulty key. Already running servers will continue to run, but no new servers can be initiated.
2. Before we have been able to fix the problem with the public key, some other problem happens in Varnish, and all running Varnish servers dies.
3. We end up with no working Varnish servers running, and not being able to start any new ones.
4. All our websites are down.
_______________________________________________
varnish-misc mailing list
varnish-misc@varnish-cache.org
https://www.varnish-cache.org/lists/mailman/listinfo/varnish-misc