Tool to parse journalctl output, find failed ssh login attempts and log them in a CSV file
sudo journalctl -f | go run authtracker.go
package main | |
import ( | |
"bufio" | |
"encoding/csv" | |
"encoding/json" | |
"fmt" | |
"io" | |
"io/ioutil" | |
"net/http" | |
"os" | |
"regexp" | |
"time" | |
) | |
var logFilePath = "log.csv" | |
type IPLookup struct { | |
CountryCode string `json:"country"` | |
Country string `json:"country_name"` | |
City string `json:"city"` | |
Latitude float32 `json:"latitude"` | |
Longitude float32 `json:"longitude"` | |
} | |
func main() { | |
if len(os.Args) > 1 { | |
logFilePath = os.Args[1] | |
} | |
calm := 10 | |
startTime := time.Now() | |
count := 0 | |
rx := regexp.MustCompile(`(\w+\s\d+\s\d+:\d+:\d+)\s.*?Failed\spassword\sfor\s(?:invalid\suser\s)?(.+?)\sfrom\s(.+)\sport\s(\d+)`) | |
reader := bufio.NewReader(os.Stdin) | |
for { | |
text, err := reader.ReadString('\n') | |
if err == io.EOF { | |
break | |
} | |
if err != nil { | |
panic(err) | |
} | |
matches := rx.FindStringSubmatch(text) | |
if len(matches) > 0 { | |
matches = matches[1:] | |
response, err := http.Get(fmt.Sprintf("https://ipapi.co/%s/json/", matches[2])) | |
if err == nil { | |
data, err := ioutil.ReadAll(response.Body) | |
response.Body.Close() | |
if err != nil { | |
panic(err) | |
} | |
var lookup IPLookup | |
err = json.Unmarshal(data, &lookup) | |
if err != nil { | |
panic(err) | |
} | |
matches = append(matches, fmt.Sprint(lookup.Longitude), fmt.Sprint(lookup.Latitude), lookup.Country, lookup.City) | |
} else { | |
fmt.Println(err) | |
matches = append(matches, "-", "-", "-", "-") | |
} | |
if err := appendToFile(matches); err != nil { | |
calm-- | |
if calm <= 0 { | |
panic(err) | |
} else { | |
fmt.Println(err) | |
} | |
} else { | |
calm = 10 | |
} | |
count++ | |
fmt.Println(count, "attempts since", startTime) | |
} else { | |
//fmt.Println(text) | |
} | |
} | |
fmt.Println("exiting...") | |
} | |
func appendToFile(line []string) error { | |
logFile, err := os.OpenFile(logFilePath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644) | |
if err != nil { | |
return err | |
} | |
csvWriter := csv.NewWriter(logFile) | |
err = csvWriter.Write(line) | |
if err != nil { | |
return err | |
} | |
csvWriter.Flush() | |
return logFile.Close() | |
} |