SSH 登录监控增加 IP 归属地

This commit is contained in:
dushixiang committed 2026-01-18 11:14:57 +08:00
1 parent bda3be6902
commit b34ddd750f
4 files changed
+43 -23

No files matched your search

+11 -10
View File
@@ -2,16 +2,17 @@ package models
// SSHLoginEvent SSH登录事件
type SSHLoginEvent struct {
ID string `gorm:"primaryKey" json:"id"` // 事件ID (UUID)
AgentID string `gorm:"index;not null" json:"agentId"` // 探针ID
Username string `gorm:"index" json:"username"` // 用户名
IP string `gorm:"index" json:"ip"` // 来源IP
Port string `json:"port,omitempty"` // 来源端口
Status string `gorm:"index" json:"status"` // 状态: success
TTY string `json:"tty,omitempty"` // 终端
SessionID string `json:"sessionId,omitempty"` // 会话ID
Timestamp int64 `gorm:"index" json:"timestamp"` // 登录时间(毫秒时间戳)
CreatedAt int64 `json:"createdAt"` // 记录创建时间(毫秒)
ID string `gorm:"primaryKey" json:"id"` // 事件ID (UUID)
AgentID string `gorm:"index;not null" json:"agentId"` // 探针ID
Username string `gorm:"index" json:"username"` // 用户名
IP string `gorm:"index" json:"ip"` // 来源IP
IPLocation string `gorm:"index" json:"ipLocation,omitempty"` // IP归属地
Port string `json:"port,omitempty"` // 来源端口
Status string `gorm:"index" json:"status"` // 状态: success
TTY string `json:"tty,omitempty"` // 终端
SessionID string `json:"sessionId,omitempty"` // 会话ID
Timestamp int64 `gorm:"index" json:"timestamp"` // 登录时间(毫秒时间戳)
CreatedAt int64 `json:"createdAt"` // 记录创建时间(毫秒)
}
func (SSHLoginEvent) TableName() string {
+24 -13
View File
@@ -137,18 +137,24 @@ func (s *SSHLoginService) HandleEvent(ctx context.Context, agentID string, event
return nil
}
ipLocation := ""
if s.geoIPSvc != nil && eventData.IP != "" {
ipLocation = s.geoIPSvc.LookupIP(eventData.IP)
}
// 保存事件到数据库
event := &models.SSHLoginEvent{
ID: uuid.NewString(),
AgentID: agentID,
Username: eventData.Username,
IP: eventData.IP,
Port: eventData.Port,
Status: eventData.Status,
TTY: eventData.TTY,
SessionID: eventData.SessionID,
Timestamp: eventData.Timestamp,
CreatedAt: time.Now().UnixMilli(),
ID: uuid.NewString(),
AgentID: agentID,
Username: eventData.Username,
IP: eventData.IP,
IPLocation: ipLocation,
Port: eventData.Port,
Status: eventData.Status,
TTY: eventData.TTY,
SessionID: eventData.SessionID,
Timestamp: eventData.Timestamp,
CreatedAt: time.Now().UnixMilli(),
}
if err := s.SSHLoginEventRepo.Create(ctx, event); err != nil {
@@ -166,12 +172,12 @@ func (s *SSHLoginService) HandleEvent(ctx context.Context, agentID string, event
s.logger.Info("IP在白名单中,忽略事件", zap.String("agentId", agentID), zap.String("ip", eventData.IP))
return nil
}
s.sendLoginSuccessNotification(agentID, eventData)
s.sendLoginSuccessNotification(agentID, eventData, ipLocation)
return nil
}
func (s *SSHLoginService) sendLoginSuccessNotification(agentID string, eventData protocol.SSHLoginEvent) {
func (s *SSHLoginService) sendLoginSuccessNotification(agentID string, eventData protocol.SSHLoginEvent, ipLocation string) {
if s.notificationSvc == nil {
return
}
@@ -199,11 +205,16 @@ func (s *SSHLoginService) sendLoginSuccessNotification(agentID string, eventData
sourceAddr = fmt.Sprintf("%s:%s", sourceIP, eventData.Port)
}
locationText := ipLocation
if locationText == "" {
locationText = "未知"
}
record := &models.AlertRecord{
AgentID: agentID,
AgentName: agent.Name,
AlertType: "ssh_login",
Message: fmt.Sprintf("SSH登录成功:用户 %s,来源 %s,终端 %s,会话 %s", eventData.Username, sourceAddr, eventData.TTY, eventData.SessionID),
Message: fmt.Sprintf("SSH登录成功:用户 %s,来源 %s,归属地 %s,终端 %s,会话 %s", eventData.Username, sourceAddr, locationText, eventData.TTY, eventData.SessionID),
Threshold: 0,
ActualValue: 0,
Level: "warning",
@@ -65,6 +65,13 @@ const SSHLoginEvents: React.FC<SSHLoginEventsProps> = ({agentId}) => {
<span className="font-mono text-sm">{record.ip}</span>
),
},
{
title: '归属地',
dataIndex: 'ipLocation',
key: 'ipLocation',
width: 140,
render: (_, record) => record.ipLocation || '-',
},
{
title: '端口',
dataIndex: 'port',
+1
View File
@@ -549,6 +549,7 @@ export interface SSHLoginEvent {
agentId: string;
username: string;
ip: string;
ipLocation?: string;
port?: string;
status: 'success' | 'failed';
method?: string;