Varnish Total Encryption provides cache encryption and a VCL based crypto API. Varnish Total Encryption uses an innovative dual key encryption algorithm with one key securely stored in the Linux kernel and the other key generated from the client request. No keys are ever stored in Varnish or in cache and every object has its own unique key.
Click here to learn more about Varnish Total Encryption.
Encrypting malloc
, file
, and mse
(non persistence) using a randomly generated master key.
include "total-encryption/random_key.vcl";
Encrypting mse
with persistence enabled using a local secret key.
First, generate a new secret key:
$ cat /dev/urandom | head -c 1024 > /etc/varnish/disk_secret
$ sudo chmod 600 /etc/varnish/disk_secret
$ sudo chown root: /etc/varnish/disk_secret
Add the key to the varnishd
systemd unit configuration.
This allows the disk_secret
to be securely read via the varnishd
jail configuration:
ExecStart=/usr/sbin/varnishd ... -E /etc/varnish/disk_secret
For more information on how to do this, please see our systemd reference.
Use the secret key to encrypt cache:
include "total-encryption/secret_key.vcl";
When using one of the above Total Encryption includes, you can optionally encrypt headers with the following VCL:
sub vcl_backend_response {
# Encrypt beresp.http.Content-Type
set beresp.http.Content-Type = crypto.hex_encode(crypto.aes_encrypt(beresp.http.Content-Type));
}
sub vcl_deliver {
# Decrypt resp.http.Content-Type
if (resp.http.Content-Type != "") {
set resp.http.Content-Type = crypto.aes_decrypt(crypto.hex_decode(resp.http.Content-Type));
}
}
Use crypto.aes_skip_response()
to skip encryption or decryption in
vcl_backend_response
or vcl_deliver
.
sub vcl_backend_response {
if (beresp.http.Content-Type ~ "video") {
crypto.aes_skip_response();
}
}
By default Varnish Total Encryption uses Cipher Block Chaining (CBC) AES encryption. On some systems, Propagating Cipher Block Chaining (PCBC) is available hardware accelerated. If so, use the following VCL to use PCBC AES encryption:
sub vcl_init {
te_opts.set("algorithm", "pcbc(aes)");
}
Generate a cookie based random ID string (UUID).
import crypto;
import cookieplus;
sub vcl_deliver
{
# ID format: 5a580f83ff659c9554b91e06c90ae7f1
if (!cookieplus.get("id")) {
cookieplus.setcookie_add("id", crypto.hex_encode(crypto.urandom()));
cookieplus.setcookie_write();
}
# ID format: 06d1ee05-ad8d-0e22-563f-8f9bd5b59bec
if (!cookieplus.get("id2")) {
cookieplus.setcookie_add("id2", crypto.uuid_v4());
cookieplus.setcookie_write();
}
}
BLOB blob(STRING value)
Description
Cast a STRING to a BLOB. If using a STRING based secret, this function must be used to cast the secret to a BLOB.
Return value
value
as a BLOB.
value
The STRING to cast.
STRING string(BLOB value)
Description
Cast a BLOB to a STRING.
Return value
value
as a STRING.
value
The BLOB to convert.
STRING hex_encode(BLOB value)
Description
Hex encode a binary (BLOB) value. Lowercase hex is used.
Return value
A hex encoded safe string.
value
The BLOB to encode.
BLOB hex_decode(STRING value)
Description
Hex decode a hex string into a binary BLOB.
Return value
A BLOB.
value
The string to decode.
STRING base64_encode(BLOB value)
Description
Base64 encode a binary (BLOB) value.
Return value
A base64 encoded safe string.
value
The BLOB to encode.
BLOB base64_decode(STRING value)
Description
Base64 decode a string into a binary BLOB.
Return value
A BLOB.
value
The string to decode.
BLOB urandom(INT bytes = 16)
Description
Get bytes from /dev/urandom
.
Return value
Random bytes.
value
The number of bytes to get. Defaults to 16 (128bit).
STRING uuid_v4()
Description
Get a version 4 UUID.
Return value
A version 4 UUID string.
BLOB secret()
Description
Get the contents of the secret file from the command line parameter -E
.
If using Total Encryption secret key, this value will be scrubbed and the return value will be empty.
Return value
The secret file contents.
VOID hash_part(ENUM algorithm, STRING part)
Description
Add a string to a hash. Use hash()
to get the final value.
Return value
None
algorithm
The hashing algorithm: md5
, sha1
, sha224
, sha256
, sha384
, sha512
part
The string to add to a hash
BLOB hash(ENUM algorithm, STRING value)
Description
Hash a value. After calling this, the hash state is reset.
Return value
The hash value.
algorithm
The hashing algorithm: md5
, sha1
, sha224
, sha256
, sha384
, sha512
value
The string to hash. This value will be combined with previous uses of hash_part()
.
BLOB hmac(ENUM algorithm, BLOB key, STRING value)
Description
Perform an HMAC operation.
Return value
The HMAC value.
algorithm
The hashing algorithm: md5
, sha1
, sha224
, sha256
, sha384
, sha512
key
The HMAC key to use.
value
The value to HMAC.
OBJECT hmac_init(ENUM algorithm, STRING cache_name)
Description
Create a new HMAC signing object. This object using the Linux Kernel Crypto API for signing. The HMAC key used is securely stored in the kernel and not kept in the Varnish address space.
Return value
A new object;
algorithm
The hashing algorithm: md5
, sha1
, sha224
, sha256
, sha384
, sha512
cache_name
If used, this object will retain a reference to its key across reloads.
VOID HMAC.set_key(BLOB key)
Description
Set the key of an HMAC signing object. Can only be used in vcl_init
.
Return value
None
value
The key to use. The key is securely transfered to the kernel and scrubbed from user space memory after reading.
VOID HMAC.add_string(STRING value)
Description
Add a string to the HMAC.
Return value
None
value
String value to add.
VOID HMAC.add_blob(BLOB value)
Description
Add a blob to the HMAC.
Return value
None
value
The BLOB value to add.
BLOB HMAC.get()
Description
The the HMAC value. After calling, the HMAC state is reset.
Return value
The HMAC value.
VOID aes_key(BLOB key, BLOB salt, STRING algorithm)
Description
Set an AES key. This is request scope only. The Linux Kernel Crypto API is used.
NOTE
If using Total Encryption, this can be safely used in vcl_recv
only.
This is automatically called in vcl_backend_response
and vcl_deliver
with a key
unique to the request. Please contact support for advanced usage.
Return value
None
key
The key to use. Must be a 128, 192, or 256 bit value. The key is securely transfered to the kernel and scrubbed from user space memory after reading.
salt
The salt (IV) to use. Must be a 128 bit value. Optional.
algorithm
The AES algorithm to use. Check /proc/crypto
for supported algorithms.
Defaults to aes(cbc)
.
BLOB aes_encrypt(STRING value)
Description
AES encrypt a value. The block size is 16 bytes and the result is NULL padded.
Return value
The value encrypted.
value
The value to encrypt.
STRING aes_decrypt(BLOB value)
Description
AES decrypt a value. The block size must be 16 bytes.
Return value
The decrypted value.
value
The value to decrypt.
To support this vmod, the kernel needs to be compiled with
CRYPTO_USER_API_HASH
. Note that stock kernels on all supported platforms
already fulfill that requirement.