diff --git a/cmd/start/start.go b/cmd/start/start.go index a9e4a89..df3d8b6 100644 --- a/cmd/start/start.go +++ b/cmd/start/start.go @@ -88,13 +88,13 @@ var StartCmd = &cobra.Command{ // ====== 启动文件监听 ====== logger.Log.Info("正在启动文件监听...") - mon, err := watcher.NewWatcher(cfg) + fileMon, err := watcher.NewWatcher(cfg) if err != nil { logger.Log.Error("启动文件监听失败", zap.Error(err)) os.Exit(1) } - mon.Start() + fileMon.Start() // ====== 初始化文件检测器 ====== 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.Start() @@ -120,7 +126,7 @@ var StartCmd = &cobra.Command{ for { select { - case event := <-mon.Events(): + case event := <-fileMon.Events(): logger.Log.Info("文件系统事件", zap.String("path", event.Path), zap.String("op", event.Op.String()), @@ -139,12 +145,29 @@ var StartCmd = &cobra.Command{ 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)) case <-quit: logger.Log.Info("正在停止系统监控守护服务...") - mon.Stop() + fileMon.Stop() procScheduler.Stop() logger.Log.Info("系统监控守护服务已停止") return diff --git a/internal/config/config.go b/internal/config/config.go index 27a27c1..b7356cc 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -51,10 +51,11 @@ type ProcessScannerConfig struct { } type StorageConfig struct { - DataDir string `yaml:"data_dir"` - ProcessSystemFile string `yaml:"process_system_file"` - FileSystemFile string `yaml:"file_system_file"` - DubiousFileListFile string `yaml:"dubious_file_list_file"` + DataDir string `yaml:"data_dir"` + ProcessSystemFile string `yaml:"process_system_file"` + FileSystemFile string `yaml:"file_system_file"` + DubiousFileListFile string `yaml:"dubious_file_list_file"` + DubiousProcessListFile string `yaml:"dubious_process_list_file"` } type FileScannerConfig struct { diff --git a/internal/monitor/detector/process_detector.go b/internal/monitor/detector/process_detector.go index 2f76726..58e6179 100644 --- a/internal/monitor/detector/process_detector.go +++ b/internal/monitor/detector/process_detector.go @@ -6,8 +6,11 @@ import ( "path/filepath" "strings" "sysmonitord/internal/config" + "sysmonitord/internal/scanner/hash" "sysmonitord/internal/scanner/process" + "sysmonitord/internal/storage" "sysmonitord/pkg/logger" + "time" "go.uber.org/zap" ) @@ -16,16 +19,18 @@ type ProcessDetector struct { cfg *config.Config whiteList map[string]string storagePath string + eventChan chan storage.DubiousProcessInfo } -func NewProcessDetector(cfg *config.Config) *ProcessDetector { +func NewProcessDetector(cfg *config.Config) (*ProcessDetector, error) { p := &ProcessDetector{ cfg: cfg, whiteList: make(map[string]string), + eventChan: make(chan storage.DubiousProcessInfo, 100), } p.loadWhiteList() - return p + return p, nil } func (p *ProcessDetector) loadWhiteList() { @@ -59,7 +64,7 @@ func (p *ProcessDetector) Run() error { currentProcs, err := process.ScanAllProcesses(p.cfg) if err != nil { logger.Log.Error("[monitor] 扫描进程失败", zap.Error(err)) - return err + return nil } 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)) 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 } +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 { return "ProcessMonitor" } diff --git a/internal/scanner/file/scanner.go b/internal/scanner/file/file.go similarity index 100% rename from internal/scanner/file/scanner.go rename to internal/scanner/file/file.go diff --git a/internal/storage/storage.go b/internal/storage/storage.go index 8bd30f0..985097a 100644 --- a/internal/storage/storage.go +++ b/internal/storage/storage.go @@ -104,6 +104,34 @@ type DubiousFileInfo struct { 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 { filePath := filepath.Join(dataDir, dubiousFileName)