-
Notifications
You must be signed in to change notification settings - Fork 10
/
exception.go
111 lines (97 loc) · 2.29 KB
/
exception.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package iprepd
import (
"bufio"
"encoding/json"
"io/ioutil"
"net"
"net/http"
"os"
"strings"
"sync"
"time"
log "github.com/sirupsen/logrus"
"github.com/zmap/go-iptree/iptree"
)
var activeTree *iptree.IPTree
var treeLock sync.Mutex
var isExceptionUpdate = false
type awsIPRanges struct {
Prefixes []struct {
IPPrefix string `json:"ip_prefix"`
} `json:"prefixes"`
}
const awsIPRangeURL = "https://ip-ranges.amazonaws.com/ip-ranges.json"
func startExceptions() {
for {
loadExceptions()
// If this was the first exception load, send a note to the main thread
// to indicate the API can begin processing requests
if !isExceptionUpdate {
sruntime.exceptionsLoaded <- true
isExceptionUpdate = true
}
time.Sleep(time.Hour)
}
}
func loadExceptions() {
log.Info("starting exception refresh")
t := iptree.New()
for _, x := range sruntime.cfg.Exceptions.File {
log.Infof("loading file exceptions from %v", x)
fd, err := os.Open(x)
if err != nil {
log.Fatal(err.Error())
}
scn := bufio.NewScanner(fd)
for scn.Scan() {
_, n, err := net.ParseCIDR(scn.Text())
if err != nil {
log.Fatal(err.Error())
}
t.Add(n, 0)
}
if err = scn.Err(); err != nil {
log.Fatal(err.Error())
}
}
if sruntime.cfg.Exceptions.AWS {
log.Infof("loading AWS exceptions from %v", awsIPRangeURL)
resp, err := http.Get(awsIPRangeURL)
if err != nil {
log.Fatal(err.Error())
}
defer resp.Body.Close()
buf, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err.Error())
}
var awsp awsIPRanges
err = json.Unmarshal(buf, &awsp)
if err != nil {
log.Fatal(err.Error())
}
for _, v := range awsp.Prefixes {
_, n, err := net.ParseCIDR(v.IPPrefix)
if err != nil {
log.Fatal(err.Error())
}
t.Add(n, 0)
}
}
treeLock.Lock()
activeTree = t
treeLock.Unlock()
log.Info("completed exception refresh")
}
func isException(ipstr string) (bool, error) {
// XXX See if the input contains both a . and a : character (IPv4 mapped IPv6 address
// using dot notation). If so, don't run a check. These addresses are not currently
// supported in the exception code.
if strings.Contains(ipstr, ":") && strings.Contains(ipstr, ".") {
return false, nil
}
treeLock.Lock()
_, f, err := activeTree.GetByString(ipstr)
treeLock.Unlock()
return f, err
}