diff --git a/conf.go b/conf.go new file mode 100644 index 0000000..4293a31 --- /dev/null +++ b/conf.go @@ -0,0 +1,53 @@ +package main + +import ( + // "flag" + "log" + "os" + + "gopkg.in/yaml.v3" +) + +type Conf struct { + // Definitions []string + Streams []struct { + Cmd string + Filters []struct { + Regex []string + Retry uint + RetryPeriod string `yaml:"retry-period"` + Actions []struct { + Cmd string + After string `yaml:",omitempty"` + } + } + } +} + +func parseConf(filename string) *Conf { + + data, err := os.ReadFile(filename) + + if err != nil { + log.Fatalln("Failed to read configuration file:", err) + } + + var conf Conf + err = yaml.Unmarshal(data, &conf) + if err != nil { + log.Fatalln("Failed to parse configuration file:", err) + } + log.Println(conf) + + yaml, err := yaml.Marshal(conf) + if err != nil { + log.Fatalln("Failed to rewrite configuration file:", err) + } + log.Println(string(yaml)) + return &conf +} + +func parseArgs() map[string]string { + var args map[string]string + return args +} diff --git a/go.mod b/go.mod index 28068d0..7915659 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module reaction go 1.19 + +require gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..4bc0337 --- /dev/null +++ b/go.sum @@ -0,0 +1,3 @@ +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index 5451066..db19ee9 100644 --- a/main.go +++ b/main.go @@ -13,7 +13,7 @@ type Action struct { type compiledAction struct { regex []regexp.Regexp - cmd []string + cmd []string } type Stream struct { @@ -30,8 +30,8 @@ func compileAction(action Action) compiledAction { return ca } -/// Handle a log command -/// Must be started in a goroutine +// Handle a log command +// Must be started in a goroutine func streamHandle(stream Stream, execQueue chan []string) { log.Printf("streamHandle{%v}: start\n", stream.cmd) cmd := exec.Command(stream.cmd[0], stream.cmd[1:]...) @@ -78,19 +78,21 @@ func execQueue() chan []string { } func main() { - mockstreams := []Stream{Stream{ - []string{"tail", "-f", "/home/ao/DOWN"}, - []Action{Action{ - []string{"prout.dev"}, - []string{"touch", "/home/ao/DAMN"}, - }}, - }} - streams := mockstreams - log.Println(streams) - queue := execQueue() - for _, stream := range streams { - go streamHandle(stream, queue) - } - // Infinite wait - <-make(chan bool) + conf := parseConf("./reaction.yml") + conf = conf + // mockstreams := []Stream{Stream{ + // []string{"tail", "-f", "/home/ao/DOWN"}, + // []Action{Action{ + // []string{"prout.dev"}, + // []string{"touch", "/home/ao/DAMN"}, + // }}, + // }} + // streams := mockstreams + // log.Println(streams) + // queue := execQueue() + // for _, stream := range streams { + // go streamHandle(stream, queue) + // } + // // Infinite wait + // <-make(chan bool) } diff --git a/reaction.yml b/reaction.yml new file mode 100644 index 0000000..5cad19a --- /dev/null +++ b/reaction.yml @@ -0,0 +1,19 @@ +--- +definitions: + - &iptablesban iptables -I reaction 1 -s -j block + - &iptablesunban iptables -D reaction 1 -s -j block + +# regexes: +# ip: '(([0-9]{1,3}\.){3}[0-9]{1,3})|([0-9a-fA-F:]{2,90})' + +streams: + - cmd: journalctl -fu phpfpm-nextcloud.service + filters: + - regex: + - '"message":"Login failed: .\+ (Remote IP: )"' + retry: 3 + retry-period: 1h + actions: + - cmd: *iptablesban + - cmd: *iptablesunban + after: 1h