@varnishcache HELP! How do I route client traffic based on client source IP address?
N.B: I have install two varnish-cache servers in two different data center.
@varnishcache HELP! How do I route client traffic based on client source IP address?
N.B: I have install two varnish-cache servers in two different data center.
As a point of reference I'd like you to look at https://www.varnish-software.com/developers/tutorials/multiple-backends/. This is a tutorial that explains how to use multiple backends.
If your goal is to have a "sticky IP" strategy, you could use some VCL code like the example below:
vcl 4.1;
import directors;
backend backend1 {
.host = "backend1.example.com";
.port = "80";
}
backend backend2 {
.host = "backend2.example.com";
.port = "80";
}
backend backend3 {
.host = "backend3.example.com";
.port = "80";
}
sub vcl_init {
new vdir = directors.hash();
vdir.add_backend(backend1);
vdir.add_backend(backend2);
vdir.add_backend(backend3);
}
sub vcl_recv {
set req.backend_hint = vdir.backend(client.ip);
}
In this case you'll create a hash based on the client.ip
value and route traffic to the backend based on that hash. Every request by the IP address will end up on the same backend.
It's important that the client.ip
value contains the right value. If you're running a TLS proxy in front of Varnish the client.ip
value will always be the one of the TLS proxy, unless you leverage the PROXY protocol.
If you're not using the PROXY protocol, you may want to consider using req.http.X-Forwarded-For
as the value to hash on, because that header will contain the IP addresses of the actual client (and potentially other proxies in between).
Based on extra comments and a detailed specification of requirements, here's a new VCL file.
vcl 4.1;
import std;
probe health {
.url = "/";
.timeout = 2s;
.interval = 5s;
.window = 10;
.threshold = 5;
}
backend cdn1 {
.host = "cdn1.example.com";
.port = "80";
.probe = health;
}
backend cdn2 {
.host = "cdn2.example.com";
.port = "80";
.probe = health;
}
backend origin {
.host = "origin.example.com";
.port = "80";
.probe = health;
}
acl cdn2_acl {
"12.13.14/24";
}
sub vcl_recv {
set req.grace = 10s;
if(std.ip(req.http.X-Forwarded-For,"0.0.0.0") ~ cdn2_acl) {
set req.backend_hint = cdn2;
} elseif(std.healthy(cdn1)) {
set req.backend_hint = cdn1;
} else {
set req.backend_hint = origin;
set req.grace = 24h;
}
}
sub vcl_backend_response {
set beresp.grace = 24h;
}
Summary of what this VCL file does:
X-Forwarded-For
header matches an IP address that is defined in the cdn2_acl
ACL, route the traffic to the cdn2
backendX-Forwarded-For
header doesn't match the ACL, try to route traffic to the cdn1
backendcdn1
backend is healthy, serve content from cdn1
cdn1
backend is unhealthy, directly connect to the origin
backend and ramp the grace value up to 24h;