Ban sshd fail login ip.

package util

import (
	"fmt"
	"github.com/stretchr/testify/assert"
	"io/ioutil"
	"os"
	"sort"
	"strings"
	"testing"
	"time"
)

func TestRead(t *testing.T) {
	path := "C:\\Users\\v_zhenlluo\\Downloads\\sshdLog"
	fileList, e := ioutil.ReadDir(path)
	if e != nil {
		fmt.Println("read dir error")
		return
	}
	ipAccessCountMap := make(map[string]int) // sshd访问失败 统计次数
	// 提取IP
	for _, fileInfo := range fileList {
		if !strings.HasPrefix(fileInfo.Name(), "secure") {
			continue
		}
		filePath := fmt.Sprintf("%s\\%s", path, fileInfo.Name())
		content, err := os.ReadFile(filePath)
		if err != nil {
			continue
		}
		splitStrItems := strings.Split(string(content), "\n")
		for _, item := range splitStrItems {
			sshdFailLoginLog := strings.ToLower(item)
			if !(strings.Contains(sshdFailLoginLog, "invalid") && strings.Contains(sshdFailLoginLog, "sshd")) {
				continue
			}
			sp1 := strings.Split(sshdFailLoginLog, "from")
			if len(sp1) < 2 {
				continue
			}
			sp2 := strings.Split(sp1[1], " ")
			if len(sp2) < 2 {
				continue
			}
			accessIP := sp2[1]
			sp3 := strings.Split(accessIP, ".")
			if len(sp3) < 4 {
				continue
			}
			ipAccessCountMap[accessIP]++
		}
	}
	// 排序
	var ipAccessList []IpAccessInfo
	for accessIP, count := range ipAccessCountMap {
		ipAccessList = append(ipAccessList, IpAccessInfo{Ip: accessIP, Count: count})
	}
	sort.Sort(IpAccess(ipAccessList))
	// 登陆失败10次 封禁
	banIpBlockMap := make(map[string]*HashSetString) // 最终封禁IP列表
	for _, info := range ipAccessList {
		if info.Count < 10 {
			continue
		}
		accessIP := info.Ip
		sp3 := strings.Split(accessIP, ".")
		if len(sp3) < 4 {
			continue
		}
		banIpBlock := fmt.Sprintf("%s.%s.0.0/24", sp3[0], sp3[1])
		if _, ok := banIpBlockMap[banIpBlock]; !ok {
			banIpBlockMap[banIpBlock] = NewHashSetString()
		}
		banIpBlockMap[banIpBlock].Add(accessIP)
	}
	// 初始化文件
	writeFilePath := fmt.Sprintf("%s\\ban_%s.txt", path, time.Now().Format("20060102150405"))
	f, err := os.OpenFile(writeFilePath, os.O_CREATE, 0777)
	defer f.Close()
	if err != nil {
		return
	}
	// 写入
	for banIp, _ := range banIpBlockMap {
		f.Write([]byte(banIp)) //data是自己定义的数据
		f.WriteString("\n")
	}
	assert.Equal(t, len(ipAccessCountMap), len(ipAccessCountMap))
}

object order:

type IpAccessInfo struct {
	Ip    string
	Count int
}

type IpAccess []IpAccessInfo

func (a IpAccess) Len() int           { return len(a) }
func (a IpAccess) Less(i, j int) bool { return a[i].Count > a[j].Count } // desc order
func (a IpAccess) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }

hashSetString Util:

// HashSetString 字符串hash结构
type HashSetString struct {
	dic  map[string]interface{} // 字典
	Data []string               // 数据
}

// NewHashSetString 初始化
func NewHashSetString() *HashSetString {
	return &HashSetString{
		dic:  make(map[string]interface{}, 0),
		Data: make([]string, 0),
	}
}

// NewHashSetStringWithData 初始化
func NewHashSetStringWithData(data []string) *HashSetString {
	set := &HashSetString{
		dic:  make(map[string]interface{}, 0),
		Data: make([]string, 0),
	}
	for i := range data {
		set.Add(data[i])
	}
	return set
}

// Add 新增元素
func (h *HashSetString) Add(ele string) bool {
	_, ok := h.dic[ele]
	if ok {
		return false
	}
	h.dic[ele] = ele
	h.Data = append(h.Data, ele)
	return true
}

// Contains 是否存在字符串
func (h *HashSetString) Contains(ele string) bool {
	_, ok := h.dic[ele]
	if ok {
		return true
	}
	return false
}

// Get 获取元素
func (h *HashSetString) Get(ele string) string {
	val, ok := h.dic[ele]
	if ok {
		return val.(string)
	}
	return ""
}

// GetList 获取所有字符串
func (h *HashSetString) GetList() []string {
	return h.Data
}

// HashSetInt 数字hash结构
type HashSetInt struct {
	dic  map[int]interface{}
	Data []int
}

// NewHashSetInt 初始化
func NewHashSetInt() *HashSetInt {
	return &HashSetInt{
		dic:  make(map[int]interface{}, 0),
		Data: make([]int, 0),
	}
}

// Add 新增元素
func (h *HashSetInt) Add(ele int) bool {
	_, ok := h.dic[ele]
	if ok {
		return false
	}
	h.dic[ele] = ele
	h.Data = append(h.Data, ele)
	return true
}

// Get 获取元素
func (h *HashSetInt) Get(ele int) int {
	val, ok := h.dic[ele]
	if ok {
		return val.(int)
	}
	return -1
}

// GetList 获取所有数字
func (h *HashSetInt) GetList() []int {
	return h.Data
}