Varnish Cache Plus

Total Encryption (crypto)

Varnish 6.0

Description

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.

Example VCL

Memory Encryption

Encrypting malloc, file, and mse (non persistence) using a randomly generated master key.

include "total-encryption/random_key.vcl";

Disk Encryption

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";

Header Encryption

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

Skipping Encryption

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

Alternate Encryption Cipher

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

VMOD API

blob

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 string(BLOB value)

  • Description

    Cast a BLOB to a STRING.

  • Return value

    value as a STRING.

    • value

      The BLOB to convert.

hex_encode

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.

hex_decode

BLOB hex_decode(STRING value)

  • Description

    Hex decode a hex string into a binary BLOB.

  • Return value

    A BLOB.

    • value

      The string to decode.

base64_encode

STRING base64_encode(BLOB value)

  • Description

    Base64 encode a binary (BLOB) value.

  • Return value

    A base64 encoded safe string.

    • value

      The BLOB to encode.

base64_decode

BLOB base64_decode(STRING value)

  • Description

    Base64 decode a string into a binary BLOB.

  • Return value

    A BLOB.

    • value

      The string to decode.

urandom

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).

secret

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.

hash_part

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

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().

hmac

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.

hmac_init

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.

HMAC.set_key

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.

HMAC.add_string

VOID HMAC.add_string(STRING value)

  • Description

    Add a string to the HMAC.

  • Return value

    None

    • value

      String value to add.

HMAC.add_blob

VOID HMAC.add_blob(BLOB value)

  • Description

    Add a blob to the HMAC.

  • Return value

    None

    • value

      The BLOB value to add.

HMAC.get

BLOB HMAC.get()

  • Description

    The the HMAC value. After calling, the HMAC state is reset.

  • Return value

    The HMAC value.

aes_key

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).

aes_encrypt

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.

aes_decrypt

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.

Compatibility notes

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.