CF Headers, Varnish GEOIP issue

Hi guys, we have Varnish 6 installed with GEOIP, which we use to set user content based on their location. When CF is enabled (developers mode on, no cache) varnish starts detecting wrong country.

Network => GEOIP is disabled.

I suspect there’s smth wrong in the headers.

Headers with CF enabled (no cache, no geoid):

:status: 200
Content-Encoding: br
Cache-Control: no-store, no-cache, must-revalidate, max-age=0
Pragma: no-cache
X-XSS-Protection: 1; mode=block
Date: Mon, 22 Feb 2021 19:06:00 GMT
Vary: Accept-Encoding
Expires: -1
X-Frame-Options: SAMEORIGIN
Content-Type: text/html; charset=UTF-8
X-Content-Type-Options: nosniff
x-country-name: United States
x-country-code: US
Server: Cloudflare
Strict-Transport-Security: max-age=31622400; includeSubDomains; preload
cf-cache-status: DYNAMIC
x-powered-by: Srg
report-to: {“group”:“cf-nel”,“endpoints”:[{“url”:“https://a.nel.Cloudflare.com/report?s=QRORqzNMpTAAIS3uYqLVUQ7ULEkKv1t6JD%2FQlg0CYV5omQSRncYiDiij2BjamFHlPzQ%2FCKGHeJNq3wSaqtYIkLaMch5lxvTriVk%3D”}],“max_age”:604800}
cf-request-id: 086cbb6b5800003a378898d000000001
x-accept: png
expect-ct: max-age=604800, report-uri=“https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct
nel: {“report_to”:“cf-nel”,“max_age”:604800}
cf-ray: 625afb588bcc3a37-SEA
x-ua-compatible: IE=Edge

Bypassing CF completely (correct GEOIP result):

:status: 200
Content-Type: text/html; charset=UTF-8
Accept-Ranges: bytes
Pragma: no-cache
Content-Encoding: gzip
Expires: -1
X-XSS-Protection: 1; mode=block
Cache-Control: no-store, no-cache, must-revalidate, max-age=0
Date: Mon, 22 Feb 2021 19:02:04 GMT
Content-Length: 32
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Vary: Accept-Encoding
x-accept: png
x-powered-by: Srg
Server: nginx/1.14.0 (Ubuntu)
x-country-code: CA
x-country-name: Canada
Strict-Transport-Security: max-age=31622400; includeSubDomains; preload
x-ua-compatible: IE=Edge

Anybody had the same issue? Trying to figure out how to configure CF to result in the correct GEOIP result.

If possible, you can change GEOIP to look at the cf_ipcountry request header your server receives.

Visit this to view how to setup the geo-location header.

The easiest thing is to use the cf-ipcountry header, unless you need more granular data.

You can also cast using the std vmod, as the geoip vmod you are using probably requires an IP input to the function. (Sample below is from memory, and may change depending on your version and vmod)

set req.http.Country-Name = geodb.country_name(std.ip(req.http.cf-connecting-ip,”0.0.0.0”));

1 Like

Thank you guys! We’ve corrected this:

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

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.