feat: 添加AgentID获取与发送

This commit is contained in:
wuko233 2026-03-25 08:22:57 +08:00
parent a9ee997d72
commit 553ce79ba2
3 changed files with 141 additions and 6 deletions

View File

@ -50,7 +50,7 @@ func main() {
log.Fatalf("[启动错误]下载配置失败: %v", err) log.Fatalf("[启动错误]下载配置失败: %v", err)
} }
CenterServerURL := determineServerURL(officialCfg, userCfg) CenterServerURL := determineServerURL(userCfg)
log.Println("[启动流程] 2/6: 初始化白名单判定引擎...") log.Println("[启动流程] 2/6: 初始化白名单判定引擎...")
wlManager := whitelist.NewManager(officialCfg, userCfg) wlManager := whitelist.NewManager(officialCfg, userCfg)
@ -168,7 +168,7 @@ func main() {
log.Println("[守护进程] 已成功停止,安全退出程序。") log.Println("[守护进程] 已成功停止,安全退出程序。")
} }
func determineServerURL(officialCfg config.OfficialConfig, userCfg config.UserConfig) string { func determineServerURL(userCfg config.UserConfig) string {
// 服务器地址仅从用户配置获取(符合 ARCHITECTURE.md 规范) // 服务器地址仅从用户配置获取(符合 ARCHITECTURE.md 规范)
if userCfg.Connection.CenterServerURL != "" { if userCfg.Connection.CenterServerURL != "" {
return userCfg.Connection.CenterServerURL return userCfg.Connection.CenterServerURL

101
internal/agent/identity.go Normal file
View File

@ -0,0 +1,101 @@
package agent
import (
"fmt"
"net"
"os"
"runtime"
"strings"
)
type Identity struct {
Hostname string `json:"hostname"`
MACAddr string `json:"mac_addr"`
AgentID string `json:"agent_id"`
IPAddr string `json:"ip_addr"`
OS string `json:"os"`
Arch string `json:"arch"`
PID int `json:"pid"`
}
func GetIdentity() (*Identity, error) {
hostname, err := os.Hostname()
if err != nil {
return nil, fmt.Errorf("[Agent]获取主机名失败: %v", err)
}
mac, err := getPrimaryMAC()
if err != nil {
return nil, fmt.Errorf("[Agent]获取MAC地址失败: %v", err)
}
ips, err := getIPAddrs()
if err != nil {
return nil, fmt.Errorf("[Agent]获取IP地址失败: %v", err)
}
AgentID := generateAgentID(hostname, mac)
return &Identity{
Hostname: hostname,
MACAddr: mac,
IPAddr: ips[0],
AgentID: AgentID,
OS: runtime.GOOS,
Arch: runtime.GOARCH,
PID: os.Getpid(),
}, nil
}
func getPrimaryMAC() (string, error) {
interfaces, err := net.Interfaces()
if err != nil {
return "", fmt.Errorf("[Agent]获取网络接口失败: %v", err)
}
for _, iface := range interfaces {
if iface.Flags&net.FlagLoopback != 0 {
continue // 跳过回环接口
}
mac := iface.HardwareAddr.String()
if mac == "" {
continue // 跳过没有MAC地址的接口
}
if iface.Flags&net.FlagUp != 0 {
return mac, nil // 返回第一个活动接口的MAC地址
}
}
for _, iface := range interfaces {
if iface.Flags&net.FlagLoopback == 0 && iface.HardwareAddr.String() != "" {
return iface.HardwareAddr.String(), nil // 返回第一个非回环接口的MAC地址
}
}
return "", fmt.Errorf("[Agent]未找到有效的网络接口")
}
func getIPAddrs() ([]string, error) {
var ips []string
addrs, err := net.InterfaceAddrs()
if err != nil {
return nil, fmt.Errorf("[Agent]获取IP地址失败: %v", err)
}
for _, addr := range addrs {
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
if ipnet.IP.To4() != nil {
ips = append(ips, ipnet.IP.String())
}
}
}
return ips, nil
}
func generateAgentID(hostname, mac string) string {
macFormat := strings.ToLower(strings.ReplaceAll(mac, ":", ""))
return fmt.Sprintf("%s-%s", hostname, macFormat)
}

View File

@ -3,14 +3,17 @@ package network
import ( import (
"encoding/json" "encoding/json"
"log" "log"
"net/url"
"sync" "sync"
"time" "time"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"github.com/wuko233/sysmonitord/internal/agent"
) )
type ClientConfig struct { type ClientConfig struct {
ServerURL string ServerURL string
AgentID string
SendInterval time.Duration SendInterval time.Duration
BufferSize int BufferSize int
} }
@ -24,20 +27,33 @@ type WSClient struct {
stopChan chan struct{} stopChan chan struct{}
handler MessageHandler handler MessageHandler
reconnectDelay time.Duration // 指数退避延迟 reconnectDelay time.Duration // 指数退避延迟
agentIdentity *agent.Identity
} }
func NewWSClient(cfg ClientConfig) *WSClient { func NewWSClient(cfg ClientConfig) *WSClient {
if cfg.BufferSize == 0 { if cfg.BufferSize == 0 {
cfg.BufferSize = 100 cfg.BufferSize = 100
} }
agentIdentity, err := agent.GetIdentity()
if err != nil {
log.Fatalf("[网络] 获取代理身份信息失败: %v", err)
}
cfg.AgentID = agentIdentity.AgentID
return &WSClient{ return &WSClient{
config: cfg, config: cfg,
sendChan: make(chan Packet, cfg.BufferSize), sendChan: make(chan Packet, cfg.BufferSize),
stopChan: make(chan struct{}), stopChan: make(chan struct{}),
reconnectDelay: 1 * time.Second, // 初始延迟 1秒 reconnectDelay: 1 * time.Second, // 初始延迟 1秒
agentIdentity: agentIdentity,
} }
} }
func (c *WSClient) GetAgentIdentity() *agent.Identity {
return c.agentIdentity
}
// SetHandler 设置消息处理器 // SetHandler 设置消息处理器
func (c *WSClient) SetHandler(handler MessageHandler) { func (c *WSClient) SetHandler(handler MessageHandler) {
c.handler = handler c.handler = handler
@ -93,9 +109,9 @@ func (c *WSClient) sendRaw(packet Packet) {
func (c *WSClient) connectionLoop() { func (c *WSClient) connectionLoop() {
const ( const (
initialDelay = 1 * time.Second initialDelay = 1 * time.Second
maxDelay = 60 * time.Second maxDelay = 60 * time.Second
backoffFactor = 2.0 backoffFactor = 2.0
) )
for { for {
@ -183,7 +199,9 @@ func (c *WSClient) closeConn() {
} }
func (c *WSClient) connect() error { func (c *WSClient) connect() error {
conn, _, err := websocket.DefaultDialer.Dial(c.config.ServerURL, nil) serverURL := c.buildURL()
conn, _, err := websocket.DefaultDialer.Dial(serverURL, nil)
if err != nil { if err != nil {
return err return err
} }
@ -203,3 +221,19 @@ func (c *WSClient) connect() error {
log.Printf("[网络] 成功连接到服务器: %s", c.config.ServerURL) log.Printf("[网络] 成功连接到服务器: %s", c.config.ServerURL)
return nil return nil
} }
func (c *WSClient) buildURL() string {
u, err := url.Parse(c.config.ServerURL)
if err != nil {
log.Printf("[网络] 解析服务器URL失败: %v", err)
return c.config.ServerURL
}
q := u.Query()
q.Set("agent_id", c.config.AgentID)
u.RawQuery = q.Encode()
return u.String()
}