Want to subscribe to topics you're interested in?
Become a Member

Featured Nginx How to enable GeoIP 2 Lite Nginx Module Support ?

Discussion in 'Centmin Mod User Tutorials & Guides' started by eva2000, Apr 8, 2019.

Thread Status:
Not open for further replies.
  1. eva2000

    eva2000 Administrator Staff Member

    54,524
    12,211
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +18,780
    Local Time:
    11:57 PM
    Nginx 1.27.x
    MariaDB 10.x/11.4+
    Below is a quick guide on how to install and enable GeoIP 2 Nginx module, ngx_http_geoip2_module support in Centmin Mod 123.09beta01 or newer versions to utilise Maxmind's GeoIP 2 Lite database. Prep work on Maxmind's GeoIP 2 Lite database support via GeoIP 2 Nginx module, ngx_http_geoip2_module started back in May 2018 to eventually replace the older legacy GeoIP database nginx module as Maxmind's GeoIP legacy database downloads are now deprecated and ended after January 2019 (though database updates stopped back in April 2018)

    An example of how I use GeoIP 2 Nginx module can be seen in one of the three GeoIP lookup site versions I created at https://geoip.centminmod.com/v2/.

    Enabling Nginx GeoIP 2 Module Support



    By default when you enable GeoIP 2 Nginx module support, it will be enabled along side the native GeoIP legacy Nginx module so you will have 2 sets of fastcgi_param mapped variables to desired PHP environmental variables. So you may need to adjust the desired PHP environmental variables based on what your PHP web application is looking for with regards to GeoIP related functions/usage. As GeoIP legacy databases are no longer downloadable, I have setup a local Centmin Mod mirror of the older GeoIP legacy databases which is pulled from for Centmin Mod Nginx's GeoIP legacy Nginx module support.
    • As at Jan 1 2020, Maxmind GeoLite2 database downloads required for Nginx GeoIP 2 Lite nginx module now require a Maxmind account and using a Maxmind token API key as outlined at Centmin Mod Maxmind GeoLite2 Free Database Download Changes. You need to set your MM_LICENSE_KEY variable specifying your Maxmind token API ket in persistent config file at /etc/centminmod/custom_config.inc before running centmin.sh menu option 4.
      Code (Text):
      MM_LICENSE_KEY='your_maxmind_api_key'
    • To install and enable Nginx GeoIP 2 module support in Centmin Mod 123.09beta01 Nginx builds, need to add 2 variables into persistent config file at /etc/centminmod/custom_config.inc before recompiling Nginx via centmin.sh menu option 4. The first variable actually enables Nginx GeoIP 2 module while 2nd variable tells Nginx to enable and install the module as a dynamic Nginx module instead of static Nginx module.
      Code (Text):
      NGINX_GEOIPTWOLITE='y'
      NGXDYNAMIC_GEOIPTWOLITE='y'
      

      After Nginx recompile, GeoIP and GeoIP 2 Lite databases will reside in directory at /usr/share/GeoIP
      Code (Text):
      ls -lah /usr/share/GeoIP| grep GeoLite2
      -rw-r--r--    1 2000 2000 6.2M Apr  1 13:52 GeoLite2-ASN.mmdb
      -rw-r--r--    1 root root 3.5M Apr  1 13:52 GeoLite2-ASN.tar.gz
      -rw-r--r--    1 2000 2000  58M Apr  2 18:44 GeoLite2-City.mmdb
      -rw-r--r--    1 root root  28M Apr  2 18:44 GeoLite2-City.tar.gz
      -rw-r--r--    1 2000 2000 3.6M Apr  2 18:32 GeoLite2-Country.mmdb
      -rw-r--r--    1 root root 1.9M Apr  2 18:32 GeoLite2-Country.tar.gz
      

      also GeoIP 2 Lite database auto updating cronjob should be automatically setup when you enable GeoIP2 Nginx module support which checks for updates every week
      Code (Text):
      crontab -l | grep geoip2db
      20 2 * * 4 /usr/local/src/centminmod/tools/geoip2db-update.sh >/dev/null 2>&1
      

      Nginx version command will report which Nginx modules are installed/loaded
      nginx process id 2128 check for ngx_http_geoip2_module.so dynamic module loading
      Code (Text):
      lsof -p 2128 | grep .so | grep geo 
      nginx   2128 nginx  mem       REG              253,1    95736 73426754 /usr/local/nginx/modules/ngx_http_geoip2_module.so
      

      and for GeoIP legacy and GeoIP 2 Lite databases
      Code (Text):
      lsof -p 2128 | grep GeoIP
      nginx   2128 nginx  mem       REG              253,1  6457614  4687427 /usr/share/GeoIP/GeoLite2-ASN.mmdb
      nginx   2128 nginx  mem       REG              253,1 60794702  5436895 /usr/share/GeoIP/GeoLite2-City.mmdb
      nginx   2128 nginx  mem       REG              253,1   197136  2290746 /usr/lib64/libGeoIP.so.1.5.0
      nginx   2128 nginx    6r      REG              253,1  1242574  4309722 /usr/share/GeoIP/GeoIP.dat
      nginx   2128 nginx    7r      REG              253,1 20539238  4721045 /usr/share/GeoIP/GeoIPCity.dat
      

    • Fresh Centmin Mod 123.09beta01 installs will have an include file /usr/local/nginx/conf/geoip2.conf referenced in their /usr/local/nginx/conf/geoip.conf include file which will disabled/commented out by default and will be auto re-enabled/uncommented out in centmin.sh menu option 4 recompiles when those 2 persistent config variables are enabled. Contents of /usr/local/nginx/conf/geoip.conf include file with legacy GeoIP nginx module database references for /usr/share/GeoIP/GeoIP.dat and /usr/share/GeoIP/GeoIPCity.dat databases and the include file /usr/local/nginx/conf/geoip2.conf containing GeoIP 2 Lite database references.
      Code (Text):
      # SET the path to the .dat file used for determining the visitors country from the IP-address ###
      geoip_country /usr/share/GeoIP/GeoIP.dat;
      
      # SET the path to the .dat file used for determining the visitors country from the IP-address ###
      geoip_city /usr/share/GeoIP/GeoIPCity.dat;
      
      # GeoIP2 Lite databases
      #include /usr/local/nginx/conf/geoip2.conf;
      
      

    • The include file /usr/local/nginx/conf/geoip2.conf will reference and define the GeoIP 2 Lite databases for /usr/share/GeoIP/GeoLite2-City.mmdb, /usr/share/GeoIP/GeoLite2-Country.mmdb and /usr/share/GeoIP/GeoLite2-ASN.mmdb. Contents for /usr/local/nginx/conf/geoip2.conf include file below basically map an Nginx variable to the corresponding variable fields in the respective databases. So the variable $geoip2_data_country_code country referenced in your Nginx vhost configuration files would retrieve the visitor's 2 letter country code i.e. Australia = AU or USA = US according to the visitor's detected IP address. You use these variables to setup your Nginx vhost accordingly just like you do for GeoIP legacy Nginx module. You can Google search for GeoIP 2 Nginx configuration examples which may have different variable names referenced and mapped, just you need to use the variables referenced in below /usr/local/nginx/conf/geoip2.conf include file instead. Remember to scroll down within CODE tag window.
      Code (Text):
      # GeoIP2 Lite databases
        #  geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {
        #    auto_reload 5m;
        #    $geoip2_metadata_country_build metadata build_epoch;
        #    $geoip2_data_country_code country iso_code;
        #    $geoip2_data_country_name country names en;
        #  }
      
        geoip2 /usr/share/GeoIP/GeoLite2-City.mmdb {
          auto_reload 5m;
          $geoip2_metadata_city_build metadata build_epoch;
          $geoip2_data_city_name city names en;
          $geoip2_data_city_geonameid city geoname_id;
          $geoip2_data_continent_code continent code;
          $geoip2_data_continent_geonameid continent geoname_id;
          $geoip2_data_continent_name continent names en;
          $geoip2_data_country_geonameid country geoname_id;
          $geoip2_data_country_code country iso_code;
          $geoip2_data_country_name country names en;
          $geoip2_data_country_is_eu country is_in_european_union;
          $geoip2_data_location_accuracyradius location accuracy_radius;
          $geoip2_data_location_latitude location latitude;
          $geoip2_data_location_longitude location longitude;
          $geoip2_data_location_metrocode location metro_code;
          $geoip2_data_location_timezone location time_zone;
          $geoip2_data_postal_code postal code;
          $geoip2_data_rcountry_geonameid registered_country geoname_id;
          $geoip2_data_rcountry_iso registered_country iso_code;
          $geoip2_data_rcountry_name registered_country names en;
          $geoip2_data_rcountry_is_eu registered_country is_in_european_union;
          $geoip2_data_region_geonameid subdivisions 0 geoname_id;
          $geoip2_data_region_iso subdivisions 0 iso_code;
          $geoip2_data_region_name subdivisions 0 names en;
        }
      
        geoip2 /usr/share/GeoIP/GeoLite2-ASN.mmdb {
          auto_reload 5m;
          $geoip2_data_autonomous_system_number autonomous_system_number;
          $geoip2_data_autonomous_system_organization autonomous_system_organization;
        } 
      
      

      For existing Centmin Mod installs, you would need to add the missing configuration settings into /usr/local/nginx/conf/geoip.conf as end users may have customised their /usr/local/nginx/conf/geoip.conf file and overwriting the contents of end users customised file would not be a good idea. If /usr/local/nginx/conf/geoip2.conf is missing from your installation, you can copy it over from /usr/local/src/centminmod/config/nginx/geoip2.conf on your local server or via the github repo version at centminmod/centminmod
    • You can also use GeoIP 2 Lite Nginx module at the php-fpm level by setting up php-fpm fastcgi_param mapped variables like Nginx ones which map the desired PHP environmental variable to the GeoIP 2 Lite Nginx registered variable. You would do the mapping and addition of fastcgi_param variables in the /usr/local/nginx/conf/php.conf include file which is included as a common file in all Nginx vhosts auto created by centmin Mod
      Code (Text):
      include /usr/local/nginx/conf/php.conf;

      The /usr/local/nginx/conf/php.conf include file already has GeoIP legacy fastgi_param variables mapped to desired PHP environmental variables.
      Code (Text):
      # Set php-fpm 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;
      

      To add the GeoIP 2 Lite fastcgi_param mapping you can replace your /usr/local/nginx/conf/php.conf file with the version at /usr/local/nginx/conf/php-geoip2.conf. Or if you already customised php.conf, just add to php.conf the missing fastcgi_param variables for GeoIP 2 Lite mapping shown directly below
      Code (Text):
      fastcgi_param GEOIP2_CITY_BUILD_DATE $geoip2_metadata_city_build;
      fastcgi_param GEOIP2_CITY $geoip2_data_city_name;
      fastcgi_param GEOIP2_CITY_GEONAMEID $geoip2_data_city_geonameid;
      fastcgi_param GEOIP2_CONTINENT_CODE $geoip2_data_continent_code;
      fastcgi_param GEOIP2_CONTINENT_GEONAMEID $geoip2_data_continent_geonameid;
      fastcgi_param GEOIP2_CONTINENT_NAME $geoip2_data_continent_name;
      fastcgi_param GEOIP2_COUNTRY_GEONAMEID $geoip2_data_country_geonameid;
      fastcgi_param GEOIP2_COUNTRY_CODE $geoip2_data_country_code;
      fastcgi_param GEOIP2_COUNTRY_NAME $geoip2_data_country_name;
      fastcgi_param GEOIP2_COUNTRY_IN_EU $geoip2_data_country_is_eu;
      fastcgi_param GEOIP2_LOCATION_ACCURACY_RADIUS $geoip2_data_location_accuracyradius;
      fastcgi_param GEOIP2_LATITUDE $geoip2_data_location_latitude;
      fastcgi_param GEOIP2_LONGITUDE $geoip2_data_location_longitude;
      fastcgi_param GEOIP2_LOCATION_METROCODE $geoip2_data_location_metrocode;
      fastcgi_param GEOIP2_LOCATION_TIMEZONE $geoip2_data_location_timezone;
      fastcgi_param GEOIP2_POSTAL_CODE $geoip2_data_postal_code;
      fastcgi_param GEOIP2_REGISTERED_COUNTRY_GEONAMEID $geoip2_data_rcountry_geonameid;
      fastcgi_param GEOIP2_REGISTERED_COUNTRY_ISO $geoip2_data_rcountry_iso;
      fastcgi_param GEOIP2_REGISTERED_COUNTRY_NAME $geoip2_data_rcountry_name;
      fastcgi_param GEOIP2_REGISTERED_COUNTRY_IN_EU $geoip2_data_rcountry_is_eu;
      fastcgi_param GEOIP2_REGION_GEONAMEID $geoip2_data_region_geonameid;
      fastcgi_param GEOIP2_REGION $geoip2_data_region_iso;
      fastcgi_param GEOIP2_REGION_NAME $geoip2_data_region_name;
      
      fastcgi_param GEOIP2_ASN $geoip2_data_autonomous_system_number;
      fastcgi_param GEOIP2_ASN_ORG $geoip2_data_autonomous_system_organization;
      

      For example, to map the 2 letter country code variable, $geoip2_data_country_code (registered in /usr/local/nginx/conf/geoip2.conf include file) to PHP environment variable = GEOIP2_COUNTRY_CODE when you set
      Code (Text):
      fastcgi_param GEOIP2_COUNTRY_CODE $geoip2_data_country_code;

      in php.conf include file you register with PHP the environmental variable you can grab with PHP code
      PHP:
      <?php

      $geoip_country_code 
      getenv(GEOIP2_COUNTRY_CODE);

      echo 
      'country code: '.$geoip_country_code.'';
      An Australian visitor visiting that php page will see
      as GeoIP 2 Nginx module referencing GeoIP 2 Lite database found that visitor's IP address has a country code = AU
      You can use phpinfo() page to view all the GeoIP 2 and GeoIP legacy mapped PHP environmental variables which can be referenced via getenv() or $_SERVER[]. Example for a UK visitor IP address detected and looked up in both GeoIP 2 Lite and GeoIP legacy databases. These PHP environment variables correspond to the ones you setup in your /usr/local/nginx/conf/php.conf include file where GEOIP2_ prefixed ones are for GeoIP 2 Lite and GEOIP_ prefixed ones for GeoIP legacy database. You will notice differences in reported data values because GeoIP legacy database updates stopped around April 2018, so when geolocation data changes with an IP address the updates are no longer happening. That is why you should switch to GeoIP 2 Lite databases which are updated monthly. Still a delay which can see incorrect geolocation data for an IP. If you need more up to date geolocation data for IPs you need to pay for Maxmind's commercial GeoIP 2 databases.

      centminmod-nginx-php-fpm-geoip2-02.png
    Maxmind's GeoIP legacy discontinuation announcement at GeoLite Legacy Discontinuation Information | MaxMind Support Center


     
    Last edited: Apr 8, 2019
  2. eva2000

    eva2000 Administrator Staff Member

    54,524
    12,211
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +18,780
    Local Time:
    11:57 PM
    Nginx 1.27.x
    MariaDB 10.x/11.4+

    GeoIP 2 Nginx Module Examples



    Examples of using GeoIP 2 Nginx module in Centmin Mod 123.009beta01 and neew after doing above setup

    Nginx Blocking Traffic At Country Level



    Nginx level country blocking using the registered mapped Nginx variables in /usr/local/nginx/conf/geoip2.conf include file for 2 digit country code = $geoip2_data_country_code

    Place nginx mapping in /usr/local/nginx/conf/nginx.conf within http{} context which maps GeoIP 2 registered nginx variable $geoip2_data_country_code to our own country variable = $country_code_allowed
    Code (Text):
    map $geoip2_data_country_code $country_code_allowed {
      default allow;
      RU deny;
      CN deny;
    }
    

    after the variable_hash_max setting like
    Code (Text):
    http {
     map_hash_bucket_size 128;
     map_hash_max_size 4096;
     server_names_hash_bucket_size 128;
     server_names_hash_max_size 2048;
     variables_hash_max_size 2048;
    
    map $geoip2_data_country_code $country_code_allowed {
      default allow;
      RU deny;
      CN deny;
    }
    

    Then within your nginx vhost's server{} context add entry
    Code (Text):
    if ($country_code_allowed = deny) {
      return 444;
    }
    

    This tells Nginx to block and not accept connections from $country_code_allowed = deny which is defined in above Nginx map as denied when $geoip2_data_country_code country codes for Russia (RU) and China (CN) are detected by GeoIP 2 Nginx module and use Nginx's own internal 444 status code which is logged by Nginx.

    Then restart Nginx and PHP-FPM services
    Code (Text):
    service nginx restart
    service php-fpm restart

    or via command shortcut
    Code (Text):
    nprestart
     
    Last edited: Apr 8, 2019
  3. eva2000

    eva2000 Administrator Staff Member

    54,524
    12,211
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +18,780
    Local Time:
    11:57 PM
    Nginx 1.27.x
    MariaDB 10.x/11.4+

    Testing Your GeoIP 2 Nginx Setups



    Now that you have setup and enabled GeoIP 2 Nginx, you can use various online tools to test if it's working. A quick one is KeyCDN's site speed performance tester at Website Speed Test | Full Page Performance Check and selecting a geographic location to test. I did test with https://geoip.centminmod.com/v2/ and Sydney location and reveals screenshot with

    keycdn-speed-test-sydney-01.png

    If you added additional nginx headers for specific GeoIP2 registered nginx variables you can also inspect HTTP headers for testing geolocation data for IP detected
    Code (Text):
      add_header Geo-City "$geoip2_data_city_name";
      add_header Geo-Country "$geoip2_data_country_code";
      add_header Geo-Asn "$geoip2_data_autonomous_system_number";
      add_header Geo-Org "$geoip2_data_autonomous_system_organization";
      add_header Geo-latitude "$geoip2_data_location_latitude";
      add_header Geo-longtitude $geoip2_data_location_longitude";
      add_header Geo-Continent "$geoip2_data_continent_code";
      add_header Geo-Registered-Ip-Country "$geoip2_data_rcountry_iso";
    


    keycdn-speed-test-sydney-02.png
     
Thread Status:
Not open for further replies.