From bcc9ec534e432b4150217366e02eef2b11f4148e Mon Sep 17 00:00:00 2001 From: Mitchell Kellett Date: Fri, 10 Mar 2023 22:49:05 +1000 Subject: [PATCH 1/3] Added functionality to allow for looking up an IP address by using NGINX maps. - New map.conf that containing maps. - Updated nginx.conf to increase map_hash_bucket_size above default value. - Updated geoip2.conf to include new variables for lookup IP addresses. - Updated ipinfo.conf to include new location blocks to allow for looking up IP addresses. Moved existing functionality for looking up requesting IP address to use NGINX maps. - Updated ipinfo.conf to remove old location blocks that have been moved to map.conf. Updated README to include details on added functionality. --- README.md | 42 +++++++++++++++++++++++++++++++++ nginx/conf.d/geoip2.conf | 12 ++++++---- nginx/conf.d/ipinfo.conf | 50 ++++++++++++---------------------------- nginx/conf.d/map.conf | 50 ++++++++++++++++++++++++++++++++++++++++ nginx/nginx.conf | 3 +++ 5 files changed, 118 insertions(+), 39 deletions(-) create mode 100644 nginx/conf.d/map.conf diff --git a/README.md b/README.md index 7cfbde7..ce568a4 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,12 @@ If you prefer to receive a machine-readable result, use path `/json` (without tr {"ip":"3.115.123.234","country_code":"JP","country_name":"Japan","asn":"16509","as_desc":"Amazon.com, Inc.","user_agent":"curl/7.58.0"} ``` +You can also use this with the lookup functionality, e.g. `https://ipinfo.tw/lookup/3.115.123.234/json`, the result will look like: + +```json +{"ip":"3.115.123.234","country_code":"JP","country_name":"Japan","asn":"16509","as_desc":"Amazon.com, Inc."} +``` + #### Endpoints You can also specify the following URI to retrieve certain info: @@ -74,6 +80,13 @@ You can also specify the following URI to retrieve certain info: - `asn`: AS number - `as_desc`: AS description - `user_agent`: User agent string +- `lookup/ip`: IP address +- `lookup/country`: Country code and name +- `lookup/country_code`: Country code +- `lookup/country_name`: Country name +- `lookup/as`: AS number and description +- `lookup/asn`: AS number +- `lookup/as_desc`: AS description Examples: @@ -110,6 +123,35 @@ Google LLC $ wget -qO- https://ipinfo.tw/user_agent Wget + +$ wget -qO- https://ipinfo.tw/lookup/157.230.195.167 +157.230.195.167 +SG / Singapore +AS14061 / DigitalOcean, LLC + +$ curl https://ipinfo.tw/lookup/18.179.200.1/ip +18.179.200.1 + +$ curl https://ipinfo.tw/lookup/18.179.200.1/country +TW / Taiwan + +$ curl https://ipinfo.tw/lookup/18.179.200.1/country_code +HK + +$ curl https://ipinfo.tw/lookup/18.179.200.1/country_name +South Korea + +$ curl https://ipinfo.tw/lookup/18.179.200.1/as +AS16509 / Amazon.com, Inc. + +$ curl https://ipinfo.tw/lookup/18.179.200.1/as +AS8075 / Microsoft Corporation + +$ curl https://ipinfo.tw/lookup/18.179.200.1/asn +15169 + +$ curl https://ipinfo.tw/lookup/18.179.200.1/as_desc +Google LLC ``` ##### Database build time endpoint diff --git a/nginx/conf.d/geoip2.conf b/nginx/conf.d/geoip2.conf index 50051de..eeb36c8 100644 --- a/nginx/conf.d/geoip2.conf +++ b/nginx/conf.d/geoip2.conf @@ -1,13 +1,17 @@ geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb { auto_reload 1d; - $ip_country_code source=$remote_addr country iso_code; - $ip_country_name source=$remote_addr country names en; + $ip_country_code source=$remote_addr country iso_code; + $ip_country_name source=$remote_addr country names en; + $lookup_ip_country_code source=$lookup_ip country iso_code; + $lookup_ip_country_name source=$lookup_ip country names en; $ip_country_build_epoch metadata build_epoch; } geoip2 /usr/share/GeoIP/GeoLite2-ASN.mmdb { auto_reload 1d; - $ip_asn source=$remote_addr autonomous_system_number; - $ip_aso source=$remote_addr autonomous_system_organization; + $ip_asn source=$remote_addr autonomous_system_number; + $ip_aso source=$remote_addr autonomous_system_organization; + $lookup_ip_asn source=$lookup_ip autonomous_system_number; + $lookup_ip_aso source=$lookup_ip autonomous_system_organization; $ip_as_build_epoch metadata build_epoch; } diff --git a/nginx/conf.d/ipinfo.conf b/nginx/conf.d/ipinfo.conf index a21c46e..2c4b3e0 100644 --- a/nginx/conf.d/ipinfo.conf +++ b/nginx/conf.d/ipinfo.conf @@ -11,9 +11,6 @@ server { add_header Referrer-Policy "no-referrer-when-downgrade" always; add_header Content-Security-Policy "default-src 'none'; img-src 'self'" always; - set $ip_country "$ip_country_code / $ip_country_name"; - set $ip_as "AS$ip_asn / $ip_aso"; - location = /favicon.ico { log_not_found off; access_log off; @@ -26,47 +23,30 @@ server { location = /github { return 301 https://github.com/PeterDaveHello/ipinfo.tw; } - location = /ip { - return 200 "$remote_addr\n"; - } - location = /country { - return 200 "$ip_country\n"; - } - location = /country_code { - return 200 "$ip_country_code\n"; - } - location = /country_name { - return 200 "$ip_country_name\n"; - } - location = /as { - return 200 "$ip_as\n"; - } - location = /asn { - return 200 "$ip_asn\n"; - } - location = /as_desc { - return 200 "$ip_aso\n"; - } - location = /user_agent { - return 200 "$http_user_agent\n"; - } + location ~* ^/index.htm(l)?$ { rewrite ^(.*)$ /; } - location = / { - return 200 "$remote_addr\n$ip_country\n$ip_as\n\n$http_user_agent\n"; + + # If looking up an IP, use this location block. + location ~* "/lookup/(.+)" { + default_type $lookup_ip_response_content_type; + return 200 $lookup_ip_response; } - location = /json { - default_type application/json; - return 200 "{\"ip\":\"$remote_addr\",\"country_code\":\"$ip_country_code\",\"country_name\":\"$ip_country_name\",\"asn\":\"$ip_asn\",\"as_desc\":\"$ip_aso\",\"user_agent\":\"$http_user_agent\"}\n"; + + # If using the requesting IP, use this location block. + location ~* "/(.*)" { + default_type $ip_response_content_type; + return 200 $ip_response; } + location = /build_epoch { - default_type application/json; - return 200 "{\"GeoLite2-Country\":\"$ip_country_build_epoch\",\"GeoLite2-ASN\":\"$ip_as_build_epoch\"}\n"; + default_type application/json; + return 200 "{\"GeoLite2-Country\":\"$ip_country_build_epoch\",\"GeoLite2-ASN\":\"$ip_as_build_epoch\"}\n"; } location @404 { - return 404 "404 not found. See https://github.com/PeterDaveHello/ipinfo.tw \n"; + return 404 "404 not found. See https://github.com/PeterDaveHello/ipinfo.tw \n"; } error_page 404 = @404; diff --git a/nginx/conf.d/map.conf b/nginx/conf.d/map.conf new file mode 100644 index 0000000..fcd17b8 --- /dev/null +++ b/nginx/conf.d/map.conf @@ -0,0 +1,50 @@ +map $1 $lookup_ip { + # Regex to test for IPv4 in NGINX Map + "~(([0-9]{1,3}\.){3}[0-9]{1,3})" $1; + + # Regex to test for IPv6 in NGINX Map + "~(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))" $1; + + default ""; +} + +# If using the requesting IP, use this map block to determine which response to provide. +map $1 $ip_response { + "~lookup\/?$" "Invalid IP.\n\nPlease enter valid IPv4 or IPv6 address.\n\nExample: /lookup/1.1.1.1 or /lookup/2606:4700:4700:0000:1111\n"; + "~ip\/?$" "$remote_addr\n"; + "~country\/?$" "$ip_country_code / $ip_country_name\n"; + "~country_code\/?$" "$ip_country_code\n"; + "~country_name\/?$" "$ip_country_name\n"; + "~(as\/?$)" "AS$ip_asn / $ip_aso\n"; + "~(asn\/?$)" "$ip_asn\n"; + "~(as_desc\/?$)" "$ip_aso\n"; + "~(json)\/?$" "{\"ip\":\"$remote_addr\",\"country_code\":\"$ip_country_code\",\"country_name\":\"$ip_country_name\",\"asn\":\"$ip_asn\",\"as_desc\":\"$ip_aso\",\"user_agent\":\"$http_user_agent\"}\n"; + default "$remote_addr\n$ip_country\n$ip_as\n\n$http_user_agent\n"; +} + +# If using the requesting IP, use this map block to determine which response type to provide. +map $1 $ip_response_content_type { + "~\/json\/?$" "default_type application/json;"; + default "default_type text/plain;"; +} + +# If looking up an IP, use this map block to determine which response to provide. +map $1 $lookup_ip_response { + "~((.)+)\/ip\/?$" "$lookup_ip\n"; + "~((.)+)\/country\/?$" "$lookup_ip_country_code / $lookup_ip_country_name\n"; + "~((.)+)\/country_code\/?$" "$lookup_ip_country_code\n"; + "~((.)+)\/country_name\/?$" "$lookup_ip_country_name\n"; + "~((.)+)(\/as\/?\/?$)" "AS$lookup_ip_asn / $lookup_ip_aso\n"; + "~((.)+)(\/asn\/?$)" "$lookup_ip_asn\n"; + "~((.)+)(\/as_desc\/?$)" "$lookup_ip_aso\n"; + "~((.)+)\/json\/?$" "{\"ip\":\"$lookup_ip\",\"country_code\":\"$lookup_ip_country_code\",\"country_name\":\"$lookup_ip_country_name\",\"asn\":\"$lookup_ip_asn\",\"as_desc\":\"$lookup_ip_aso\"}\n"; + "~(([0-9]{1,3}\.){3}[0-9]{1,3})\/?$" "$lookup_ip\n$lookup_ip_country_code / $lookup_ip_country_name\nAS$lookup_ip_asn / $lookup_ip_aso\n"; + "~(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/?$" "$lookup_ip\n$lookup_ip_country_code / $lookup_ip_country_name\nAS$lookup_ip_asn / $lookup_ip_aso\n"; + default "Invalid IP.\n\nPlease enter valid IPv4 or IPv6 address.\n\nExample: /lookup/1.1.1.1 or /lookup/2606:4700:4700:0000:1111\n"; +} + +# If looking up an IP, use this map block to determine which response type to provide. +map $1 $lookup_ip_response_content_type { + "~((.)+)\/json\/?$" "default_type application/json;"; + default "default_type text/plain;"; +} \ No newline at end of file diff --git a/nginx/nginx.conf b/nginx/nginx.conf index b88ce89..87a2053 100644 --- a/nginx/nginx.conf +++ b/nginx/nginx.conf @@ -23,5 +23,8 @@ http { tcp_nodelay on; types_hash_max_size 2048; + map_hash_max_size 2048; + map_hash_bucket_size 1024; + include /etc/nginx/conf.d/*.conf; } From b006807cba32492856174d389329de4f7220f69e Mon Sep 17 00:00:00 2001 From: Mitchell Kellett Date: Sat, 11 Mar 2023 10:10:58 +1000 Subject: [PATCH 2/3] Using City database instead of Country; updated throughout. Added build data to headers. Formatting updated throughout. Updated regex to fix identified bug in map.conf. --- Dockerfile | 10 +++--- nginx/conf.d/geoip2.conf | 30 ++++++++++------ nginx/conf.d/ipinfo.conf | 50 +++++++++++++++----------- nginx/conf.d/map.conf | 77 +++++++++++++++++++++------------------- 4 files changed, 96 insertions(+), 71 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0b8274c..fa2281a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,11 +13,11 @@ RUN sed 's/GeoLite2-ASN_[0-9]*.tar.gz/GeoLite2-ASN.tar.gz/g' -i GeoLite2-ASN.tar RUN sha256sum -c GeoLite2-ASN.tar.gz.sha256 RUN tar xvf GeoLite2-ASN.tar.gz --strip 1 -RUN wget "${MAXMIND_BASE_URL}edition_id=GeoLite2-Country&suffix=tar.gz" -O GeoLite2-Country.tar.gz -RUN wget "${MAXMIND_BASE_URL}edition_id=GeoLite2-Country&suffix=tar.gz.sha256" -O GeoLite2-Country.tar.gz.sha256 -RUN sed 's/GeoLite2-Country_[0-9]*.tar.gz/GeoLite2-Country.tar.gz/g' -i GeoLite2-Country.tar.gz.sha256 -RUN sha256sum -c GeoLite2-Country.tar.gz.sha256 -RUN tar xvf GeoLite2-Country.tar.gz --strip 1 +RUN wget "${MAXMIND_BASE_URL}edition_id=GeoLite2-City&suffix=tar.gz" -O GeoLite2-City.tar.gz +RUN wget "${MAXMIND_BASE_URL}edition_id=GeoLite2-City&suffix=tar.gz.sha256" -O GeoLite2-City.tar.gz.sha256 +RUN sed 's/GeoLite2-City_[0-9]*.tar.gz/GeoLite2-City.tar.gz/g' -i GeoLite2-City.tar.gz.sha256 +RUN sha256sum -c GeoLite2-City.tar.gz.sha256 +RUN tar xvf GeoLite2-City.tar.gz --strip 1 FROM alpine:3.17 as release LABEL name="ipinfo.tw" diff --git a/nginx/conf.d/geoip2.conf b/nginx/conf.d/geoip2.conf index eeb36c8..1e1cc22 100644 --- a/nginx/conf.d/geoip2.conf +++ b/nginx/conf.d/geoip2.conf @@ -1,17 +1,27 @@ -geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb { +geoip2 /usr/share/GeoIP/GeoLite2-City.mmdb { auto_reload 1d; - $ip_country_code source=$remote_addr country iso_code; - $ip_country_name source=$remote_addr country names en; - $lookup_ip_country_code source=$lookup_ip country iso_code; - $lookup_ip_country_name source=$lookup_ip country names en; - $ip_country_build_epoch metadata build_epoch; + $ip_country_code source=$remote_addr country iso_code; + $ip_country_name source=$remote_addr country names en; + $ip_city_name source=$remote_addr city names en; + $ip_latitude source=$remote_addr location latitude; + $ip_longitude source=$remote_addr location longitude; + $ip_accuracy_radius source=$remote_addr location accuracy_radius; + $ip_time_zone source=$remote_addr location time_zone; + $lookup_ip_country_code source=$lookup_ip country iso_code; + $lookup_ip_country_name source=$lookup_ip country names en; + $lookup_ip_city_name source=$lookup_ip city names en; + $lookup_ip_latitude source=$lookup_ip location latitude; + $lookup_ip_longitude source=$lookup_ip location longitude; + $lookup_ip_accuracy_radius source=$lookup_ip location accuracy_radius; + $lookup_ip_time_zone source=$lookup_ip location time_zone; + $ip_city_build_epoch metadata build_epoch; } geoip2 /usr/share/GeoIP/GeoLite2-ASN.mmdb { auto_reload 1d; - $ip_asn source=$remote_addr autonomous_system_number; - $ip_aso source=$remote_addr autonomous_system_organization; - $lookup_ip_asn source=$lookup_ip autonomous_system_number; - $lookup_ip_aso source=$lookup_ip autonomous_system_organization; + $ip_asn source=$remote_addr autonomous_system_number; + $ip_aso source=$remote_addr autonomous_system_organization; + $lookup_ip_asn source=$lookup_ip autonomous_system_number; + $lookup_ip_aso source=$lookup_ip autonomous_system_organization; $ip_as_build_epoch metadata build_epoch; } diff --git a/nginx/conf.d/ipinfo.conf b/nginx/conf.d/ipinfo.conf index 2c4b3e0..e0281ca 100644 --- a/nginx/conf.d/ipinfo.conf +++ b/nginx/conf.d/ipinfo.conf @@ -1,14 +1,16 @@ server { - listen 8080 default_server; - listen [::]:8080 default_server; - server_name _; - add_header X-Powered-By "ipinfo.tw/github" always; - - add_header Cache-Control "no-store" always; - add_header X-Frame-Options "SAMEORIGIN" always; - add_header X-XSS-Protection "1; mode=block" always; - add_header X-Content-Type-Options "nosniff" always; - add_header Referrer-Policy "no-referrer-when-downgrade" always; + listen 8080 default_server; + listen [::]:8080 default_server; + + server_name _; + + add_header X-Powered-By "ipinfo.tw/github" always; + add_header X-GeoLite2-ASN-Build $ip_as_build_epoch always; + add_header Cache-Control "no-store" always; + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header X-Content-Type-Options "nosniff" always; + add_header Referrer-Policy "no-referrer-when-downgrade" always; add_header Content-Security-Policy "default-src 'none'; img-src 'self'" always; location = /favicon.ico { @@ -28,24 +30,32 @@ server { rewrite ^(.*)$ /; } - # If looking up an IP, use this location block. - location ~* "/lookup/(.+)" { - default_type $lookup_ip_response_content_type; - return 200 $lookup_ip_response; - } - - # If using the requesting IP, use this location block. location ~* "/(.*)" { - default_type $ip_response_content_type; + default_type ""; + + if ($request_uri ~* "/(.*)") { + add_header Content-Type $ip_response_content_type; + add_header X-Powered-By "ipinfo.tw/github" always; + add_header X-GeoLite2-City-Build $ip_city_build_epoch always; + add_header X-GeoLite2-ASN-Build $ip_as_build_epoch always; + add_header Cache-Control "no-store" always; + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header X-Content-Type-Options "nosniff" always; + add_header Referrer-Policy "no-referrer-when-downgrade" always; + add_header Content-Security-Policy "default-src 'none'; img-src 'self'" always; + } + return 200 $ip_response; - } +} location = /build_epoch { default_type application/json; - return 200 "{\"GeoLite2-Country\":\"$ip_country_build_epoch\",\"GeoLite2-ASN\":\"$ip_as_build_epoch\"}\n"; + return 200 "{\"GeoLite2-City\":\"$ip_city_build_epoch\",\"GeoLite2-ASN\":\"$ip_as_build_epoch\"}\n"; } location @404 { + default_type text/plain; return 404 "404 not found. See https://github.com/PeterDaveHello/ipinfo.tw \n"; } error_page 404 = @404; diff --git a/nginx/conf.d/map.conf b/nginx/conf.d/map.conf index fcd17b8..b7afd68 100644 --- a/nginx/conf.d/map.conf +++ b/nginx/conf.d/map.conf @@ -1,50 +1,55 @@ map $1 $lookup_ip { # Regex to test for IPv4 in NGINX Map - "~(([0-9]{1,3}\.){3}[0-9]{1,3})" $1; + "~(([0-9]{1,3}\.){3}[0-9]{1,3})" $1; # Regex to test for IPv6 in NGINX Map "~(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))" $1; - default ""; + default ""; } # If using the requesting IP, use this map block to determine which response to provide. map $1 $ip_response { - "~lookup\/?$" "Invalid IP.\n\nPlease enter valid IPv4 or IPv6 address.\n\nExample: /lookup/1.1.1.1 or /lookup/2606:4700:4700:0000:1111\n"; - "~ip\/?$" "$remote_addr\n"; - "~country\/?$" "$ip_country_code / $ip_country_name\n"; - "~country_code\/?$" "$ip_country_code\n"; - "~country_name\/?$" "$ip_country_name\n"; - "~(as\/?$)" "AS$ip_asn / $ip_aso\n"; - "~(asn\/?$)" "$ip_asn\n"; - "~(as_desc\/?$)" "$ip_aso\n"; - "~(json)\/?$" "{\"ip\":\"$remote_addr\",\"country_code\":\"$ip_country_code\",\"country_name\":\"$ip_country_name\",\"asn\":\"$ip_asn\",\"as_desc\":\"$ip_aso\",\"user_agent\":\"$http_user_agent\"}\n"; - default "$remote_addr\n$ip_country\n$ip_as\n\n$http_user_agent\n"; + "" "$remote_addr\n$ip_country_code / $ip_country_name\nAS$ip_asn / $ip_aso\n$ip_latitude, $ip_longitude\n$ip_accuracy_radius KM\n$ip_time_zone\n\n$http_user_agent\n"; + "~^ip\/?$" "$remote_addr\n"; + "~^country\/?$" "$ip_country_code / $ip_country_name\n"; + "~^country_code\/?$" "$ip_country_code\n"; + "~^country_name\/?$" "$ip_country_name\n"; + "~^city_name\/?$" "$ip_city_name\n"; + "~^geo\/?$" "$ip_latitude, $ip_longitude\n"; + "~^accuracy_radius\/?$" "$ip_accuracy_radius\n"; + "~^time_zone\/?$" "$ip_time_zone\n"; + "~^(as\/?$)" "AS$ip_asn / $ip_aso\n"; + "~^(asn\/?$)" "$ip_asn\n"; + "~^(as_desc\/?$)" "$ip_aso\n"; + "~^(user_agent\/?$)" "$http_user_agent\n"; + "~^(json)\/?$" "{\"ip\":\"$remote_addr\",\"country_code\":\"$ip_country_code\",\"country_name\":\"$ip_country_name\",\"asn\":\"$ip_asn\",\"as_desc\":\"$ip_aso\",\"latitude\":\"$ip_latitude\",\"longitude\":\"$ip_longitude\",\"accuracy_radius\":\"$ip_accuracy_radius\",\"time_zone\":\"$ip_time_zone\",\"user_agent\":\"$http_user_agent\"}\n"; + + # This section caters to the lookup functionality. + "~^lookup\/?$" "Invalid IP.\n\nPlease enter valid IPv4 or IPv6 address.\n\nExample: /lookup/1.1.1.1 or /lookup/2606:4700:4700:0000:1111\n"; + "~^lookup\/([^\/]+)\/ip\/?$" "$lookup_ip\n"; + "~^lookup\/([^\/]+)\/country\/?$" "$lookup_ip_country_code / $lookup_ip_country_name\n"; + "~^lookup\/([^\/]+)\/country_code\/?$" "$lookup_ip_country_code\n"; + "~^lookup\/([^\/]+)\/country_name\/?$" "$lookup_ip_country_name\n"; + "~^lookup\/([^\/]+)\/city_name\/?$" "$lookup_ip_city_name\n"; + "~^lookup\/([^\/]+)\/geo\/?$" "$lookup_ip_latitude, $lookup_ip_longitude\n"; + "~^lookup\/([^\/]+)\/accuracy_radius\/?$" "$lookup_ip_accuracy_radius\n"; + "~^lookup\/([^\/]+)\/time_zone\/?$" "$lookup_ip_time_zone\n"; + "~^lookup\/([^\/]+)\/as\/?$" "AS$lookup_ip_asn / $lookup_ip_aso\n"; + "~^lookup\/([^\/]+)\/asn\/?$" "$lookup_ip_asn\n"; + "~^lookup\/([^\/]+)\/as_desc\/?$" "$lookup_ip_aso\n"; + "~^lookup\/([^\/]+)\/json\/?$" "{\"ip\":\"$lookup_ip\",\"country_code\":\"$lookup_ip_country_code\",\"country_name\":\"$lookup_ip_country_name\",\"asn\":\"$lookup_ip_asn\",\"as_desc\":\"$lookup_ip_aso\",\"latitude\":\"$lookup_ip_latitude\",\"longitude\":\"$lookup_ip_longitude\",\"accuracy_radius\":\"$lookup_ip_accuracy_radius\",\"time_zone\":\"$lookup_ip_time_zone\"}\n"; + "~^lookup\/([^\/]+)\/?$" "$lookup_ip\n$lookup_ip_country_code / $lookup_ip_country_name\nAS$lookup_ip_asn / $lookup_ip_aso\n$lookup_ip_latitude, $lookup_ip_longitude\n$lookup_ip_accuracy_radius KM\n$lookup_ip_time_zone\n"; + + default "404 not found. See https://github.com/PeterDaveHello/ipinfo.tw \n"; } # If using the requesting IP, use this map block to determine which response type to provide. -map $1 $ip_response_content_type { - "~\/json\/?$" "default_type application/json;"; - default "default_type text/plain;"; -} - -# If looking up an IP, use this map block to determine which response to provide. -map $1 $lookup_ip_response { - "~((.)+)\/ip\/?$" "$lookup_ip\n"; - "~((.)+)\/country\/?$" "$lookup_ip_country_code / $lookup_ip_country_name\n"; - "~((.)+)\/country_code\/?$" "$lookup_ip_country_code\n"; - "~((.)+)\/country_name\/?$" "$lookup_ip_country_name\n"; - "~((.)+)(\/as\/?\/?$)" "AS$lookup_ip_asn / $lookup_ip_aso\n"; - "~((.)+)(\/asn\/?$)" "$lookup_ip_asn\n"; - "~((.)+)(\/as_desc\/?$)" "$lookup_ip_aso\n"; - "~((.)+)\/json\/?$" "{\"ip\":\"$lookup_ip\",\"country_code\":\"$lookup_ip_country_code\",\"country_name\":\"$lookup_ip_country_name\",\"asn\":\"$lookup_ip_asn\",\"as_desc\":\"$lookup_ip_aso\"}\n"; - "~(([0-9]{1,3}\.){3}[0-9]{1,3})\/?$" "$lookup_ip\n$lookup_ip_country_code / $lookup_ip_country_name\nAS$lookup_ip_asn / $lookup_ip_aso\n"; - "~(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/?$" "$lookup_ip\n$lookup_ip_country_code / $lookup_ip_country_name\nAS$lookup_ip_asn / $lookup_ip_aso\n"; - default "Invalid IP.\n\nPlease enter valid IPv4 or IPv6 address.\n\nExample: /lookup/1.1.1.1 or /lookup/2606:4700:4700:0000:1111\n"; -} - -# If looking up an IP, use this map block to determine which response type to provide. -map $1 $lookup_ip_response_content_type { - "~((.)+)\/json\/?$" "default_type application/json;"; - default "default_type text/plain;"; +map $request_uri $ip_response_content_type { + "~^\/(json)\/?$" application/json; + + # This section caters to the lookup functionality. + "~^\/lookup\/([^\/]+)\/json\/?$" application/json; + + default text/plain; } \ No newline at end of file From b57477643df40afdeff95718f02ecdde2181ed90 Mon Sep 17 00:00:00 2001 From: Mitchell Kellett Date: Tue, 11 Apr 2023 09:35:32 +1000 Subject: [PATCH 3/3] Added additional info to README, expanded examples. --- README.md | 57 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index ce568a4..7766ace 100644 --- a/README.md +++ b/README.md @@ -59,13 +59,33 @@ Without any specified URI, the server will return IP address, country, AS, and u If you prefer to receive a machine-readable result, use path `/json` (without trailing slash), e.g. `https://ipinfo.tw/json`, the result will look like: ```json -{"ip":"3.115.123.234","country_code":"JP","country_name":"Japan","asn":"16509","as_desc":"Amazon.com, Inc.","user_agent":"curl/7.58.0"} +{ + "ip": "3.115.123.234", + "country_code": "JP", + "country_name": "Japan", + "asn": "16509", + "as_desc": "AMAZON-02", + "latitude": "35.68930", + "longitude": "139.68990", + "accuracy_radius": "1000", + "time_zone": "Asia/Tokyo", + "user_agent":"curl/7.58.0" +} ``` -You can also use this with the lookup functionality, e.g. `https://ipinfo.tw/lookup/3.115.123.234/json`, the result will look like: - +This will also work with ip lookup ```json -{"ip":"3.115.123.234","country_code":"JP","country_name":"Japan","asn":"16509","as_desc":"Amazon.com, Inc."} +{ + "ip": "3.115.123.234", + "country_code": "JP", + "country_name": "Japan", + "asn": "16509", + "as_desc": "AMAZON-02", + "latitude": "35.68930", + "longitude": "139.68990", + "accuracy_radius": "1000", + "time_zone": "Asia/Tokyo" +} ``` #### Endpoints @@ -76,17 +96,27 @@ You can also specify the following URI to retrieve certain info: - `country`: Country code and name - `country_code`: Country code - `country_name`: Country name +- `city_name`: City name +- `geo`: Longitude & Latitude +- `accuracy_radius`: Longitude & Latitude accuracy +- `time_zone`: Timezone - `as`: AS number and description - `asn`: AS number - `as_desc`: AS description - `user_agent`: User agent string -- `lookup/ip`: IP address -- `lookup/country`: Country code and name -- `lookup/country_code`: Country code -- `lookup/country_name`: Country name -- `lookup/as`: AS number and description -- `lookup/asn`: AS number -- `lookup/as_desc`: AS description + +You can also specify the following URI to retrieve certain info about an IP. Replace "{ip_address}" with the IPv4 or IPv6 you want to lookup. +- `lookup/{ip_address}/ip`: IP address +- `lookup/{ip_address}/country`: Country code and name +- `lookup/{ip_address}/country_code`: Country code +- `lookup/{ip_address}/country_name`: Country name +- `lookup/{ip_address}/city_name`: City name +- `lookup/{ip_address}/geo`: Longitude & Latitude +- `lookup/{ip_address}/accuracy_radius`: Longitude & Latitude accuracy +- `lookup/{ip_address}/time_zone`: Timezone +- `lookup/{ip_address}/as`: AS number and description +- `lookup/{ip_address}/asn`: AS number +- `lookup/{ip_address}/as_desc`: AS description Examples: @@ -161,8 +191,9 @@ There is a special endpoint - `/build_epoch`, which will return a json object th The response of `/build_epoch` will be look like: ```json -{"GeoLite2-Country":"1655395486","GeoLite2-ASN":"1655730848"} +{"GeoLite2-City":"1655395486","GeoLite2-ASN":"1655730848"} ``` +These are also included in the headers as `X-GeoLite2-City-Build` and `X-GeoLite2-ASN-Build`. As mentioned above, on the demo domain - `ipinfo.tw`, if `https://` is not specified in the URL, connection will be redirected from http to https, in this case, `curl` will need an additional parameter: `-L`/`--location` to follow location redirection. @@ -205,4 +236,4 @@ This project is released under the GPL-3.0 license. [5]:https://alpinelinux.org/ [6]:https://nginx.org/ [7]:https://github.com/leev/ngx_http_geoip2_module -[8]:https://www.docker.com/ +[8]:https://www.docker.com/ \ No newline at end of file