From 405d61e729a91a1e55fe0f6490ae376d1e115378 Mon Sep 17 00:00:00 2001 From: Sean DuBois Date: Mon, 16 Jun 2014 03:38:10 +0000 Subject: [PATCH] Move fail2ban socket communication into its own project called fail2go --- README.md | 5 +---- basic.go | 50 ----------------------------------------- fail2banClient.go | 39 -------------------------------- main.go => fail2rest.go | 4 ++-- global.go | 34 ++++++++++++++++++++++++++++ jail.go | 27 ++++++++++++++++++++++ jailControl.go | 43 ----------------------------------- 7 files changed, 64 insertions(+), 138 deletions(-) delete mode 100644 basic.go delete mode 100644 fail2banClient.go rename main.go => fail2rest.go (83%) create mode 100644 global.go create mode 100644 jail.go delete mode 100644 jailControl.go diff --git a/README.md b/README.md index ef9dda1..22abe66 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ##Overview -fail2rest is a small REST server that aims to replicate the failban-client UI +fail2rest is a small REST server that aims to allow full administration of a fail2ban server via HTTP fail2rest will eventually be used as a backend to a small web app to make fail2ban administration and reporting easier. @@ -13,12 +13,9 @@ Every PR will be merged! Feel free to open up PRs that aren't fully done, I will my best to finish them for you. I will make sure to review everything I can. If you are interested in working on fail2rest, but don't know where to start here are some ideas. -* Find unimplemented fail2ban-client commands -* Improve data assertions before json.marshall (this is really important!) * Document current API calls (and examples with cURL), small static website for this info * Start on fail2web, I would like to write this in angular, angular-ui, browserify and d3.js (Open to suggestions just most comfortable with this) * Write tests, and implement some post-commit system for running tests -* Expand fail2ban-server so that we can perform more operations via socket. I would like to avoid editing files as long as possible ##License iThe MIT License (MIT) diff --git a/basic.go b/basic.go deleted file mode 100644 index 8327103..0000000 --- a/basic.go +++ /dev/null @@ -1,50 +0,0 @@ -package main - -import ( - "encoding/json" - "github.com/gorilla/mux" - "net/http" - "strings" -) - -func BasicStatusHandler(res http.ResponseWriter, req *http.Request) { - fail2banInput := make([]string, 1) - fail2banInput[0] = "status" - - output, err := fail2banRequest(fail2banInput) - if err != nil { - } - - //TODO use reflection to assert data structures and give proper errors - jails := output.([]interface{})[1].([]interface{})[1].([]interface{})[1] - jails = strings.Split(jails.(string), ",") - - encodedOutput, err := json.Marshal(jails) - if err != nil { - } - - res.Write(encodedOutput) -} - -func BasicPingHandler(res http.ResponseWriter, req *http.Request) { - fail2banInput := make([]string, 1) - fail2banInput[0] = "ping" - - output, err := fail2banRequest(fail2banInput) - if err != nil { - } - - //TODO use reflection to assert data structures and give proper errors - output = output.([]interface{})[1] - - encodedOutput, err := json.Marshal(output) - if err != nil { - } - - res.Write(encodedOutput) -} - -func BasicHandler(basicRouter *mux.Router) { - basicRouter.HandleFunc("/status", BasicStatusHandler).Methods("GET") - basicRouter.HandleFunc("/ping", BasicPingHandler).Methods("GET") -} diff --git a/fail2banClient.go b/fail2banClient.go deleted file mode 100644 index 6a42a84..0000000 --- a/fail2banClient.go +++ /dev/null @@ -1,39 +0,0 @@ -package main - -import ( - "bytes" - "errors" - "github.com/kisielk/og-rek" - "net" -) - -func fail2banRequest(input []string) (interface{}, error) { - c, err := net.Dial("unix", "/var/run/fail2ban/fail2ban.sock") - - if err != nil { - return nil, errors.New("Failed to contact fail2ban socket") - } - - p := &bytes.Buffer{} - ogórek.NewEncoder(p).Encode(input) - c.Write(p.Bytes()) - c.Write([]byte("")) - - buf := make([]byte, 0) - tmpBuf := make([]byte, 1) - for { - bufRead, _ := c.Read(tmpBuf) - - if bufRead != 0 { - buf = append(buf, tmpBuf...) - } else { - buf = buf[:len(buf)-17] - break - } - - } - - dec := ogórek.NewDecoder(bytes.NewBuffer(buf)) - v, err := dec.Decode() - return v, err -} diff --git a/main.go b/fail2rest.go similarity index 83% rename from main.go rename to fail2rest.go index 1f58677..4cf9f91 100644 --- a/main.go +++ b/fail2rest.go @@ -29,8 +29,8 @@ func main() { } r := mux.NewRouter() - BasicHandler(r.PathPrefix("/basic").Subrouter()) - JailControlHandler(r.PathPrefix("/jailControl").Subrouter()) + globalHandler(r.PathPrefix("/global").Subrouter()) + jailHandler(r.PathPrefix("/jail").Subrouter()) http.Handle("/", r) http.ListenAndServe(configuration.Addr, nil) } diff --git a/global.go b/global.go new file mode 100644 index 0000000..a3279d8 --- /dev/null +++ b/global.go @@ -0,0 +1,34 @@ +package main + +import ( + "encoding/json" + "github.com/Sean-Der/fail2go" + "github.com/gorilla/mux" + "net/http" +) + +func globalStatusHandler(res http.ResponseWriter, req *http.Request) { + globalStatus, _ := fail2go.GlobalStatus() + + encodedOutput, err := json.Marshal(globalStatus) + if err != nil { + } + + res.Write(encodedOutput) +} + +func globalPingHandler(res http.ResponseWriter, req *http.Request) { + globalPing, _ := fail2go.GlobalPing() + + encodedOutput, err := json.Marshal(globalPing) + if err != nil { + } + + res.Write(encodedOutput) + +} + +func globalHandler(globalRouter *mux.Router) { + globalRouter.HandleFunc("/status", globalStatusHandler).Methods("GET") + globalRouter.HandleFunc("/ping", globalPingHandler).Methods("GET") +} diff --git a/jail.go b/jail.go new file mode 100644 index 0000000..0392529 --- /dev/null +++ b/jail.go @@ -0,0 +1,27 @@ +package main + +import ( + "encoding/json" + "github.com/gorilla/mux" + "github.com/Sean-Der/fail2go" + "net/http" +) + +func jailGetHandler(res http.ResponseWriter, req *http.Request) { + jailStatus, _ := fail2go.JailStatus(mux.Vars(req)["jail"]) + + output := make(map[string]interface{}) + + for key, value := range jailStatus { + output[key] = value + } + encodedOutput, err := json.Marshal(output) + if err != nil { + } + + res.Write(encodedOutput) +} + +func jailHandler(jailRouter *mux.Router) { + jailRouter.HandleFunc("/{jail}", jailGetHandler).Methods("GET") +} diff --git a/jailControl.go b/jailControl.go deleted file mode 100644 index aca5708..0000000 --- a/jailControl.go +++ /dev/null @@ -1,43 +0,0 @@ -package main - -import ( - "encoding/json" - "github.com/gorilla/mux" - "net/http" -) - -func JailControlStatusHandler(res http.ResponseWriter, req *http.Request) { - fail2banInput := make([]string, 2) - fail2banInput[0] = "status" - fail2banInput[1] = mux.Vars(req)["jail"] - - fail2banOutput, err := fail2banRequest(fail2banInput) - if err != nil { - } - - //TODO use reflection to assert data structures and give proper errors - action := fail2banOutput.([]interface{})[1].([]interface{})[1].([]interface{})[1] - filter := fail2banOutput.([]interface{})[1].([]interface{})[0].([]interface{})[1] - - output := make(map[string]map[string]interface{}) - output["action"] = make(map[string]interface{}) - output["filter"] = make(map[string]interface{}) - - output["filter"]["currentlyFailed"] = filter.([]interface{})[0].([]interface{})[1] - output["filter"]["totalFailed"] = filter.([]interface{})[1].([]interface{})[1] - output["filter"]["fileList"] = filter.([]interface{})[2].([]interface{})[1] - - output["action"]["currentlyBanned"] = action.([]interface{})[0].([]interface{})[1] - output["action"]["totalBanned"] = action.([]interface{})[1].([]interface{})[1] - output["action"]["ipList"] = action.([]interface{})[2].([]interface{})[1] - - encodedOutput, err := json.Marshal(output) - if err != nil { - } - - res.Write(encodedOutput) -} - -func JailControlHandler(basicRouter *mux.Router) { - basicRouter.HandleFunc("/status/{jail}", JailControlStatusHandler).Methods("GET") -}