Varnish X-Forwarded-for Public IP not visible

This post describes under which scenario you may not see X- Forwarded-for public IP in your Varnish / Apache logs and How to resolve the same.

If you have a website doing Country detection based on IP address then it may stop working if correct IP address is not available.

By default Varnish will remove several headers, this does not affect unless you have specific scenario.

I came across an issue where varnish was not sending Intermediary proxy IP or Public IP in a particular case.

Scenario :

  • Some Hotel / Company has squid proxy configured and all traffic for Internet is routed via Squid.
  • User accessing my  website first hits the Load Balancer then Varnish & then Apache
  • Apache is configured with mod_geoip. The code on my site does the Country redirection based on the IP address

Problem :

  • User (Behind that squid proxy) accessing my website follows this path :

Load Balancer -> VARNISH -> Apache

Here apache gets only Internal IP (LAN IP of user) & Load Balancer Internal IP as X-forwarded-for and Hence the IP based redirection FAILS!

Solution :

Credit goes to Mithrandir @ Varnish IRC Channel, Thanks!

Below mentioned changes were required to resolve the issue.

  • At the start of the default.vcl add :

import std;

  • Below     “if (req.http.x-forwarded-for)” add :

std.collect(req.http.x-forwarded-for);

  • Do varnish configtest & reload. This should start showing the Public IP.
  • Below is the explanation from the documentation of vmod_std :

collect

Prototype
collect(HEADER header)

Return value
Void

Description
Collapses the header, joining the headers into one.

Example
std.collect(req.http.cookie); This will collapse several Cookie:
headers into one, long cookie header.