Skip to content

Commit

Permalink
Add check to see if an IP belongs to AWS (close #40)
Browse files Browse the repository at this point in the history
  • Loading branch information
jreisinger committed May 16, 2023
1 parent 8b4c053 commit 83ff88e
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 1 deletion.
2 changes: 2 additions & 0 deletions check/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ var All = []checkip.Check{
Firehol,
IPSum,
IPtoASN,
IsOnAWS,
MaxMind,
OTX,
PhishStats,
Expand All @@ -38,6 +39,7 @@ var Default = []checkip.Check{
Firehol,
IPSum,
IPtoASN,
IsOnAWS,
OTX,
Ping,
Shodan,
Expand Down
2 changes: 1 addition & 1 deletion check/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
)

// defaultHttpClient is reused by checks that make HTTP requests.
var defaultHttpClient = newHttpClient(&http.Client{Timeout: 5 * time.Second})
var defaultHttpClient = newHttpClient(&http.Client{Timeout: 10 * time.Second})

type httpClient struct {
client *http.Client
Expand Down
70 changes: 70 additions & 0 deletions check/isonaws.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package check

import (
"encoding/json"
"fmt"
"net"

"github.com/jreisinger/checkip"
)

type awsIpRanges struct {
IsOn bool
Info struct {
IpPrefix string `json:"ip_prefix"`
Region string `json:"region"`
Services []string `json:"services"`
NetworkBorderGroup string `json:"network_border_group"`
}
}

// Json implements checkip.Info
func (a awsIpRanges) Json() ([]byte, error) {
return json.Marshal(&a)
}

// Summary implements checkip.Info
func (a awsIpRanges) Summary() string {
if a.IsOn {
return fmt.Sprintf("%t, prefix: %s, region: %s, sevices: %v",
a.IsOn, a.Info.IpPrefix, a.Info.Region, a.Info.Services)
}
return fmt.Sprintf("%t", a.IsOn)
}

// IsOnAWS checks if ipaddr belongs to AWS. If so it provides info about the IP
// address. It gets the info from https://ip-ranges.amazonaws.com/ip-ranges.json
func IsOnAWS(ipaddr net.IP) (checkip.Result, error) {
result := checkip.Result{
Name: "is on AWS",
}
resp := struct {
Prefixes []struct {
IpPrefix string `json:"ip_prefix"`
Region string `json:"region"`
Service string `json:"service"`
NetworkBorderGroup string `json:"network_border_group"`
} `json:"prefixes"`
}{}
apiUrl := "https://ip-ranges.amazonaws.com/ip-ranges.json"
if err := defaultHttpClient.GetJson(apiUrl, map[string]string{}, map[string]string{}, &resp); err != nil {
return result, newCheckError(err)
}
var a awsIpRanges
for _, prefix := range resp.Prefixes {
_, network, err := net.ParseCIDR(prefix.IpPrefix)
if err != nil {
return result, fmt.Errorf("parse CIDR %q: %v", prefix.IpPrefix, err)
}
if network.Contains(ipaddr) {
a.IsOn = true
a.Info.IpPrefix = prefix.IpPrefix
a.Info.NetworkBorderGroup = prefix.NetworkBorderGroup
a.Info.Region = prefix.Region
a.Info.Services = append(a.Info.Services, prefix.Service)
}

}
result.Info = a
return result, nil
}
35 changes: 35 additions & 0 deletions check/isonaws_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package check_test

import (
"net"
"testing"

"github.com/jreisinger/checkip/check"
)

func TestIsOnAWS(t *testing.T) {
tests := []struct {
ipAddr string
summary string
}{
{
ipAddr: "54.74.0.27",
summary: "true, prefix: 54.74.0.0/15, region: eu-west-1, sevices: [AMAZON EC2]",
},
{
ipAddr: "1.1.1.1",
summary: "false",
},
}

for i, test := range tests {
ipaddr := net.ParseIP(test.ipAddr)
r, err := check.IsOnAWS(ipaddr)
if err != nil {
t.Fatalf("check.IsOnAWS(%s) failed: %v", ipaddr, err)
}
if r.Info.Summary() != test.summary {
t.Errorf("test %d\ngot\t%q\nwant\t%q", i, r.Info.Summary(), test.summary)
}
}
}

0 comments on commit 83ff88e

Please sign in to comment.