[monitor] 实现进程报警与处理

This commit is contained in:
wuko233 2026-04-07 08:53:48 +08:00
parent 2167db4918
commit 14e41d114e
5 changed files with 109 additions and 14 deletions

View File

@ -88,13 +88,13 @@ var StartCmd = &cobra.Command{
// ====== 启动文件监听 ====== // ====== 启动文件监听 ======
logger.Log.Info("正在启动文件监听...") logger.Log.Info("正在启动文件监听...")
mon, err := watcher.NewWatcher(cfg) fileMon, err := watcher.NewWatcher(cfg)
if err != nil { if err != nil {
logger.Log.Error("启动文件监听失败", zap.Error(err)) logger.Log.Error("启动文件监听失败", zap.Error(err))
os.Exit(1) os.Exit(1)
} }
mon.Start() fileMon.Start()
// ====== 初始化文件检测器 ====== // ====== 初始化文件检测器 ======
fileDetector, err := detector.NewFileDetector(cfg) fileDetector, err := detector.NewFileDetector(cfg)
@ -104,7 +104,13 @@ var StartCmd = &cobra.Command{
} }
// ====== 启动进程检测定时任务 ====== // ====== 启动进程检测定时任务 ======
procDetector := detector.NewProcessDetector(cfg) procDetector, err := detector.NewProcessDetector(cfg)
if err != nil {
logger.Log.Error("初始化进程检测器失败", zap.Error(err))
os.Exit(1)
}
procEventChan := procDetector.Event()
procScheduler := timer.NewScheduler(time.Duration(cfg.Scanner.Process.Interval)*time.Second, procDetector) procScheduler := timer.NewScheduler(time.Duration(cfg.Scanner.Process.Interval)*time.Second, procDetector)
procScheduler.Start() procScheduler.Start()
@ -120,7 +126,7 @@ var StartCmd = &cobra.Command{
for { for {
select { select {
case event := <-mon.Events(): case event := <-fileMon.Events():
logger.Log.Info("文件系统事件", logger.Log.Info("文件系统事件",
zap.String("path", event.Path), zap.String("path", event.Path),
zap.String("op", event.Op.String()), zap.String("op", event.Op.String()),
@ -139,12 +145,29 @@ var StartCmd = &cobra.Command{
Details: "To test", Details: "To test",
}) })
case err := <-mon.Errors(): case procEvents := <-procEventChan:
logger.Log.Info("可疑进程事件",
zap.Int32("pid", procEvents.PID),
zap.String("name", procEvents.Name),
zap.String("path", procEvents.Path),
)
procDetector.HandleDubiousProcesses(procEvents)
// test
alerter.PushAlert(notifier.AlertEvent{
Type: "Process",
Path: procEvents.Path,
Reason: "可疑进程",
Details: "To test",
})
case err := <-fileMon.Errors():
logger.Log.Error("文件监听错误", zap.Error(err)) logger.Log.Error("文件监听错误", zap.Error(err))
case <-quit: case <-quit:
logger.Log.Info("正在停止系统监控守护服务...") logger.Log.Info("正在停止系统监控守护服务...")
mon.Stop() fileMon.Stop()
procScheduler.Stop() procScheduler.Stop()
logger.Log.Info("系统监控守护服务已停止") logger.Log.Info("系统监控守护服务已停止")
return return

View File

@ -55,6 +55,7 @@ type StorageConfig struct {
ProcessSystemFile string `yaml:"process_system_file"` ProcessSystemFile string `yaml:"process_system_file"`
FileSystemFile string `yaml:"file_system_file"` FileSystemFile string `yaml:"file_system_file"`
DubiousFileListFile string `yaml:"dubious_file_list_file"` DubiousFileListFile string `yaml:"dubious_file_list_file"`
DubiousProcessListFile string `yaml:"dubious_process_list_file"`
} }
type FileScannerConfig struct { type FileScannerConfig struct {

View File

@ -6,8 +6,11 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"sysmonitord/internal/config" "sysmonitord/internal/config"
"sysmonitord/internal/scanner/hash"
"sysmonitord/internal/scanner/process" "sysmonitord/internal/scanner/process"
"sysmonitord/internal/storage"
"sysmonitord/pkg/logger" "sysmonitord/pkg/logger"
"time"
"go.uber.org/zap" "go.uber.org/zap"
) )
@ -16,16 +19,18 @@ type ProcessDetector struct {
cfg *config.Config cfg *config.Config
whiteList map[string]string whiteList map[string]string
storagePath string storagePath string
eventChan chan storage.DubiousProcessInfo
} }
func NewProcessDetector(cfg *config.Config) *ProcessDetector { func NewProcessDetector(cfg *config.Config) (*ProcessDetector, error) {
p := &ProcessDetector{ p := &ProcessDetector{
cfg: cfg, cfg: cfg,
whiteList: make(map[string]string), whiteList: make(map[string]string),
eventChan: make(chan storage.DubiousProcessInfo, 100),
} }
p.loadWhiteList() p.loadWhiteList()
return p return p, nil
} }
func (p *ProcessDetector) loadWhiteList() { func (p *ProcessDetector) loadWhiteList() {
@ -59,7 +64,7 @@ func (p *ProcessDetector) Run() error {
currentProcs, err := process.ScanAllProcesses(p.cfg) currentProcs, err := process.ScanAllProcesses(p.cfg)
if err != nil { if err != nil {
logger.Log.Error("[monitor] 扫描进程失败", zap.Error(err)) logger.Log.Error("[monitor] 扫描进程失败", zap.Error(err))
return err return nil
} }
newCount := 0 newCount := 0
@ -69,7 +74,19 @@ func (p *ProcessDetector) Run() error {
logger.Log.Warn("[monitor] 发现新进程", zap.String("name", proc.Name), zap.String("path", proc.Path)) logger.Log.Warn("[monitor] 发现新进程", zap.String("name", proc.Name), zap.String("path", proc.Path))
newCount++ newCount++
// Todo: 处理新进程 dubiousProcess := storage.DubiousProcessInfo{
PID: proc.PID,
Name: proc.Name,
Path: proc.Path,
Cmdline: proc.Cmdline,
DiscoveredAt: time.Now().Format("2006-01-02 15:04:05"),
}
select {
case p.eventChan <- dubiousProcess:
default:
logger.Log.Warn("[monitor] 进程事件通道已满,丢弃事件", zap.Int32("pid", proc.PID), zap.String("name", proc.Name))
}
} }
} }
@ -77,6 +94,32 @@ func (p *ProcessDetector) Run() error {
return nil return nil
} }
func (p *ProcessDetector) Event() <-chan storage.DubiousProcessInfo {
return p.eventChan
}
func (p *ProcessDetector) HandleDubiousProcesses(proc storage.DubiousProcessInfo) {
hashCfg, err := p.cfg.GetHashConfig()
if err != nil {
logger.Log.Error("[monitor] 获取哈希配置失败", zap.Error(err))
}
logger.Log.Debug("[monitor] 处理可疑进程", zap.Int32("pid", proc.PID), zap.String("name", proc.Name), zap.String("path", proc.Path))
procHash, err := hash.Calculate(proc.Path, 0, hashCfg)
if err != nil {
logger.Log.Error("[monitor] 计算进程哈希失败", zap.String("path", proc.Path), zap.Error(err))
}
proc.FileHash = procHash
if err := storage.SaveDubiousProcesses(proc, p.cfg.Storage.DataDir, p.cfg.Storage.DubiousProcessListFile); err != nil {
logger.Log.Error("[monitor] 保存可疑进程失败", zap.Int32("pid", proc.PID), zap.String("name", proc.Name), zap.String("path", proc.Path), zap.Error(err))
}
}
func (p *ProcessDetector) Name() string { func (p *ProcessDetector) Name() string {
return "ProcessMonitor" return "ProcessMonitor"
} }

View File

@ -104,6 +104,34 @@ type DubiousFileInfo struct {
DiscoveredAt string DiscoveredAt string
} }
type DubiousProcessInfo struct {
PID int32
Name string
Path string
Cmdline string
FileHash string
DiscoveredAt string
}
func SaveDubiousProcesses(proc DubiousProcessInfo, dataDir string, dubiousProcessFile string) error {
filePath := filepath.Join(dataDir, dubiousProcessFile)
f, err := os.OpenFile(filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
return fmt.Errorf("[storage]无法创建或打开可疑进程记录文件%s: %w", filePath, err)
}
defer f.Close()
writer := bufio.NewWriter(f)
line := fmt.Sprintf("%d:%s:%s:%s:%s\n", proc.PID, proc.Name, proc.Path, proc.Cmdline, proc.DiscoveredAt)
if _, err := writer.WriteString(line); err != nil {
return err
}
return writer.Flush()
}
func SaveDubiousFiles(files DubiousFileInfo, dataDir string, dubiousFileName string) error { func SaveDubiousFiles(files DubiousFileInfo, dataDir string, dubiousFileName string) error {
filePath := filepath.Join(dataDir, dubiousFileName) filePath := filepath.Join(dataDir, dubiousFileName)