I have written simple fail2ban log file parcer in Golang that finds banned IPs, makes a struct with date, time and IP and a map with IP as a key and count as a value. I am thinking of nmapping the values I’ve got and making a report out of them.
package main
import (
"bufio"
"fmt"
"regexp"
"os"
)
type record struct {
day string
time string
ip string
}
type ip struct {
ip string
count int
}
// Checking most calls for errors.
// This helper will streamline our error checks below.
func check(e error) {
if e != nil {
panic(e)
}
}
//reading file to array of lines
func readLines(path string) ([]string, error) {
file, err := os.Open(path)
check(err)
defer file.Close()
var lines []string
scanner := bufio.NewScanner(file)
for scanner.Scan() {
lines = append(lines, scanner.Text())
}
return lines, scanner.Err()
}
func main() {
lines, err := readLines("./fail2ban.log")
var log_records []record
if err != nil {
fmt.Println("readLines: %s", err)
}
//date
dr, _ := regexp.Compile("[0-9]{4}-[0-9]{2}-[0-9]{2}")
//time
tr, _ := regexp.Compile("[0-9]{2}:[0-9]{2}\\:[0-9]{2},[0-9]{3}")
//IPv4 address
ir, _ := regexp.Compile("(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$")
//"Ban"
br, _ := regexp.Compile("Ban")
ip_map := make(map[string]int)
var j int
j = 0
for i, line := range lines {
if (br.MatchString(line) == true){
var tmp record
log_records = append (log_records, tmp)
log_records[j].day = dr.FindString(line)
log_records[j].time = tr.FindString(line)
log_records[j].ip = ir.FindString(line)
//count unique IPs
ip_map[log_records[j].ip]++
fmt.Println("Log line: ",i)
fmt.Println("Date: ",log_records[j].day)
fmt.Println("Time: ",log_records[j].time)
fmt.Println("IP address: ",log_records[j].ip)
fmt.Println("Count: ",ip_map[log_records[j].ip])
fmt.Println("")
j++
}
}
//pring map of IPs
fmt.Println(ip_map)
}
Leave a Reply