fix: Fix some bugs in the alert (#10176)

This commit is contained in:
2025-08-28 15:58:10 +08:00 committed by GitHub
parent 97cdf7bc78
commit bc8d564ce8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 40 additions and 26 deletions

View file

@ -351,7 +351,7 @@ func CountRecentFailedLoginLogs(minutes uint, failCount uint) (int, bool, error)
if err != nil { if err != nil {
return 0, false, err return 0, false, err
} }
return int(count), int(count) > int(failCount), nil return int(count), int(count) >= int(failCount), nil
} }
func FindRecentSuccessLoginsNotInWhitelist(minutes int, whitelist []string) ([]model.LoginLog, error) { func FindRecentSuccessLoginsNotInWhitelist(minutes int, whitelist []string) ([]model.LoginLog, error) {
@ -381,7 +381,7 @@ func FindRecentSuccessLoginsNotInWhitelist(minutes int, whitelist []string) ([]m
} }
func CountRecentFailedSSHLog(minutes uint, maxAllowed uint) (int, bool, error) { func CountRecentFailedSSHLog(minutes uint, maxAllowed uint) (int, bool, error) {
lines, err := grepSSHLog("Failed password") lines, err := grepSSHLog([]string{"Failed password", "Invalid user", "authentication failure"})
if err != nil { if err != nil {
return 0, false, err return 0, false, err
} }
@ -402,11 +402,11 @@ func CountRecentFailedSSHLog(minutes uint, maxAllowed uint) (int, bool, error) {
count++ count++
} }
} }
return count, count > int(maxAllowed), nil return count, count >= int(maxAllowed), nil
} }
func FindRecentSuccessLoginNotInWhitelist(minutes int, whitelist []string) ([]string, error) { func FindRecentSuccessLoginNotInWhitelist(minutes int, whitelist []string) ([]string, error) {
lines, err := grepSSHLog("Accepted password") lines, err := grepSSHLog([]string{"Accepted password", "Accepted publickey"})
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -452,35 +452,42 @@ func findGrepPath() (string, error) {
return path, nil return path, nil
} }
func grepSSHLog(keyword string) ([]string, error) { func grepSSHLog(keywords []string) ([]string, error) {
logFiles := []string{"/var/log/secure", "/var/log/auth.log"} logFiles := []string{"/var/log/secure", "/var/log/auth.log"}
var results []string var results []string
seen := make(map[string]struct{})
grepPath, err := findGrepPath() grepPath, err := findGrepPath()
if err != nil { if err != nil {
panic(err) return nil, fmt.Errorf("find grep failed: %w", err)
} }
for _, logFile := range logFiles { for _, logFile := range logFiles {
if _, err := os.Stat(logFile); err != nil { if _, err := os.Stat(logFile); err != nil {
continue continue
} }
cmd := exec.Command(grepPath, "-a", keyword, logFile) for _, keyword := range keywords {
output, err := cmd.Output() cmd := exec.Command(grepPath, "-a", keyword, logFile)
if err != nil { output, err := cmd.Output()
var exitErr *exec.ExitError if err != nil {
if errors.As(err, &exitErr) { var exitErr *exec.ExitError
if exitErr.ExitCode() == 1 { if errors.As(err, &exitErr) {
continue if exitErr.ExitCode() == 1 {
continue
}
} }
return nil, fmt.Errorf("read log file fail [%s]: %w", logFile, err)
} }
return nil, fmt.Errorf("read log file fail [%s]: %w", logFile, err)
}
lines := strings.Split(string(output), "\n") lines := strings.Split(string(output), "\n")
for _, line := range lines { for _, line := range lines {
line = strings.TrimSpace(line) line = strings.TrimSpace(line)
if line != "" { if line != "" {
results = append(results, line) if _, exists := seen[line]; !exists {
results = append(results, line)
seen[line] = struct{}{}
}
}
} }
} }
} }
@ -490,12 +497,12 @@ func grepSSHLog(keyword string) ([]string, error) {
func parseLogTime(line string) (time.Time, error) { func parseLogTime(line string) (time.Time, error) {
if len(line) < 15 { if len(line) < 15 {
return time.Time{}, errors.New("log line time is incorrect") return time.Time{}, nil
} }
timeStr := line[:15] timeStr := line[:15]
parsedTime, err := time.ParseInLocation("Jan 2 15:04:05", timeStr, time.Local) parsedTime, err := time.ParseInLocation("Jan 2 15:04:05", timeStr, time.Local)
if err != nil { if err != nil {
return time.Time{}, err return time.Time{}, nil
} }
return parsedTime.AddDate(time.Now().Year(), 0, 0), nil return parsedTime.AddDate(time.Now().Year(), 0, 0), nil
} }

View file

@ -63,6 +63,7 @@
<ComplexTable <ComplexTable
:pagination-config="paginationConfig" :pagination-config="paginationConfig"
:data="data" :data="data"
:height-diff="380"
@sort-change="changeSort" @sort-change="changeSort"
@search="search()" @search="search()"
> >

View file

@ -272,8 +272,10 @@
v-if="ipTypes.includes(dialogData.rowData!.type)" v-if="ipTypes.includes(dialogData.rowData!.type)"
prop="count" prop="count"
> >
<div class="flex items-center flex-row md:flex-nowrap flex-wrap justify-between gap-x-3 w-full"> <div
<el-form-item prop="cycle"> class="flex items-center flex-row md:flex-nowrap sm:flex-nowrap flex-wrap justify-between gap-2 w-full"
>
<el-form-item prop="cycle" class="md:flex-1 sm:flex-1">
<el-input v-model.number="dialogData.rowData!.cycle" :max="200"> <el-input v-model.number="dialogData.rowData!.cycle" :max="200">
<template #append>{{ $t('commons.units.minute') }}</template> <template #append>{{ $t('commons.units.minute') }}</template>
</el-input> </el-input>
@ -282,7 +284,7 @@
<span class="whitespace-nowrap input-help w-[4.5rem]"> <span class="whitespace-nowrap input-help w-[4.5rem]">
{{ $t('xpack.alert.loginFail') }} {{ $t('xpack.alert.loginFail') }}
</span> </span>
<el-form-item prop="count"> <el-form-item prop="count" class="md:flex-1 sm:flex-1">
<el-input v-model.number="dialogData.rowData!.count"> <el-input v-model.number="dialogData.rowData!.count">
<template #append>{{ $t('commons.units.time') }}</template> <template #append>{{ $t('commons.units.time') }}</template>
</el-input> </el-input>
@ -498,7 +500,11 @@ function checkSendCount(rule: any, value: any, callback: any) {
if (value === '') { if (value === '') {
callback(); callback();
} }
if (dialogData.value.rowData.type === 'disk' || avgTypes.includes(dialogData.value.rowData.type)) { if (
dialogData.value.rowData.type === 'disk' ||
avgTypes.includes(dialogData.value.rowData.type) ||
ipTypes.includes(dialogData.value.rowData.type)
) {
const regex = /^(?:[1-9]|[1-4][0-9]|50)$/; const regex = /^(?:[1-9]|[1-4][0-9]|50)$/;
if (!regex.test(value)) { if (!regex.test(value)) {
return callback(new Error(i18n.global.t('commons.rule.numberRange', [1, 50]))); return callback(new Error(i18n.global.t('commons.rule.numberRange', [1, 50])));