Seit ich von Apache auf Nginx als Webserver umgestiegen bin, verwende ich das ngx_http_geoip_module. Die Variablen kann man einerseits an PHP weitergeben, aber auch zum Beispiel einzelne Webseiten nur für bestimmt Länder freigeben. Das ist nicht immer super genau, aber um auf privaten Seiten ein paar chinesische Bots auszusperren funktioniert es ganz gut.

Um von der IP auf Geo Informationen schließen zu können werden die GeoLite Datenbanken von MaxMind benötigt. Jedoch hat MaxMind angekündigt ab dem 1. April 2018 die GeoLite Datenbanken nicht mehr zu aktualisieren. Ab dann wird es nur noch Updates für die neueren GeoLite2 Datenbanken geben. Leider kann das ngx_http_geoip_module nur mit den alten Datenbanken umgehen. Zum Glück gibt es aber das ngx_http_geoip2_module welches mit den neuen GeoLite2 Datenbanken umgehen kann.

Fall ihr selber euren Nginx aus dem Source Code baut ist die Installation sehr einfach. Es muss nur ein weiteres Modul mit –add-dynamic-module= oder –add-module= bei der Konfiguration hinzugefügt werden. Zusätzlich muss auch die libmaxminddb von MaxMind installiert sein. Falls ihr die Distributionsversion von Nginx nehmt ist das ein Problem. Hier müsst ihr entweder selber bauen oder ein weiteres Repo finden, dass das Modul mit baut.

Für Ubuntu Xenial habe ich ein PPA mit der Mainline Version von Nginx angelegt. Dort muss einfach das Paket libnginx-mod-http-geoip2 zusätzlich zu den normalen Nginx Paketen installiert werden.

Nach der Installation und dem Download der GeoLite2 Datenbanken kann es los gehen. Die Konfiguration ist hier etwas anders als bein dem alten Modul.

Zum Beispiel für die ASN Datenbank, sieht der Eintrag in die nginx.conf so aus. Der Variablen Name ist hierbei frei wählbar, nur was nach der Variable kommt ist fest. Das ganze geschieht im http { … } Kontext.

geoip2 /etc/nginx/geo2/GeoLite2-ASN.mmdb {
 $geoip2_asn_system_number autonomous_system_number;
 $geoip2_asn_system_organization autonomous_system_organization;
}

Es gibt in der GeoLite2 City jetzt auch Einträge in weiteren Sprachen als nur Englisch. Ein paar Beispiele mit der GeoLite2 City Datenbank. Auch hier sind die Variablen Namen frei wählbar, falls sie nicht schon reserviert sind. Nur der Pfad hinter den Variablen muss auf einen eindeutigen Eintrag verweisen. Eine Auswahl an möglichen Pfaden für Variablen der GeoLite2 City Datenbank.

geoip2 /etc/nginx/geo2/GeoLite2-City.mmdb {
 $geoip2_city_city_name city names en;
 $geoip2_city_city_name_de city names de;
 $geoip2_city_continent_code continent code;
 $geoip2_city_continent_name continent names en;
 $geoip2_city_continent_name_de continent names de;
 $geoip2_city_country_code country iso_code;
 $geoip2_city_country_name country names en;
 $geoip2_city_country_name_de country names de;
 $geoip2_city_subdivisions_code0 subdivisions 0 iso_code;
 $geoip2_city_subdivisions_name0 subdivisions 0 names en;
 $geoip2_city_subdivisions_name0_de subdivisions 0 names de;
 $geoip2_city_subdivisions_code1 subdivisions 1 iso_code; 
 $geoip2_city_subdivisions_name1 subdivisions 1 names en;
 $geoip2_city_subdivisions_name1_de subdivisions_de 1 names de;
}

Am einfachsten lassen sich mögliche Pfade mit dem von MaxMind erstellen Tool mmdb-bin oder mmdblookup herausfinden. So in etwa wird die Ausgabe aussehen.

{
 "continent": 
  {
    "code": 
       "NA" <utf8_string>
    "geoname_id": 
       6255149 <uint32>
    "names": 
     {
       "de": 
          "Nordamerika" <utf8_string>
       "en": 
          "North America" <utf8_string>
     }
  }
 "country": 
  {
    "geoname_id": 
       6252001 <uint32>
    "iso_code": 
       "US" <utf8_string>
    "names": 
     {
       "de": 
          "USA" <utf8_string>
       "en": 
          "United States" <utf8_string>
  }
 }
...

Dort kann man dann den Pfad „continent“ –> „names“ –> „de“ folgen und kommt zum Eintrag „Nordamerika“. Der Eintrage in der nginx.conf sieht dann in etwa so aus: $geoip2_city_continent_name_de continent names de; Der Inhalt von $geoip2_city_continent_name_de wäre in diesem Beispiel „Nordamerika“.

Nginx mit dem GeoIP2 Modul