Reputation: 51
We're using Varnish 3.0.3. Varnish is behind a load balancer.
We would like to bypass the Varnish cache for a particular IP address. After doing research, I found the following. Unfortunately, it is not working.
acl passem { "7x.xxx.xxx.xxx"; }
sub vcl_recv {
if (!(client.ip ~ passem)) {
return (pass);
}
}
This appears in varnishlog
"6 VCL_acl c NO_MATCH passem"
I'm not sure what is wrong. The only thing I can think of is Varnish is not seeing the incoming IP address. This is what I see in varnishlog
.
6 RxHeader c X-Real-IP: "7x.xxx.xxx.xxx"
6 RxHeader c X-Forwarded-For: "7x.xxx.xxx.xxx"
6 SessionOpen c 10.10.10.4 58143 0.0.0.0:80
6 ReqStart c 10.10.10.4 58143 1026834560
The RxHeader is receiving the correct IP and matches the acl passem
, but I don't know if acl passem
is instead referencing the SessionOpen
IP address, which is the IP address of the load balancer.
Upvotes: 0
Views: 2233
Reputation: 168
In current varnish-cache versions you can use std.ip()
, e.g.
import std;
sub vcl_recv {
if (std.ip(req.http.X-Real-IP) !~ passem) {
return (pass);
}
}
Upvotes: 0
Reputation: 51
In Varnish, "X-Real-IP"
and "http.x-forwarded-for"
are strings and "client.ip"
is an object.
Extra code is required to copy the IP address from the "X-Forwarded-For"
header into Varnish's client_ip structure.
Below is what was required to make it work. This worked successfully. Credit goes to http://zcentric.com/2012/03/16/varnish-acl-with-x-forwarded-for-header/
C{
#include <netinet/in.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
}C
acl passem { "7x.xxx.xxx.xxx"; }
sub vcl_recv {
C{
struct sockaddr_storage *client_ip_ss = VRT_r_client_ip(sp);
struct sockaddr_in *client_ip_si = (struct sockaddr_in *) client_ip_ss;
struct in_addr *client_ip_ia = &(client_ip_si->sin_addr);
char *xff_ip = VRT_GetHdr(sp, HDR_REQ, "\020X-Forwarded-For:");
if (xff_ip != NULL) {
inet_pton(AF_INET, xff_ip, client_ip_ia);
}
}C
if (!(client.ip ~ passem)) {
return (pass);
}
}
Upvotes: 4
Reputation: 2964
Yes, your client.ip will be the real IP, not anything forwarded in headers. Instead you need to use the correct header req.http.X-Real-IP
for instance.
Upvotes: 1