Skip to content

Instantly share code, notes, and snippets.

@ryupold
Last active November 24, 2019 15:58
Show Gist options
  • Save ryupold/eaedea845d4b54f10d68c9e97f48c65b to your computer and use it in GitHub Desktop.
Save ryupold/eaedea845d4b54f10d68c9e97f48c65b to your computer and use it in GitHub Desktop.
Tool to parse journalctl output, find failed ssh login attempts and log them in a CSV file

authtracker.go

Tool to parse journalctl output, find failed ssh login attempts and log them in a CSV file

usage

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()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment