cluster code inside on cookie lock to prevent flailing at startup; add saving and loading of blocklist
This commit is contained in:
parent
1857b4da76
commit
a1cac321ac
75
main.go
75
main.go
|
@ -1,11 +1,13 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.openprivacy.ca/openprivacy/log"
|
"git.openprivacy.ca/openprivacy/log"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -14,6 +16,7 @@ import (
|
||||||
|
|
||||||
const MaxLength = 8192
|
const MaxLength = 8192
|
||||||
const SameCookieTimeLimitMins = 10
|
const SameCookieTimeLimitMins = 10
|
||||||
|
const blocklistFile = "blocklist.json"
|
||||||
|
|
||||||
type Ip2LastSeen map[string]time.Time
|
type Ip2LastSeen map[string]time.Time
|
||||||
|
|
||||||
|
@ -45,11 +48,41 @@ func main() {
|
||||||
cookiesToIps = map[string]Ip2LastSeen{}
|
cookiesToIps = map[string]Ip2LastSeen{}
|
||||||
blocklistedIps = map[string]bool{}
|
blocklistedIps = map[string]bool{}
|
||||||
|
|
||||||
|
load()
|
||||||
|
|
||||||
counter = NewCounter()
|
counter = NewCounter()
|
||||||
go logger()
|
go logger()
|
||||||
|
go save()
|
||||||
listen(*listenPort, *proxyPort)
|
listen(*listenPort, *proxyPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func load() {
|
||||||
|
_, err := os.Stat(blocklistFile)
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
bytes, err := ioutil.ReadFile(blocklistFile)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
json.Unmarshal(bytes, blocklistedIps)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func save() {
|
||||||
|
for {
|
||||||
|
time.Sleep(1*time.Minute)
|
||||||
|
blocklistLock.Lock()
|
||||||
|
bytes, err := json.Marshal(blocklistedIps)
|
||||||
|
blocklistLock.Unlock()
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Could not marshal blockedIPlist: %v\n", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ioutil.WriteFile(blocklistFile, bytes, 0600)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func logger() {
|
func logger() {
|
||||||
for {
|
for {
|
||||||
time.Sleep(5*time.Second)
|
time.Sleep(5*time.Second)
|
||||||
|
@ -87,7 +120,6 @@ func filter(res http.ResponseWriter, req *http.Request, listenPort, proxyPort in
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//log.Debugf("%v: Request %v %v\n", ip, req.Host, req.URL)
|
|
||||||
cookieObj, err := req.Cookie("i_like_gogits")
|
cookieObj, err := req.Cookie("i_like_gogits")
|
||||||
log.Debugf("ip: %v cookie: %v\n", ip, cookieObj)
|
log.Debugf("ip: %v cookie: %v\n", ip, cookieObj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -97,36 +129,37 @@ func filter(res http.ResponseWriter, req *http.Request, listenPort, proxyPort in
|
||||||
|
|
||||||
cookie := cookieObj.Value
|
cookie := cookieObj.Value
|
||||||
|
|
||||||
cookiesLock.Lock()
|
var mostRecent string = ""
|
||||||
ips, ok := cookiesToIps[cookie]
|
var ipList = []string{}
|
||||||
cookiesLock.Unlock()
|
cookiesLock.Lock() /**** Inside cookies Lock *****/
|
||||||
|
|
||||||
if !ok {
|
ipsForCookie, foundIpsForCookie := cookiesToIps[cookie]
|
||||||
|
if !foundIpsForCookie {
|
||||||
ips := Ip2LastSeen{ip: time.Now()}
|
ips := Ip2LastSeen{ip: time.Now()}
|
||||||
cookiesLock.Lock()
|
|
||||||
cookiesToIps[cookie] = ips
|
cookiesToIps[cookie] = ips
|
||||||
cookiesLock.Unlock()
|
} else {
|
||||||
|
for ip, lastSeen := range ipsForCookie {
|
||||||
|
ipList = append(ipList, ip)
|
||||||
|
if mostRecent == "" || lastSeen.After(ipsForCookie[mostRecent]) {
|
||||||
|
mostRecent = ip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ipsForCookie[ip] = time.Now()
|
||||||
|
cookiesToIps[cookie] = ipsForCookie
|
||||||
|
}
|
||||||
|
cookiesLock.Unlock() /***** End Cookies Lock *****/
|
||||||
|
|
||||||
|
if !foundIpsForCookie {
|
||||||
pass(res, req, listenPort, proxyPort)
|
pass(res, req, listenPort, proxyPort)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var mostRecent string = ""
|
|
||||||
cookiesLock.Lock()
|
|
||||||
for ip, lastSeen := range ips {
|
|
||||||
if mostRecent == "" || lastSeen.After(ips[mostRecent]) {
|
|
||||||
mostRecent = ip
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ips[ip] = time.Now()
|
|
||||||
cookiesToIps[cookie] = ips
|
|
||||||
cookiesLock.Unlock()
|
|
||||||
|
|
||||||
if mostRecent == "" || mostRecent == ip {
|
if mostRecent == "" || mostRecent == ip {
|
||||||
pass(res, req, listenPort, proxyPort)
|
pass(res, req, listenPort, proxyPort)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
timeDiff := time.Now().Sub(ips[mostRecent])
|
timeDiff := time.Now().Sub(ipsForCookie[mostRecent])
|
||||||
if timeDiff.Minutes() > SameCookieTimeLimitMins {
|
if timeDiff.Minutes() > SameCookieTimeLimitMins {
|
||||||
pass(res, req, listenPort, proxyPort)
|
pass(res, req, listenPort, proxyPort)
|
||||||
return
|
return
|
||||||
|
@ -134,7 +167,9 @@ func filter(res http.ResponseWriter, req *http.Request, listenPort, proxyPort in
|
||||||
|
|
||||||
log.Infof("different IP in the last %v minutes, 404ing\n", SameCookieTimeLimitMins)
|
log.Infof("different IP in the last %v minutes, 404ing\n", SameCookieTimeLimitMins)
|
||||||
blocklistLock.Lock()
|
blocklistLock.Lock()
|
||||||
blocklistedIps[ip] = true
|
for _, ip := range ipList {
|
||||||
|
blocklistedIps[ip] = true
|
||||||
|
}
|
||||||
blocklistLock.Unlock()
|
blocklistLock.Unlock()
|
||||||
res.WriteHeader(http.StatusNotFound)
|
res.WriteHeader(http.StatusNotFound)
|
||||||
fmt.Fprint(res, "404 - suspected botnet")
|
fmt.Fprint(res, "404 - suspected botnet")
|
||||||
|
|
Loading…
Reference in New Issue