TransWikia.com

Varnish PURGE client.ip docker-compose

Server Fault Asked by zhartaunik on November 12, 2021

I’m trying to configure varnish for Magento2.

Question: I’m unable to configure PURGE varnish cache.

Here is my build: https://github.com/zhartaunik/magento2-docker

Varnish settings: https://github.com/zhartaunik/magento2-docker/tree/master/docker/varnish

I’m using docker-compose.
Varnish FROM varnish:6.2
vcl 4.0;

I’m trying to configure purge command in a safe way.
I’m not sure what is the best practice on how to configure varnish, but Magento recommends the following:

acl purge {
    "nginx";
}

And there is following verification:

sub vcl_recv {
    if (req.method == "PURGE") {
        if (!client.ip ~ purge) {
            return (synth(405, "Purging not allowed for " + client.ip));
        }

In my case when I’m trying to purge varnish from console / admin UI – I’m always facing with the following error:

<!DOCTYPE html>
<html>
  <head>
    <title>405 Purging not allowed for 192.168.128.7</title>
  </head>
  <body>
    <h1>Error 405 Purging not allowed for 192.168.128.7</h1>
    <p>Purging not allowed for 192.168.128.7</p>
    <h3>Guru Meditation:</h3>
    <p>XID: 32770</p>
    <hr>
    <p>Varnish cache server</p>
  </body>
</html>

After the docker restart, this IP address changes.

When I’m trying to configure acl purge with container names I’m still facing the same error. However, adding container name to "whitelist" and running

curl -k -X PURGE https://magento2.docker

Passes this verification.

What is the best and safest way to configure acl purge section?

One Answer

If you use Nginx as your TLS terminator, the client.ip value has the risk of always being the Nginx IP. This is predictable, but not necessarily safe.

What you should do, is make sure Nginx & Varnish connect to each other using the PROXY protocol. This will make sure that the original client IP is transmitted and stored in client.ip.

Setting up PROXY protocol on Varnish

In order to enable the PROXY protocol in Varnish using your Docker setup, you'll need to modify the value of ${VARNISH_LISTEN}.

Here's how you could do that:

ENV VARNISH_LISTEN  :6081,PROXY

At this point, Varnish no longer accepts traditional HTTP connections.

Setting up PROXY protocol in Nginx

According to the docs, Nginx supports the proxy_protocol as of version 1.9.2. This seems to be compatible with the version you're using in your Dockerfile.

It's just a matter of adding the following line to your /docker/nginx/etc/vhost.conf file:

proxy_protocol on;

The added value of using the PROXY protocol, is that the X-Forwarded-For value set by Varnish will always contain the IP address of the original client, regardless of the number of proxy nodes in front of Varnish.

Backup plan

If PROXY protocol in Nginx is not an option, I can give you 3 alternative plans:

  1. Use Hitch as your TLS proxy: it supports PROXY protocol, it's super lightweight and developed at Varnish Software
  2. Use HAProxy as your TLS proxy: they invented PROXY protocol, it's a bit heavier than Hitch
  3. Don't use PROXY protocol and match the X-Real-IP value in your ACL. This header was set by Nginx, and contains the client IP according to Nginx.

Answered by Thijs Feryn on November 12, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP