[monitor] 实现进程报警与处理
This commit is contained in:
parent
2167db4918
commit
14e41d114e
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user