Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
Jozef Reisinger committed Nov 11, 2021
1 parent 1dbe592 commit 4db3ca8
Show file tree
Hide file tree
Showing 20 changed files with 243 additions and 240 deletions.
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
test:
go test -cover ./...

install: test
install:
go install

run: install
checkip 91.228.166.47
checkip 209.141.33.65
checkip 218.92.0.158
checkip -j 91.228.166.47 | jq -r '.[] | select(.Type=="Sec" or .Type=="InfoSec") | "\(.IPaddrMalicious)\t\(.Name)"' | sort
checkip -j 209.141.33.65 | jq -r '.[] | select(.Type=="Sec" or .Type=="InfoSec") | "\(.IPaddrMalicious)\t\(.Name)"' | sort
checkip -j 218.92.0.158 | jq -r '.[] | select(.Type=="Sec" or .Type=="InfoSec") | "\(.IPaddrMalicious)\t\(.Name)"' | sort
56 changes: 41 additions & 15 deletions check/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,57 @@ package check

import (
"net"
"sync"
)

type Type string

const (
TypeInfo Type = "Info" // provides some useful information about the IP address
TypeSec Type = "Sec" // says whether the IP address is considered malicious
TypeInfoSec Type = "InfoSec"
)

type Type string
type Check func(ipaddr net.IP) (Result, error)

type Result struct {
Name string
Type Type
IPaddrMalicious bool
Info Info
// Error *ResultError
// Error error
// ErrorRedacted string
}

type Info interface {
String() string
JsonString() (string, error)
}

type Check func(ipaddr net.IP) Result
type EmptyInfo struct {
}

func (EmptyInfo) String() string {
return Na("")
}

