cluster code inside on cookie lock to prevent flailing at startup; add saving and loading of blocklist

This commit is contained in:
Dan Ballard 2020-09-28 14:40:29 -07:00
parent 1857b4da76
commit a1cac321ac
1 changed files with 55 additions and 20 deletions

75
main.go
View File

@ -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")