Compare commits
2 Commits
279f58b644
...
ce031be060
| Author | SHA1 | Date | |
|---|---|---|---|
|
ce031be060
|
|||
|
5e50bc179f
|
@@ -7,6 +7,9 @@
|
||||
* В настройках analyzer.toml добавил параметры su_enable и su_notify.
|
||||
* su_enable = Включает отслеживание авторизаций через su. По умолчанию включён.
|
||||
* su_notify = Включает уведомления об авторизациях через su. По умолчанию включён.
|
||||
* В настройках analyzer.toml добавил параметры sudo_enable и sudo_notify.
|
||||
* sudo_enable = Включает отслеживание авторизаций через sudo. По умолчанию выключен.
|
||||
* sudo_notify = Включает уведомления об авторизациях через sudo. По умолчанию включён.
|
||||
***
|
||||
#### English
|
||||
* Added local_enable and local_notify parameters to analyzer.toml settings.
|
||||
@@ -15,6 +18,9 @@
|
||||
* Added su_enable and su_notify parameters to analyzer.toml settings.
|
||||
* su_enable = Enables tracking of logins via su. Enabled by default.
|
||||
* su_notify = Enables notifications about logins via su. Enabled by default.
|
||||
* Added sudo_enable and sudo_notify parameters to analyzer.toml settings.
|
||||
* sudo_enable = Enables tracking of logins via sudo. Off by default.
|
||||
* sudo_notify = Enables notifications about logins via sudo. Enabled by default.
|
||||
***
|
||||
## 0.4.0 (11.1.2026)
|
||||
***
|
||||
|
||||
@@ -81,3 +81,30 @@ su_enable = true
|
||||
# Default: true
|
||||
###
|
||||
su_notify = true
|
||||
|
||||
###
|
||||
# Включает отслеживание, если кто-либо использует команду `sudo` для доступа к другой учетной записи.
|
||||
#
|
||||
# ПРИМЕЧАНИЕ: Эта опция может стать обременительной, если команда sudo широко используется
|
||||
# для получения root-доступа администраторами или панелями управления.
|
||||
#
|
||||
# По умолчанию: false
|
||||
# ***
|
||||
# Enables tracking if someone uses the `sudo` command to access another account.
|
||||
#
|
||||
# NOTE: This option could become onerous if sudo is used extensively for root
|
||||
# access by administrators or control panels.
|
||||
#
|
||||
# Default: false
|
||||
###
|
||||
sudo_enable = false
|
||||
|
||||
###
|
||||
# Включает уведомления, если кто-либо использует команду `sudo` для доступа к другой учетной записи.
|
||||
# По умолчанию: true
|
||||
# ***
|
||||
# Enables notifications if someone uses the `sudo` command to access another account.
|
||||
# Default: true
|
||||
###
|
||||
sudo_notify = true
|
||||
|
||||
|
||||
@@ -41,6 +41,10 @@ func New(config config2.Config, logger log.Logger, notify notifications.Notifica
|
||||
if config.Login.Su.Enabled {
|
||||
units = append(units, "SYSLOG_IDENTIFIER=su")
|
||||
}
|
||||
|
||||
if config.Login.Sudo.Enabled {
|
||||
units = append(units, "SYSLOG_IDENTIFIER=sudo")
|
||||
}
|
||||
}
|
||||
|
||||
systemdService := analyzerLog.NewSystemd(config.BinPath.Journalctl, units, logger)
|
||||
@@ -84,6 +88,10 @@ func (a *analyzer) processLogs(ctx context.Context) {
|
||||
if err := a.analysis.Locale(&entry); err != nil {
|
||||
a.logger.Error(fmt.Sprintf("Failed to analyze locale logs: %s", err))
|
||||
}
|
||||
case entry.SyslogIdentifier == "sudo":
|
||||
if err := a.analysis.Sudo(&entry); err != nil {
|
||||
a.logger.Error(fmt.Sprintf("Failed to analyze sudo 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))
|
||||
|
||||
@@ -6,6 +6,7 @@ type Login struct {
|
||||
SSH LoginSSH
|
||||
Local LoginLocal
|
||||
Su LoginSu
|
||||
Sudo LoginSudo
|
||||
}
|
||||
|
||||
type LoginSSH struct {
|
||||
@@ -22,3 +23,8 @@ type LoginSu struct {
|
||||
Enabled bool
|
||||
Notify bool
|
||||
}
|
||||
|
||||
type LoginSudo struct {
|
||||
Enabled bool
|
||||
Notify bool
|
||||
}
|
||||
|
||||
@@ -11,12 +11,14 @@ type Analysis interface {
|
||||
SSH(entry *analysisServices.Entry) error
|
||||
Locale(entry *analysisServices.Entry) error
|
||||
Su(entry *analysisServices.Entry) error
|
||||
Sudo(entry *analysisServices.Entry) error
|
||||
}
|
||||
|
||||
type analysis struct {
|
||||
sshService analysisServices.Analysis
|
||||
localeService analysisServices.Analysis
|
||||
suService analysisServices.Analysis
|
||||
sudoService analysisServices.Analysis
|
||||
|
||||
logger log.Logger
|
||||
notify notifications.Notifications
|
||||
@@ -27,6 +29,7 @@ func NewAnalysis(config *config.Config, logger log.Logger, notify notifications.
|
||||
sshService: analysisServices.NewSSH(config, logger, notify),
|
||||
localeService: analysisServices.NewLocale(config, logger, notify),
|
||||
suService: analysisServices.NewSu(config, logger, notify),
|
||||
sudoService: analysisServices.NewSudo(config, logger, notify),
|
||||
logger: logger,
|
||||
notify: notify,
|
||||
}
|
||||
@@ -43,3 +46,7 @@ func (a *analysis) Locale(entry *analysisServices.Entry) error {
|
||||
func (a *analysis) Su(entry *analysisServices.Entry) error {
|
||||
return a.suService.Process(entry)
|
||||
}
|
||||
|
||||
func (a *analysis) Sudo(entry *analysisServices.Entry) error {
|
||||
return a.sudoService.Process(entry)
|
||||
}
|
||||
|
||||
81
internal/daemon/analyzer/log/analysis/sudo.go
Normal file
81
internal/daemon/analyzer/log/analysis/sudo.go
Normal file
@@ -0,0 +1,81 @@
|
||||
package analysis
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"git.kor-elf.net/kor-elf-shield/kor-elf-shield/internal/daemon/analyzer/config"
|
||||
"git.kor-elf.net/kor-elf-shield/kor-elf-shield/internal/daemon/notifications"
|
||||
"git.kor-elf.net/kor-elf-shield/kor-elf-shield/internal/i18n"
|
||||
"git.kor-elf.net/kor-elf-shield/kor-elf-shield/internal/log"
|
||||
)
|
||||
|
||||
type sudo struct {
|
||||
login sudoLogin
|
||||
|
||||
logger log.Logger
|
||||
notify notifications.Notifications
|
||||
}
|
||||
|
||||
type sudoLogin struct {
|
||||
enabled bool
|
||||
notify bool
|
||||
}
|
||||
|
||||
func NewSudo(config *config.Config, logger log.Logger, notify notifications.Notifications) Analysis {
|
||||
if !config.Login.Enabled || !config.Login.Su.Enabled {
|
||||
return &EmptyAnalysis{}
|
||||
}
|
||||
|
||||
return &sudo{
|
||||
login: sudoLogin{
|
||||
enabled: config.Login.Enabled && config.Login.Sudo.Enabled,
|
||||
notify: config.Login.Notify && config.Login.Sudo.Notify,
|
||||
},
|
||||
|
||||
logger: logger,
|
||||
notify: notify,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *sudo) Process(entry *Entry) error {
|
||||
if s.login.enabled {
|
||||
result, err := s.login.process(entry)
|
||||
if err != nil {
|
||||
s.logger.Error(fmt.Sprintf("Failed to process Sudo login: %s", err))
|
||||
} else if result.found {
|
||||
if s.login.notify {
|
||||
s.notify.SendAsync(notifications.Message{Subject: result.subject, Body: result.body})
|
||||
}
|
||||
s.logger.Info(fmt.Sprintf("Sudo login detected: %s", entry.Message))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *sudoLogin) process(entry *Entry) (processReturn, error) {
|
||||
re := regexp.MustCompile(`^pam_unix\(sudo:session\): session opened for user (\S+)\(\S+\) by (\S+)\(\S+\)`)
|
||||
matches := re.FindStringSubmatch(entry.Message)
|
||||
|
||||
if matches != nil {
|
||||
user := matches[1]
|
||||
byUser := matches[2]
|
||||
|
||||
return processReturn{
|
||||
found: true,
|
||||
subject: i18n.Lang.T("alert.login.sudo.subject", map[string]any{
|
||||
"User": user,
|
||||
"ByUser": byUser,
|
||||
}),
|
||||
body: i18n.Lang.T("alert.login.sudo.body", map[string]any{
|
||||
"User": user,
|
||||
"ByUser": byUser,
|
||||
"Log": entry.Message,
|
||||
"Time": entry.Time,
|
||||
}),
|
||||
}, nil
|
||||
}
|
||||
|
||||
return processReturn{found: false}, nil
|
||||
}
|
||||
@@ -34,5 +34,8 @@
|
||||
"alert.login.locale.body": "Logged into the OS via TTY:\n Time: {{.Time}}\n User: {{.User}}\n Log: {{.Log}}",
|
||||
|
||||
"alert.login.su.subject": "User {{.ByUser}} has accessed user {{.User}} via su",
|
||||
"alert.login.su.body": "User {{.ByUser}} accessed user {{.User}} via su.\nTime: {{.Time}}\nLog: {{.Log}}"
|
||||
"alert.login.su.body": "User {{.ByUser}} accessed user {{.User}} via su.\nTime: {{.Time}}\nLog: {{.Log}}",
|
||||
|
||||
"alert.login.sudo.subject": "User {{.ByUser}} has accessed user {{.User}} via sudo",
|
||||
"alert.login.sudo.body": "User {{.ByUser}} accessed user {{.User}} via sudo.\nTime: {{.Time}}\nLog: {{.Log}}"
|
||||
}
|
||||
|
||||
@@ -34,5 +34,8 @@
|
||||
"alert.login.locale.body": "ОЖ-ға TTY арқылы кірдіңіз:\n Уақыт: {{.Time}}\n Пайдаланушы: {{.User}}\n Лог: {{.Log}}",
|
||||
|
||||
"alert.login.su.subject": "{{.ByUser}} пайдаланушысы {{.User}} пайдаланушысына su арқылы кіру мүмкіндігін алды",
|
||||
"alert.login.su.body": "{{.ByUser}} пайдаланушысы {{.User}} пайдаланушысына su арқылы кірді.\nУақыты: {{.Time}}\nЛог: {{.Log}}"
|
||||
"alert.login.su.body": "{{.ByUser}} пайдаланушысы {{.User}} пайдаланушысына su арқылы кірді.\nУақыты: {{.Time}}\nЛог: {{.Log}}",
|
||||
|
||||
"alert.login.sudo.subject": "{{.ByUser}} пайдаланушысы {{.User}} пайдаланушысына sudo арқылы кіру мүмкіндігін алды",
|
||||
"alert.login.sudo.body": "{{.ByUser}} пайдаланушысы {{.User}} пайдаланушысына sudo арқылы кірді.\nУақыты: {{.Time}}\nЛог: {{.Log}}"
|
||||
}
|
||||
@@ -34,5 +34,8 @@
|
||||
"alert.login.locale.body": "Вошли в ОС через TTY:\n Время: {{.Time}}\n Пользователь: {{.User}}\n Лог: {{.Log}}",
|
||||
|
||||
"alert.login.su.subject": "Пользователь {{.ByUser}} получил доступ к пользователю {{.User}} через su",
|
||||
"alert.login.su.body": "Пользователь {{.ByUser}} получил доступ к пользователю {{.User}} через su.\nВремя: {{.Time}}\nЛог: {{.Log}}"
|
||||
"alert.login.su.body": "Пользователь {{.ByUser}} получил доступ к пользователю {{.User}} через su.\nВремя: {{.Time}}\nЛог: {{.Log}}",
|
||||
|
||||
"alert.login.sudo.subject": "Пользователь {{.ByUser}} получил доступ к пользователю {{.User}} через sudo",
|
||||
"alert.login.sudo.body": "Пользователь {{.ByUser}} получил доступ к пользователю {{.User}} через sudo.\nВремя: {{.Time}}\nЛог: {{.Log}}"
|
||||
}
|
||||
@@ -12,6 +12,9 @@ type Login struct {
|
||||
|
||||
SuEnable bool `mapstructure:"su_enable"`
|
||||
SuNotify bool `mapstructure:"su_notify"`
|
||||
|
||||
SudoEnable bool `mapstructure:"sudo_enable"`
|
||||
SudoNotify bool `mapstructure:"sudo_notify"`
|
||||
}
|
||||
|
||||
func defaultLogin() Login {
|
||||
@@ -27,6 +30,9 @@ func defaultLogin() Login {
|
||||
|
||||
SuEnable: true,
|
||||
SuNotify: true,
|
||||
|
||||
SudoEnable: false,
|
||||
SudoNotify: true,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -165,6 +165,10 @@ func (o *otherSettingsPath) ToAnalyzerConfig(binaryLocations *binaryLocations) (
|
||||
Enabled: setting.Login.SuEnable,
|
||||
Notify: setting.Login.SuNotify,
|
||||
},
|
||||
Sudo: config.LoginSudo{
|
||||
Enabled: setting.Login.SudoEnable,
|
||||
Notify: setting.Login.SudoNotify,
|
||||
},
|
||||
}
|
||||
|
||||
return config.Config{
|
||||
|
||||
Reference in New Issue
Block a user