Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added additional endpoints. #24

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
79 changes: 76 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +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"
}
```

This will also work with ip lookup
```json
{
"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
Expand All @@ -70,11 +96,28 @@ 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

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:

```sh
Expand Down Expand Up @@ -110,6 +153,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
Expand All @@ -119,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.

Expand Down Expand Up @@ -163,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/
26 changes: 20 additions & 6 deletions nginx/conf.d/geoip2.conf
Original file line number Diff line number Diff line change
@@ -1,13 +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;
$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;
$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;
}
82 changes: 36 additions & 46 deletions nginx/conf.d/ipinfo.conf
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
server {
listen 8080 default_server;
listen [::]:8080 default_server;
server_name _;
add_header X-Powered-By "ipinfo.tw/github" always;
listen 8080 default_server;
listen [::]:8080 default_server;

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;
server_name _;

set $ip_country "$ip_country_code / $ip_country_name";
set $ip_as "AS$ip_asn / $ip_aso";
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 {
log_not_found off;
Expand All @@ -26,47 +25,38 @@ 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";
}
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";
}

location ~* "/(.*)" {
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";
default_type application/json;
return 200 "{\"GeoLite2-City\":\"$ip_city_build_epoch\",\"GeoLite2-ASN\":\"$ip_as_build_epoch\"}\n";
}

location @404 {
return 404 "404 not found. See https://github.com/PeterDaveHello/ipinfo.tw \n";
default_type text/plain;
return 404 "404 not found. See https://github.com/PeterDaveHello/ipinfo.tw \n";
}
error_page 404 = @404;

Expand Down
55 changes: 55 additions & 0 deletions nginx/conf.d/map.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
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 {
"" "$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 $request_uri $ip_response_content_type {
"~^\/(json)\/?$" application/json;

# This section caters to the lookup functionality.
"~^\/lookup\/([^\/]+)\/json\/?$" application/json;

default text/plain;
}
3 changes: 3 additions & 0 deletions nginx/nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}