I have a nginx with geoip, but it is not working rightly. The issue is the next:

Nginx are getting geodata from $_SERVER['REMOTE_ADDR'] instead of $_SERVER['HTTP_X_HAPROXY_IP'], which have the real client ip. So, the reported geodata belongs to my server ip instead of client ip.

Does anybody where could be the error to fix it?

Nginx version and compiled modules:

nginx -V
nginx version: nginx/1.2.3
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --conf-path=/etc/nginx/nginx.conf --error-log-    path=/var/log/nginx/error.log --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-log-path=/var/log/nginx/access.log --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --lock-path=/var/lock/nginx.lock --pid-path=/var/run/nginx.pid --with-pcre-jit --with-debug --with-file-aio --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_realip_module --with-http_secure_link_module --with-http_stub_status_module --with-http_ssl_module --with-http_sub_module --with-http_xslt_module --with-ipv6 --with-sha1=/usr/include/openssl --with-md5=/usr/include/openssl --with-mail --with-mail_ssl_module --add-module=/usr/src/nginx/source/nginx-1.2.3/debian/modules/nginx-auth-pam --add-module=/usr/src/nginx/source/nginx-1.2.3/debian/modules/nginx-echo --add-module=/usr/src/nginx/source/nginx-1.2.3/debian/modules/nginx-upstream-fair --add-module=/usr/src/nginx/source/nginx-1.2.3/debian/modules/nginx-dav-ext-module --add-module=/usr/src/nginx/source/nginx-1.2.3/debian/modules/nginx-syslog --add-module=/usr/src/nginx/source/nginx-1.2.3/debian/modules/nginx-cache-purge

nginx site conf (frontend machine)

server {
    root /var/www/storage;

    server_name ~^.*(\.)?mydomain.com$;

    if ($host ~ ^(.*)\.mydomain\.com$) {
            set $new_host $1.mydomain.com;
    if ($host !~ ^(.*)\.mydomain\.com$) {
            set $new_host www.mydomain.com;

    add_header Staging true;
    real_ip_header X-HAProxy-IP;

    location /files {
            expires 30d;
            if ($uri !~ ^/files/([a-fA-F0-9]+)_(220|45)\.jpg$) {
                    return 403;
            rewrite  ^/files/([a-fA-F0-9][a-fA-F0-9])([a-fA-F0-9][a-fA-F0-9])([a-fA-F0-9][a-fA-F0-9])([a-fA-F0-9][a-fA-F0-9])([a-fA-F0-9]+)_(220|45)\.jpg$ /files/$1/$2/$3/$4/$1$2$3$4$5_$6.jpg break;
            try_files $uri @to_backend;

    location /assets {
            if ($uri ~ ^/assets/r([a-zA-Z0-9]+[^/])(/(css|js|fonts)/.*)) {
                    rewrite ^/assets/r([a-zA-Z0-9]+[^/])/(css|js|fonts)/(.*)$ /assets/$2/$3 break;
            try_files $uri @to_backend;

    location / {
            proxy_set_header Host $new_host;
            proxy_set_header X-HAProxy-IP $remote_addr;

    location @to_backend {
            proxy_set_header Host $new_host;

nginx.conf (backend machine)

    # GeoIP Config
    geoip_country  /etc/nginx/geoip/GeoIP.dat; # the country IP database
    geoip_city     /etc/nginx/geoip/GeoLiteCity.dat; # the city IP database

fastcgi_params (backend machine)

### SET GEOIP Variables ###
fastcgi_param  GEOIP_COUNTRY_CODE               $geoip_country_code;
fastcgi_param  GEOIP_COUNTRY_CODE3              $geoip_country_code3;
fastcgi_param  GEOIP_COUNTRY_NAME               $geoip_country_name;
fastcgi_param  GEOIP_CITY_COUNTRY_CODE          $geoip_city_country_code;
fastcgi_param  GEOIP_CITY_COUNTRY_CODE3         $geoip_city_country_code3;
fastcgi_param  GEOIP_CITY_COUNTRY_NAME          $geoip_city_country_name;
fastcgi_param  GEOIP_REGION                     $geoip_region;
fastcgi_param  GEOIP_CITY                       $geoip_city;
fastcgi_param  GEOIP_POSTAL_CODE                $geoip_postal_code;
fastcgi_param  GEOIP_CITY_CONTINENT_CODE        $geoip_city_continent_code;
fastcgi_param  GEOIP_LATITUDE                   $geoip_latitude;
fastcgi_param  GEOIP_LONGITUDE                  $geoip_longitude;

haproxy.conf (frontend machine)

    log global
    option forwardfor
    option httpclose
    mode http
    retries 3
    option redispatch
    maxconn 4096
    contimeout 100000
    clitimeout 100000
    srvtimeout 100000

listen cluster_webs *:8080
    mode http
    option tcpka
    option httpchk
    option httpclose
    option forwardfor
    balance roundrobin
    server backend-stage weight 1

$_SERVER dump: http://paste.laravel.com/7dy

Where is frontend private ip and backend private ip


You need to configure the realip module in nginx to set $remote_addr for the geoip module to use:

real_ip_header X-HAProxy-IP;
set_real_ip_from your.haproxy.ip/32;
| improve this answer | |
  • I already have that, but $remote_addr is showing my server ip instead of client ip. That's the problem – blacksoul Oct 5 '12 at 14:33
  • Can you add your server{} block to the post? I don't want to just start guessing why it's not picking up the header. – kolbyjack Oct 5 '12 at 14:48
  • Yes, sure :). I have just updated the question with it – blacksoul Oct 5 '12 at 14:54
  • I don't see you actually using the geoip module anywhere in here. While I'm not sure why $remote_addr isn't being set, you should actually be able to use proxy_set_header X-HAProxy-IP $http_x_haproxy_ip; to have nginx pass through the header if it's not passing it through automatically. – kolbyjack Oct 5 '12 at 15:02
  • you also seem to be passing back to haproxy. Does it trust the X-HAProxy-IP that nginx is setting in its request, or does it overwrite it? – kolbyjack Oct 5 '12 at 15:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.