// Run runs checkers concurrently checking the ipaddr.
func Run(checks []Check, ipaddr net.IP) Results {
var res []Result
func (EmptyInfo) JsonString() (string, error) {
return "{}", nil
}

func Na(s string) string {
if s == "" {
return "n/a"
}
return s
}

var wg sync.WaitGroup
for _, chk := range checks {
wg.Add(1)
go func(c Check) {
defer wg.Done()
res = append(res, c(ipaddr))
}(chk)
func NonEmpty(strings ...string) []string {
var ss []string
for _, s := range strings {
if s != "" {
ss = append(ss, s)
}
}
wg.Wait()
return res
return ss
}
34 changes: 0 additions & 34 deletions check/data.go

This file was deleted.

13 changes: 7 additions & 6 deletions check/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@ package check

import "regexp"

type ResultError struct {
err error
type Error struct {
err error
ErrString string `json:"error"`
}

func NewResultError(err error) *ResultError {
return &ResultError{err: err}
func NewError(err error) *Error {
return &Error{err: err, ErrString: redactSecrets(err.Error())}
}

func (e *ResultError) Error() string {
return redactSecrets(e.err.Error())
func (e *Error) Error() string {
return e.ErrString
}

func redactSecrets(s string) string {
Expand Down
2 changes: 1 addition & 1 deletion check/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func (c HttpClient) GetJson(apiUrl string, headers map[string]string, queryParam
}
if response != nil {
if err := json.Unmarshal(b, response); err != nil {
return err
return fmt.Errorf("unmarshalling JSON from %s: %v", apiUrl, err)
}
}
return nil
Expand Down
76 changes: 0 additions & 76 deletions check/result.go

This file was deleted.

14 changes: 7 additions & 7 deletions checker/abuseipdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
// Only return reports within the last x amount of days. Default is 30.
const abuseIPDBMaxAgeInDays = "90"

// AbuseIPDB holds information from abuseipdb.com.
type AbuseIPDB struct {
IsWhitelisted bool `json:"isWhitelisted"`
AbuseConfidenceScore int `json:"abuseConfidenceScore"`
Expand All @@ -35,12 +36,10 @@ func (d AbuseIPDB) JsonString() (string, error) {
return string(b), err
}

// CheckAbuseIPDB fills in AbuseIPDB data for a given IP address. It gets the data from
// api.abuseipdb.com/api/v2/check (docs.abuseipdb.com/#check-endpoint).
func CheckAbuseIPDB(ipaddr net.IP) check.Result {
func CheckAbuseIPDB(ipaddr net.IP) (check.Result, error) {
apiKey, err := check.GetConfigValue("ABUSEIPDB_API_KEY")
if err != nil {
return check.Result{Error: check.NewResultError(err)}
return check.Result{}, check.NewError(err)
}

headers := map[string]string{
Expand All @@ -57,14 +56,15 @@ func CheckAbuseIPDB(ipaddr net.IP) check.Result {
var data struct {
AbuseIPDB AbuseIPDB `json:"data"`
}
// docs.abuseipdb.com/#check-endpoint
if err := check.DefaultHttpClient.GetJson("https://api.abuseipdb.com/api/v2/check", headers, queryParams, &data); err != nil {
return check.Result{Error: check.NewResultError(err)}
return check.Result{}, check.NewError(err)
}

return check.Result{
Name: "abuseipdb.com",
Type: check.TypeInfoSec,
Data: data.AbuseIPDB,
Info: data.AbuseIPDB,
IPaddrMalicious: data.AbuseIPDB.TotalReports > 0 && !data.AbuseIPDB.IsWhitelisted && data.AbuseIPDB.AbuseConfidenceScore > 25,
}
}, nil
}
10 changes: 5 additions & 5 deletions checker/as.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,24 +34,24 @@ func (a AS) JsonString() (string, error) {
// CheckAs fills in AS data for a given IP address. The data is taken from a TSV
// file ip2asn-combined downloaded from iptoasn.com. The file is created or
// updated as needed.
func CheckAs(ipaddr net.IP) check.Result {
func CheckAs(ipaddr net.IP) (check.Result, error) {
file := "/var/tmp/ip2asn-combined.tsv"
url := "https://iptoasn.com/data/ip2asn-combined.tsv.gz"

if err := check.UpdateFile(file, url, "gz"); err != nil {
return check.Result{Error: check.NewResultError(err)}
return check.Result{}, check.NewError(err)
}

as, err := asSearch(ipaddr, file)
if err != nil {
return check.Result{Error: check.NewResultError(fmt.Errorf("searching %s in %s: %v", ipaddr, file, err))}
return check.Result{}, check.NewError(fmt.Errorf("searching %s in %s: %v", ipaddr, file, err))
}

return check.Result{
Name: "iptoasn.com",
Type: check.TypeInfo,
Data: as,
}
Info: as,
}, nil
}

// search the ippadrr in tsvFile and if found fills in AS data.
Expand Down
15 changes: 7 additions & 8 deletions checker/blocklist.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,31 @@ import (
"github.com/jreisinger/checkip/check"
)

// CheckBlockList fills in BlockList data for a given IP address. It gets the data from
// http://api.blocklist.de
func CheckBlockList(ipddr net.IP) check.Result {
// CheckBlockList searches the ipaddr in http://api.blocklist.de.
func CheckBlockList(ipddr net.IP) (check.Result, error) {
url := fmt.Sprintf("http://api.blocklist.de/api.php?ip=%s&start=1", ipddr)

resp, err := check.DefaultHttpClient.Get(url, map[string]string{}, map[string]string{})
if err != nil {
return check.Result{Error: check.NewResultError(err)}
return check.Result{}, check.NewError(err)
}

number := regexp.MustCompile(`\d+`)
numbers := number.FindAll(resp, 2)

attacks, err := strconv.Atoi(string(numbers[0]))
if err != nil {
return check.Result{Error: check.NewResultError(err)}
return check.Result{}, check.NewError(err)
}
reports, err := strconv.Atoi(string(numbers[1]))
if err != nil {
return check.Result{Error: check.NewResultError(err)}
return check.Result{}, check.NewError(err)
}

return check.Result{
Name: "blocklist.de",
Type: check.TypeSec,
Data: check.EmptyData{},
Info: check.EmptyInfo{},
IPaddrMalicious: attacks > 0 && reports > 0,
}
}, nil
}
2 changes: 1 addition & 1 deletion checker/checkers.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package checker
import "github.com/jreisinger/checkip/check"

var DefaultCheckers = []check.Check{
CheckAs,
CheckAbuseIPDB,
CheckAs,
CheckBlockList,
CheckCins,
CheckDNS,
Expand Down
11 changes: 5 additions & 6 deletions checker/cins.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,26 +17,25 @@ type CINSArmy struct {
CountIPs int
}

// CheckCins fills in the CINSArmy data.
func CheckCins(ipaddr net.IP) check.Result {
func CheckCins(ipaddr net.IP) (check.Result, error) {
file := "/var/tmp/cins.txt"
url := "http://cinsscore.com/list/ci-badguys.txt"

if err := check.UpdateFile(file, url, ""); err != nil {
return check.Result{Error: check.NewResultError(err)}
return check.Result{}, check.NewError(err)
}

cins, err := cinsSearch(ipaddr, file)
if err != nil {
return check.Result{Error: check.NewResultError(fmt.Errorf("searching %s in %s: %v", ipaddr, file, err))}
return check.Result{}, check.NewError(fmt.Errorf("searching %s in %s: %v", ipaddr, file, err))
}

return check.Result{
Name: "cinsscore.com",
Type: check.TypeSec,
Data: check.EmptyData{},
Info: check.EmptyInfo{},
IPaddrMalicious: cins.BadGuyIP,
}
}, nil
}

// search searches the ippadrr in filename fills in ET data.
Expand Down
Loading

0 comments on commit 4db3ca8

Please sign in to comment.