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 extra IP Stack fields #2

Merged
merged 2 commits into from
Oct 4, 2023
Merged
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
15 changes: 14 additions & 1 deletion cmd/echoip/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ func main() {
var ipstackApiKey string
service := flag.String("d", "geoip", "Which database to use, 'ipstack' or 'geoip'")
flag.StringVar(&ipstackApiKey, "S", "", "IP Stack API Key")
ipStackEnableSecurityModule := flag.Bool("x", false, "Enable security module for IP Stack ( must have security module, aka. non-free account. )")
ipStackUseHttps := flag.Bool("h", false, "Use HTTPS for IP Stack ( only non-free accounts )")
countryFile := flag.String("f", "", "Path to GeoIP country database")
cityFile := flag.String("c", "", "Path to GeoIP city database")
asnFile := flag.String("a", "", "Path to GeoIP ASN database")
Expand All @@ -56,6 +58,7 @@ func main() {

var parser parser.Parser
if *service == "geoip" {
log.Print("Using GeoIP for IP database")
geo, err := geo.Open(*countryFile, *cityFile, *asnFile)
if err != nil {
log.Fatal(err)
Expand All @@ -64,7 +67,17 @@ func main() {
}

if *service == "ipstack" {
if err := ipstackApi.Init(ipstackApiKey); err != nil {
log.Print("Using GeoIP for IP database")
if *ipStackEnableSecurityModule {
log.Print("Enable Security Module ( Requires Professional Plus account )")
}
enableSecurity := ipstackApi.ParamEnableSecurity(*ipStackEnableSecurityModule)
apiKey := ipstackApi.ParamToken(ipstackApiKey)
useHttps := ipstackApi.ParamUseHTTPS(*ipStackUseHttps)
if *ipStackUseHttps {
log.Print("Use IP Stack HTTPS API ( Requires non-free account )")
}
if err := ipstackApi.Init(apiKey, enableSecurity, useHttps); err != nil {
log.Fatal(err)
}
ips := ipstack.IPStack{}
Expand Down
44 changes: 43 additions & 1 deletion html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@ <h2>What do we know about this IP address?</h2>
<th scope="row">Timezone</th>
<td>{{ .Timezone }}</td>
</tr>
{{ end }} {{ if .IsDayLightSavings }}
<tr>
<th scope="row">Is Daylight Savings?</th>
<td>{{ .IsDayLightSavings }}</td>
</tr>
{{ end }} {{ if .ASN }}
<tr>
<th scope="row">ASN</th>
Expand Down Expand Up @@ -166,7 +171,44 @@ <h2>What do we know about this IP address?</h2>
<th scope="row">User&nbsp;agent: Raw</th>
<td>{{ .UserAgent.RawValue }}</td>
</tr>
{{ end }} {{ end }}
{{ end }}

{{ if .IPStackSecurityEnabled }}
<tr>
<th scope="row">Is Proxy?</th>
<td>{{ .IsProxy }}</td>
</tr>
<tr>
<th scope="row">Is Crawler?</th>
<td>{{ .IsCrawler }}</td>
</tr>

{{ if .IsCrawler }}
<tr>
<th scope="row">Crawler Name</th>
<td>{{ .CrawlerName }}</td>
</tr>
<tr>
<th scope="row">Crawler Type</th>
<td>{{ .CrawlerType }}</td>
</tr>
{{ end }}

<tr>
<th scope="row">Is Tor?</th>
<td>{{ .IsTor }}</td>
</tr>
<tr>
<th scope="row">Threat Level</th>
<td>{{ .ThreatLevel }}</td>
</tr>
<tr>
<th scope="row">Threat Types</th>
<td>{{ .ThreatTypes }}</td>
</tr>
{{ end }}

{{ end }}
</table>
{{ if .Country }} {{ if .UsingGeoIP }}
<p>
Expand Down
4 changes: 2 additions & 2 deletions http/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ func TestDisabledHandlers(t *testing.T) {
{s.URL + "/country", "404 page not found", 404},
{s.URL + "/country-iso", "404 page not found", 404},
{s.URL + "/city", "404 page not found", 404},
{s.URL + "/json", "{\n \"UsingGeoIP\": true,\n \"UsingIPStack\": false,\n \"ip\": \"127.0.0.1\",\n \"ip_decimal\": 2130706433\n}", 200},
{s.URL + "/json", "{\n \"UsingGeoIP\": true,\n \"UsingIPStack\": false,\n \"IPStackSecurityEnabled\": false,\n \"ip\": \"127.0.0.1\",\n \"ip_decimal\": 2130706433\n}", 200},
}

for _, tt := range tests {
Expand All @@ -189,7 +189,7 @@ func TestJSONHandlers(t *testing.T) {
out string
status int
}{
{s.URL, "{\n \"UsingGeoIP\": true,\n \"UsingIPStack\": false,\n \"ip\": \"127.0.0.1\",\n \"ip_decimal\": 2130706433,\n \"country\": \"Elbonia\",\n \"country_iso\": \"EB\",\n \"country_eu\": false,\n \"region_name\": \"North Elbonia\",\n \"region_code\": \"1234\",\n \"metro_code\": 1234,\n \"zip_code\": \"1234\",\n \"city\": \"Bornyasherk\",\n \"latitude\": 63.416667,\n \"longitude\": 10.416667,\n \"time_zone\": \"Europe/Bornyasherk\",\n \"asn\": \"AS59795\",\n \"asn_org\": \"Hosting4Real\",\n \"hostname\": \"localhost\",\n \"user_agent\": {\n \"product\": \"curl\",\n \"version\": \"7.2.6.0\",\n \"raw_value\": \"curl/7.2.6.0\"\n }\n}", 200},
{s.URL, "{\n \"UsingGeoIP\": true,\n \"UsingIPStack\": false,\n \"IPStackSecurityEnabled\": false,\n \"ip\": \"127.0.0.1\",\n \"ip_decimal\": 2130706433,\n \"country\": \"Elbonia\",\n \"country_iso\": \"EB\",\n \"country_eu\": false,\n \"region_name\": \"North Elbonia\",\n \"region_code\": \"1234\",\n \"metro_code\": 1234,\n \"zip_code\": \"1234\",\n \"city\": \"Bornyasherk\",\n \"latitude\": 63.416667,\n \"longitude\": 10.416667,\n \"time_zone\": \"Europe/Bornyasherk\",\n \"asn\": \"AS59795\",\n \"asn_org\": \"Hosting4Real\",\n \"hostname\": \"localhost\",\n \"user_agent\": {\n \"product\": \"curl\",\n \"version\": \"7.2.6.0\",\n \"raw_value\": \"curl/7.2.6.0\"\n }\n}", 200},
{s.URL + "/port/foo", "{\n \"status\": 400,\n \"error\": \"invalid port: foo\"\n}", 400},
{s.URL + "/port/0", "{\n \"status\": 400,\n \"error\": \"invalid port: 0\"\n}", 400},
{s.URL + "/port/65537", "{\n \"status\": 400,\n \"error\": \"invalid port: 65537\"\n}", 400},
Expand Down
37 changes: 19 additions & 18 deletions iputil/geo/geo.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,24 +81,25 @@ func (g *geoip) Parse(ip net.IP, hostname string) (parser.Response, error) {
autonomousSystemNumber = fmt.Sprintf("AS%d", asn.AutonomousSystemNumber)
}
return parser.Response{
UsingGeoIP: true,
UsingIPStack: false,
IP: ip,
IPDecimal: ipDecimal,
Country: country.Name,
CountryISO: country.ISO,
CountryEU: country.IsEU,
RegionName: city.RegionName,
RegionCode: city.RegionCode,
MetroCode: city.MetroCode,
PostalCode: city.PostalCode,
City: city.Name,
Latitude: city.Latitude,
Longitude: city.Longitude,
Timezone: city.Timezone,
ASN: autonomousSystemNumber,
ASNOrg: asn.AutonomousSystemOrganization,
Hostname: hostname,
UsingGeoIP: true,
UsingIPStack: false,
IPStackSecurityEnabled: false,
IP: ip,
IPDecimal: ipDecimal,
Country: country.Name,
CountryISO: country.ISO,
CountryEU: country.IsEU,
RegionName: city.RegionName,
RegionCode: city.RegionCode,
MetroCode: city.MetroCode,
PostalCode: city.PostalCode,
City: city.Name,
Latitude: city.Latitude,
Longitude: city.Longitude,
Timezone: city.Timezone,
ASN: autonomousSystemNumber,
ASNOrg: asn.AutonomousSystemOrganization,
Hostname: hostname,
}, nil
}

Expand Down
16 changes: 16 additions & 0 deletions iputil/ipstack/ipstack.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ipstack
import (
"fmt"
"net"
"reflect"

"github.com/mpolden/echoip/iputil"
parser "github.com/mpolden/echoip/iputil/paser"
Expand Down Expand Up @@ -41,6 +42,21 @@ func (ips *IPStack) Parse(ip net.IP, hostname string) (parser.Response, error) {

if res.Timezone != nil {
parserResponse.Timezone = res.Timezone.ID
parserResponse.IsDayLightSavings = res.Timezone.IsDaylightSaving
}

if res.Security != nil {
parserResponse.IPStackSecurityEnabled = true
parserResponse.IsProxy = res.Security.IsProxy
parserResponse.IsCrawler = res.Security.IsCrawler
parserResponse.CrawlerName = res.Security.CrawlerName
parserResponse.CrawlerType = res.Security.CrawlerType
parserResponse.IsTor = res.Security.IsTOR
parserResponse.ThreatLevel = res.Security.ThreatLevel

if !reflect.ValueOf(&res.Security.ThreatTypes).IsNil() {
parserResponse.ThreatTypes = &res.Security.ThreatTypes
}
}

if res.Location != nil {
Expand Down
48 changes: 29 additions & 19 deletions iputil/paser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,33 @@ type Parser interface {
}

type Response struct {
UsingGeoIP bool `json:"UsingGeoIP"`
UsingIPStack bool `json:"UsingIPStack"`
IP net.IP `json:"ip"`
IPDecimal *big.Int `json:"ip_decimal"`
Country string `json:"country,omitempty"`
CountryISO string `json:"country_iso,omitempty"`
CountryEU *bool `json:"country_eu,omitempty"`
RegionName string `json:"region_name,omitempty"`
RegionCode string `json:"region_code,omitempty"`
MetroCode uint `json:"metro_code,omitempty"`
PostalCode string `json:"zip_code,omitempty"`
City string `json:"city,omitempty"`
Latitude float64 `json:"latitude,omitempty"`
Longitude float64 `json:"longitude,omitempty"`
Timezone string `json:"time_zone,omitempty"`
ASN string `json:"asn,omitempty"`
ASNOrg string `json:"asn_org,omitempty"`
Hostname string `json:"hostname,omitempty"`
UserAgent *useragent.UserAgent `json:"user_agent,omitempty"`
UsingGeoIP bool `json:"UsingGeoIP"`
UsingIPStack bool `json:"UsingIPStack"`
IPStackSecurityEnabled bool `json:"IPStackSecurityEnabled"`
IP net.IP `json:"ip"`
IPDecimal *big.Int `json:"ip_decimal"`
Country string `json:"country,omitempty"`
CountryISO string `json:"country_iso,omitempty"`
CountryEU *bool `json:"country_eu,omitempty"`
RegionName string `json:"region_name,omitempty"`
RegionCode string `json:"region_code,omitempty"`
MetroCode uint `json:"metro_code,omitempty"`
PostalCode string `json:"zip_code,omitempty"`
City string `json:"city,omitempty"`
Latitude float64 `json:"latitude,omitempty"`
Longitude float64 `json:"longitude,omitempty"`
Timezone string `json:"time_zone,omitempty"`
IsDayLightSavings bool `json:"is_daylight_savings,omitempty"`
ASN string `json:"asn,omitempty"`
ASNOrg string `json:"asn_org,omitempty"`
Hostname string `json:"hostname,omitempty"`
UserAgent *useragent.UserAgent `json:"user_agent,omitempty"`
CurrencyCode string `json:"currency_code,omitempty"`
IsProxy bool `json:"is_proxy,omitempty"`
IsCrawler bool `json:"is_crawler,omitempty"`
CrawlerName string `json:"crawler_name,omitempty"`
CrawlerType string `json:"crawler_type,omitempty"`
IsTor bool `json:"is_tor,omitempty"`
ThreatLevel string `json:"threat_level,omitempty"`
ThreatTypes *interface{} `json:"threat_types,omitempty"`
}
Loading