Skip to content
Cyril Bonté edited this page Jun 17, 2013 · 20 revisions

Geolocation patch provides an easy and performant way to configure geolocation in HAProxy.

This is an enhancement to the solution described on the Exceliance Blog : http://blog.exceliance.fr/2012/07/02/use-geoip-database-within-haproxy/

One of the advantages of this previous solution is that it doesn't require any modification in the HAProxy core. But some of its disadvantages are :

  • performance degradation if an IP needs to traverse a lot of rules.
  • maintainability nightmare for the operators : lots of ACLs, redirects, files...depending on the GeoIP database, time to time we can have more or less files generated (all IPs moving from a country to another, ...).

Using this patch allows to have a fair performance throughput for each country (continent, datacenter, ...).

Note : Performance Comparison will come soon.

Security

Caution ! Users of this patch are asked to update to at least haproxy 1.4.24 or haproxy 1.5-dev19, as it is vulnerable to CVE-2013-2175 (see the announcement for more details).

Sources

https://github.com/cbonte/haproxy-patches/tree/master/geolocation

New keywords

  • geolocate <src|hdr_ip(<header>,<occ>)> <dictionary filename> [{if | unless} <cond>]

    Where :

    • src defines geolocation based on the client IP.

    • hdr_ip defines geolocation based on a request header identified by <header>. <occ> is the occurrence number of a value to be used in a multi-value header. Positive values indicate a position from the first occurrence, 1 being the first one. Negative values indicate positions relative to the last one, -1 being the last one. This is helpful for situations where an X-Forwarded-For header is set at the entry point of an infrastructure and must be used several proxy layers away. When this value is not specified, -1 is assumed. Passing a zero here disables the feature.

    • <dictionary filename> points to a file containing key/value lines. The file syntax is:

          <IP address or network in CIDR form> <value> 
      

      Empty lines as well as lines beginning with a sharp ('#') will be ignored. All leading spaces and tabs will be stripped.

New acls

  • geoloc <values>

    Where <values> is one of the value found in the file, or "*" to match any of them.

New behaviours

  • redirect keyword now allows to substitute the token ${geoloc} with the value that matched the geolocation, or by an empty string if none matched.

Command line tools

haproxy-geoip

Source : https://raw.github.com/cbonte/haproxy-patches/master/geolocation/tools/haproxy-geoip

Documentation coming later.

Usage examples

Example 1 : some general rules

geolocate hdr_ip(X-Forwarded-For,-1) geolocation.txt
redirect location http://${geoloc}.website.com/ if { geoloc fr us }
redirect prefix /spaceman if { geoloc mercury venus mars jupiter saturn uranus neptune pluto }
redirect prefix /${geoloc} if { geoloc * }

Example 2 : failover only if the frontend geolocation failed

frontend myfrontend :80
    geolocate src country.db
    default_backend mybackend

backend mybackend
    geolocate src continent.db if !{ geoloc * } # Geolocate only if the frontend didn't succeed
    redirect location /${geoloc} if { geoloc * }

Quick comparison without any details

A complete benchmark will come later (see the configuration file sources used for this benchmark).

Performance comparison