Files
kor-elf-shield/internal/daemon/analyzer/analyzer.go
T

108 lines
2.6 KiB
Go

package analyzer
import (
"context"
"fmt"
config2 "git.kor-elf.net/kor-elf-shield/kor-elf-shield/internal/daemon/analyzer/config"
analyzerLog "git.kor-elf.net/kor-elf-shield/kor-elf-shield/internal/daemon/analyzer/log"
analysisServices "git.kor-elf.net/kor-elf-shield/kor-elf-shield/internal/daemon/analyzer/log/analysis"
"git.kor-elf.net/kor-elf-shield/kor-elf-shield/internal/daemon/notifications"
"git.kor-elf.net/kor-elf-shield/kor-elf-shield/internal/log"
)
type Analyzer interface {
Run(ctx context.Context)
Close() error
}
type analyzer struct {
config config2.Config
logger log.Logger
notify notifications.Notifications
systemd analyzerLog.Systemd
analysis analyzerLog.Analysis
logChan chan analysisServices.Entry
}
func New(config config2.Config, logger log.Logger, notify notifications.Notifications) Analyzer {
var units []string
if config.Login.Enabled {
if config.Login.SSH.Enabled {
units = append(units, "_SYSTEMD_UNIT=ssh.service")
}
if config.Login.Local.Enabled {
units = append(units, "SYSLOG_IDENTIFIER=login")
}
if config.Login.Su.Enabled {
units = append(units, "SYSLOG_IDENTIFIER=su")
}
}
systemdService := analyzerLog.NewSystemd(config.BinPath.Journalctl, units, logger)
analysisService := analyzerLog.NewAnalysis(&config, logger, notify)
return &analyzer{
config: config,
logger: logger,
notify: notify,
systemd: systemdService,
analysis: analysisService,
logChan: make(chan analysisServices.Entry, 1000),
}
}
func (a *analyzer) Run(ctx context.Context) {
go a.systemd.Run(ctx, a.logChan)
go a.processLogs(ctx)
a.logger.Debug("Analyzer is start")
}
func (a *analyzer) processLogs(ctx context.Context) {
for {
select {
case <-ctx.Done():
return
case entry, ok := <-a.logChan:
if !ok {
// Channel closed
return
}
a.logger.Debug(fmt.Sprintf("Received log entry: %s", entry))
switch {
case entry.Unit == "ssh.service":
if err := a.analysis.SSH(&entry); err != nil {
a.logger.Error(fmt.Sprintf("Failed to analyze SSH logs: %s", err))
}
case entry.SyslogIdentifier == "login":
if err := a.analysis.Locale(&entry); err != nil {
a.logger.Error(fmt.Sprintf("Failed to analyze locale logs: %s", err))
}
case entry.SyslogIdentifier == "su":
if err := a.analysis.Su(&entry); err != nil {
a.logger.Error(fmt.Sprintf("Failed to analyze su logs: %s", err))
}
default:
a.logger.Debug(fmt.Sprintf("Unknown unit or SyslogIdentifier: %s", entry.Unit))
}
}
}
}
func (a *analyzer) Close() error {
if err := a.systemd.Close(); err != nil {
return err
}
close(a.logChan)
a.logger.Debug("Analyzer is stop")
return nil
}