Last active
May 30, 2021 15:01
-
-
Save SoftCreatR/9d9723a5833dc2d1c4fe5635bbcc083d to your computer and use it in GitHub Desktop.
IP Address Information in pure nginx, using GeoIP2, JSON Var Module and some mapping magic.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
##### | |
# IPInfo Host configuration | |
# | |
# Source: https://gist.github.com/SoftCreatR | |
# | |
# Requires: | |
# - ngx_http_json_var_module (https://github.com/SoftCreatR/nginx-json-var-module) | |
# - geoip2.conf (see below) | |
##### | |
include conf.d/geoip2.conf; | |
map $remote_addr $remote_addr_type | |
{ | |
default "v4"; | |
~: "v6"; | |
} | |
json_var $ipinfo_json | |
{ | |
ip $remote_addr; | |
type $remote_addr_type; | |
city_name $geoip_city_name; | |
zip_code $geoip_postal_code; | |
region_code $geoip_region_code; | |
region_name $geoip_region_name; | |
country_code $geoip_city_country_code; | |
country_name $geoip_country_name; | |
is_in_european_union $geoip_country_is_in_european_union; | |
continent_code $geoip_country_continent_code; | |
continent_name $geoip_country_continent_name; | |
lat $geoip_latitude; | |
lon $geoip_longitude; | |
timezone $geoip_timezone; | |
asn "AS$geoip_asn"; | |
isp $geoip_aso; | |
} | |
map $request_uri $ipinfo_output_data_by_request | |
{ | |
default $ipinfo_json; | |
~/ip $remote_addr; | |
~/city $geoip_city_name; | |
~/(zip|postal) $geoip_postal_code; | |
~/region $geoip_region_name; | |
~/country $geoip_country_name; | |
~/continent $geoip_country_continent_name; | |
~/lat $geoip_latitude; | |
~/lon $geoip_longitude; | |
~/loc "$geoip_latitude,$geoip_longitude"; | |
~/timezone $geoip_timezone; | |
~/asn "AS$geoip_asn"; | |
~/isp $geoip_aso; | |
~/org "AS$geoip_asn $geoip_aso"; | |
} | |
server | |
{ | |
listen *:80; | |
listen *:443 ssl http2; | |
# Define your hostname(s) here | |
server_name myip4.softcreatr.com | |
myip.softcreatr.com; | |
## | |
# Load additional config here, if needed. | |
## | |
location / | |
{ | |
access_log off; | |
default_type "application/json"; | |
add_header Access-Control-Allow-Origin "*"; | |
return 200 "$ipinfo_output_data_by_request"; | |
} | |
location ~ ^/(ip|city|zip|postal|region|country|continent|lat|lon|loc|timezone|asn|isp|org)$ | |
{ | |
access_log off; | |
default_type "text/plain"; | |
add_header Access-Control-Allow-Origin "*"; | |
return 200 "$ipinfo_output_data_by_request"; | |
} | |
} | |
server | |
{ | |
listen [::]:80; | |
listen [::]:443 ssl http2; | |
# Define your hostname(s) here | |
server_name myip6.softcreatr.com | |
myip.softcreatr.com; | |
## | |
# Load additional config here, if needed. | |
## | |
location / | |
{ | |
access_log off; | |
default_type "application/json"; | |
add_header Access-Control-Allow-Origin "*"; | |
return 200 "$ipinfo_output_data_by_request"; | |
} | |
location ~ ^/(ip|city|zip|postal|region|country|continent|lat|lon|loc|timezone|asn|isp|org)$ | |
{ | |
access_log off; | |
default_type "text/plain"; | |
add_header Access-Control-Allow-Origin "*"; | |
return 200 "$ipinfo_output_data_by_request"; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
##### | |
# GeoIP2 configuration | |
# | |
# Source: https://gist.github.com/SoftCreatR | |
# | |
# Requires: | |
# - ngx_http_geoip2_module (https://github.com/leev/ngx_http_geoip2_module) | |
# - libmaxminddb (https://github.com/maxmind/libmaxminddb) | |
# - GeoLite 2 databases (City, Country, ASN - https://dev.maxmind.com/geoip/geoip2/geolite2/) | |
##### | |
# GeoIP: Country | |
geoip2 /opt/geoip/GeoLite2-Country.mmdb | |
{ | |
# continent | |
$geoip_country_continent_code continent code; | |
$geoip_country_continent_name_de continent names de; | |
$geoip_country_continent_name_en continent names en; | |
$geoip_country_continent_name_es continent names es; | |
$geoip_country_continent_name_fr continent names fr; | |
$geoip_country_continent_name_ja continent names ja; | |
$geoip_country_continent_name_pt_br continent names pt-BR; | |
$geoip_country_continent_name_ru continent names ru; | |
$geoip_country_continent_name_zh_cn continent names zh-CN; | |
# country | |
$geoip_country_is_in_european_union country is_in_european_union; | |
$geoip_country_code default=XX country iso_code; | |
$geoip_country_name_de country names de; | |
$geoip_country_name_en country names en; | |
$geoip_country_name_es country names es; | |
$geoip_country_name_fr country names fr; | |
$geoip_country_name_ja country names ja; | |
$geoip_country_name_pt_br country names pt-BR; | |
$geoip_country_name_ru country names ru; | |
$geoip_country_name_zh_cn country names zh-CN; | |
} | |
# GeoIP: City | |
geoip2 /opt/geoip/GeoLite2-City.mmdb | |
{ | |
# city | |
$geoip_city_name_de city names de; | |
$geoip_city_name_en city names en; | |
$geoip_city_name_es city names es; | |
$geoip_city_name_fr city names fr; | |
$geoip_city_name_ja city names ja; | |
$geoip_city_name_pt_br city names pt-BR; | |
$geoip_city_name_ru city names ru; | |
$geoip_city_name_zh_cn city names zh-CN; | |
# continent | |
$geoip_city_continent_code continent code; | |
$geoip_city_continent_name_de continent names de; | |
$geoip_city_continent_name_en continent names en; | |
$geoip_city_continent_name_es continent names es; | |
$geoip_city_continent_name_fr continent names fr; | |
$geoip_city_continent_name_ja continent names ja; | |
$geoip_city_continent_name_pt_br continent names pt-BR; | |
$geoip_city_continent_name_ru continent names ru; | |
$geoip_city_continent_name_zh_cn continent names zh-CN; | |
# country | |
$geoip_city_country_code default=XX country iso_code; | |
$geoip_city_country_name_de country names de; | |
$geoip_city_country_name_en country names en; | |
$geoip_city_country_name_es country names es; | |
$geoip_city_country_name_fr country names fr; | |
$geoip_city_country_name_ja country names ja; | |
$geoip_city_country_name_pt_br country names pt-BR; | |
$geoip_city_country_name_ru country names ru; | |
$geoip_city_country_name_zh_cn country names zh-CN; | |
# location | |
$geoip_accuracy_radius location accuracy_radius; | |
$geoip_latitude location latitude; | |
$geoip_longitude location longitude; | |
$geoip_timezone location time_zone; | |
# postal | |
$geoip_postal_code postal code; | |
# subdivisions | |
$geoip_region_code subdivisions 0 iso_code; | |
$geoip_region_name_de subdivisions 0 names de; | |
$geoip_region_name_en subdivisions 0 names en; | |
$geoip_region_name_es subdivisions 0 names es; | |
$geoip_region_name_fr subdivisions 0 names fr; | |
$geoip_region_name_ru subdivisions 0 names ru; | |
} | |
# GeoIP: ASN | |
geoip2 /opt/geoip/GeoLite2-ASN.mmdb | |
{ | |
$geoip_asn autonomous_system_number; | |
$geoip_aso autonomous_system_organization; | |
} | |
# Variables | |
map $http_accept_language $geoip_city_name | |
{ | |
default $geoip_city_name_en; | |
~de $geoip_city_name_de; | |
~es $geoip_city_name_es; | |
~fr $geoip_city_name_fr; | |
~ja $geoip_city_name_ja; | |
~pt-br $geoip_city_name_pt_br; | |
~ru $geoip_city_name_ru; | |
~zh-cn $geoip_city_name_zh_cn; | |
} | |
map $http_accept_language $geoip_region_name | |
{ | |
default $geoip_region_name_en; | |
~de $geoip_region_name_de; | |
~es $geoip_region_name_es; | |
~fr $geoip_region_name_fr; | |
~ru $geoip_region_name_ru; | |
} | |
map $http_accept_language $geoip_country_name | |
{ | |
default $geoip_country_name_en; | |
~de $geoip_country_name_de; | |
~es $geoip_country_name_es; | |
~fr $geoip_country_name_fr; | |
~ja $geoip_country_name_ja; | |
~pt-br $geoip_country_name_pt_br; | |
~ru $geoip_country_name_ru; | |
~zh-cn $geoip_country_name_zh_cn; | |
} | |
map $http_accept_language $geoip_country_continent_name | |
{ | |
default $geoip_country_continent_name_en; | |
~de $geoip_country_continent_name_de; | |
~es $geoip_country_continent_name_es; | |
~fr $geoip_country_continent_name_fr; | |
~ja $geoip_country_continent_name_ja; | |
~pt-br $geoip_country_continent_name_pt_br; | |
~ru $geoip_country_continent_name_ru; | |
~zh-cn $geoip_country_continent_name_zh_cn; | |
} |
This may come in handy, if you want to add a route that matches IPv6 addresses:
location ~ "^/((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:)))(%.+)?$"
{
# yadda
}
Example: https://myip.softcreatr.com/2605:8600:223:c497:6999:8ebc:1b9a:f216
For IPv4:
location ~ "^/((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9]).){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$"
{
# yadda
}
Example: https://myip.softcreatr.com/79.181.52.28
And combined:
location ~ "^/((((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:)))(%.+)?$)|((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9]).){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9]))"
{
# yadda
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Instead of using the JSON var module, you could simply create a variable by hand, containing valid JSON to return (which is more flexible than the module but not required in our case).