Table of Contents

Use Disk Cache

To use the disk cache instead of the memory cache, edit the Varnish command line and locate the -s argument and change it from:

-s malloc,256m

which uses memory storage of 256MiB, to:

-s file,/var/cache/varnish/varnish_storage.bin,10G

where:

Passing the Real IP Address to Apache from Cloudflare

The following are some notes on getting the real IP address passed to Apache when Varnish and Cloudflare sit in front of Apache. For this to work, all other "real IP" Apache modules must be disabled, such as "rpaf" or "remoteip", and only Varnish left to pass the real IP address to Apache. In other words, this works for the following configuration:

If Cloudflare is proxying requests for Apache, then Cloudflare passes the real IP address of the hit to Apache via the CF-CONNECTING-IP header. The following code will remap the real ip address to the X-FORWARDED-FOR header, typically used for proxying.

    if (req.http.cf-connecting-ip) {
        set req.http.X-Forwarded-For = req.http.cf-connecting-ip;
    } else {
        set req.http.X-Forwarded-For = client.ip;
    }

The code is written to account for the case where the client IP address is passed directly without Cloudflare in the second part of the conditional block.

Lastly, the varnish logging facility, "varnishncsa" must also be changed in order to log the real IP address. varnishncsa acts after varnish such that the log-format of varnishncsa must be changed in order to make varnishncsa log the X-FORWARDED-FOR as the IP address. Here is a SystemD service file that should be copied from /lib/systemd/system/varnishncsa.service to /etc/systemd/system/, then modified to match the content below, and then started via systemctl:

[Unit]
Description=Varnish HTTP accelerator log daemon
Documentation=https://www.varnish-cache.org/docs/6.1/ man:varnishncsa
After=varnish.service

[Service]
Type=forking
PIDFile=/run/varnishncsa/varnishncsa.pid
RuntimeDirectory=varnishncsa
User=varnishlog
Group=varnish
ExecStart=/usr/bin/varnishncsa -a -w /var/log/varnish/varnishncsa.log -D -P /run/varnishncsa/varnishncsa.pid -F '%%{X-Forwarded-For}i %%l %%u %%t "%%r" %%s %%b "%%{Referer}i" "%%{User-agent}i"'
ExecReload=/bin/kill -HUP $MAINPID
PrivateDevices=true
PrivateTmp=true
ProtectHome=true
ProtectSystem=full

[Install]
WantedBy=multi-user.target

The change here is the formatting line of the log files produced by varnishncsa passed to the -F parameters, namely:

-F '%%{X-Forwarded-For}i %%l %%u %%t "%%r" %%s %%b "%%{Referer}i" "%%{User-agent}i"'

CloudFlare IPv6 and Blocking with Varnish

Project Honeypot decided to pass IPv6 addresses to webservers when a client connects via IPv6 to Cloudflare and makes a request to a webserver behind Cloudflare. The consequence is that if the webserver is not configured for IPv6, then the request might end up bypassing any protections or throttling.

Unfortunately, the only fix is to block IPv6 "customers" with a 400 and "Bad Request" HTTP error message. This can be done via the following stanza:

    if(req.http.cf-connecting-ip ~ "([a-f0-9:]+:+)+[a-f0-9]+") {
        return(synth(400, "Bad Request"));
    }

in the Varnish configuration.