在 Linux 环境增加自动配置 ICMP 权限的逻辑
This commit is contained in:
1 parent
087b4b4071
commit
d10fad98ba
3 files changed
+129
-29
No files matched your search
@@ -9,6 +9,7 @@ import (
|
||||
"syscall"
|
||||
|
||||
"github.com/dushixiang/pika/pkg/agent/config"
|
||||
"github.com/dushixiang/pika/pkg/agent/sysutil"
|
||||
"github.com/dushixiang/pika/pkg/agent/updater"
|
||||
"github.com/kardianos/service"
|
||||
)
|
||||
@@ -21,33 +22,53 @@ type program struct {
|
||||
cancel context.CancelFunc
|
||||
}
|
||||
|
||||
// Start 启动服务
|
||||
func (p *program) Start(s service.Service) error {
|
||||
log.Println("✅ Pika Agent 服务启动中...")
|
||||
|
||||
// 创建 context
|
||||
p.ctx, p.cancel = context.WithCancel(context.Background())
|
||||
// configureICMP 配置 ICMP 权限(抽取通用逻辑)
|
||||
func configureICMP() {
|
||||
if err := sysutil.ConfigureICMPPermissions(); err != nil {
|
||||
log.Printf("⚠️ 配置 ICMP 权限失败: %v", err)
|
||||
log.Println(" 提示: ICMP 监控可能需要 root 权限运行,或手动执行:")
|
||||
log.Println(" sudo sysctl -w net.ipv4.ping_group_range=\"0 2147483647\"")
|
||||
}
|
||||
}
|
||||
|
||||
// startAgent 启动 Agent 和自动更新(抽取通用逻辑)
|
||||
func startAgent(ctx context.Context, cfg *config.Config) *Agent {
|
||||
// 创建 Agent 实例
|
||||
p.agent = New(p.cfg)
|
||||
agent := New(cfg)
|
||||
|
||||
// 启动自动更新(如果启用)
|
||||
if p.cfg.AutoUpdate.Enabled {
|
||||
upd, err := updater.New(p.cfg, GetVersion())
|
||||
if cfg.AutoUpdate.Enabled {
|
||||
upd, err := updater.New(cfg, GetVersion())
|
||||
if err != nil {
|
||||
log.Printf("⚠️ 创建更新器失败: %v", err)
|
||||
} else {
|
||||
go upd.Start(p.ctx)
|
||||
go upd.Start(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
// 在后台启动 Agent
|
||||
go func() {
|
||||
if err := p.agent.Start(p.ctx); err != nil {
|
||||
if err := agent.Start(ctx); err != nil {
|
||||
log.Printf("⚠️ 探针运行出错: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
return agent
|
||||
}
|
||||
|
||||
// Start 启动服务
|
||||
func (p *program) Start(s service.Service) error {
|
||||
log.Println("✅ Pika Agent 服务启动中...")
|
||||
|
||||
// 初始化系统配置(Linux ICMP 权限等)
|
||||
configureICMP()
|
||||
|
||||
// 创建 context
|
||||
p.ctx, p.cancel = context.WithCancel(context.Background())
|
||||
|
||||
// 启动 Agent
|
||||
p.agent = startAgent(p.ctx, p.cfg)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -189,6 +210,9 @@ func (m *ServiceManager) Run() error {
|
||||
log.Printf(" 采集间隔: %v", m.cfg.GetCollectorInterval())
|
||||
log.Printf(" 心跳间隔: %v", m.cfg.GetHeartbeatInterval())
|
||||
|
||||
// 初始化系统配置(Linux ICMP 权限等)
|
||||
configureICMP()
|
||||
|
||||
// 创建 context
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
@@ -197,25 +221,8 @@ func (m *ServiceManager) Run() error {
|
||||
interrupt := make(chan os.Signal, 1)
|
||||
signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM)
|
||||
|
||||
// 创建 Agent 实例
|
||||
agent := New(m.cfg)
|
||||
|
||||
// 启动自动更新(如果启用)
|
||||
if m.cfg.AutoUpdate.Enabled {
|
||||
upd, err := updater.New(m.cfg, GetVersion())
|
||||
if err != nil {
|
||||
log.Printf("⚠️ 创建更新器失败: %v", err)
|
||||
} else {
|
||||
go upd.Start(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
// 启动 Agent
|
||||
go func() {
|
||||
if err := agent.Start(ctx); err != nil {
|
||||
log.Printf("⚠️ 探针运行出错: %v", err)
|
||||
}
|
||||
}()
|
||||
agent := startAgent(ctx, m.cfg)
|
||||
|
||||
// 等待中断信号
|
||||
<-interrupt
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
package sysutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ConfigureICMPPermissions 配置 ICMP 权限
|
||||
// 在 Linux 系统上,允许非特权用户发起 ICMP 请求
|
||||
// 使用 sync.Once 确保只执行一次
|
||||
func ConfigureICMPPermissions() error {
|
||||
return doConfigureICMPPermissions()
|
||||
}
|
||||
|
||||
// doConfigureICMPPermissions 实际执行配置
|
||||
func doConfigureICMPPermissions() error {
|
||||
const sysctlPath = "/proc/sys/net/ipv4/ping_group_range"
|
||||
|
||||
// 1. 先检查当前配置
|
||||
currentMin, currentMax, err := readPingGroupRange(sysctlPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("读取当前 ICMP 配置失败: %w", err)
|
||||
}
|
||||
|
||||
// 2. 检查是否已经满足要求 (范围包含 0 到 2147483647)
|
||||
if currentMin <= 0 && currentMax >= 2147483647 {
|
||||
log.Printf("✅ ICMP 权限已配置: net.ipv4.ping_group_range=%d %d", currentMin, currentMax)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 3. 需要配置,写入新值
|
||||
log.Printf("🔧 当前 ICMP 配置: net.ipv4.ping_group_range=%d %d (不满足要求)", currentMin, currentMax)
|
||||
log.Println(" 正在配置为: 0 2147483647")
|
||||
|
||||
if err := writePingGroupRange(sysctlPath, 0, 2147483647); err != nil {
|
||||
return fmt.Errorf("配置 ICMP 权限失败: %w", err)
|
||||
}
|
||||
|
||||
log.Println("✅ ICMP 权限配置成功: net.ipv4.ping_group_range=0 2147483647")
|
||||
return nil
|
||||
}
|
||||
|
||||
// readPingGroupRange 读取 ping_group_range 的当前值
|
||||
func readPingGroupRange(path string) (min, max int, err error) {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
// 格式: "min max\n"
|
||||
fields := strings.Fields(string(data))
|
||||
if len(fields) != 2 {
|
||||
return 0, 0, fmt.Errorf("无效的格式: %s", string(data))
|
||||
}
|
||||
|
||||
min, err = strconv.Atoi(fields[0])
|
||||
if err != nil {
|
||||
return 0, 0, fmt.Errorf("解析 min 值失败: %w", err)
|
||||
}
|
||||
|
||||
max, err = strconv.Atoi(fields[1])
|
||||
if err != nil {
|
||||
return 0, 0, fmt.Errorf("解析 max 值失败: %w", err)
|
||||
}
|
||||
|
||||
return min, max, nil
|
||||
}
|
||||
|
||||
// writePingGroupRange 写入新的 ping_group_range 值
|
||||
func writePingGroupRange(path string, min, max int) error {
|
||||
value := fmt.Sprintf("%d\t%d", min, max)
|
||||
if err := os.WriteFile(path, []byte(value), 0644); err != nil {
|
||||
// 检查是否是权限问题
|
||||
if os.IsPermission(err) {
|
||||
return fmt.Errorf("需要 root 权限才能配置 ICMP 权限: %w", err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
//go:build !linux
|
||||
// +build !linux
|
||||
|
||||
package sysutil
|
||||
|
||||
// ConfigureICMPPermissions 在非 Linux 平台上不需要配置
|
||||
func ConfigureICMPPermissions() error {
|
||||
// Windows 和 macOS 不需要特殊配置
|
||||
return nil
|
||||
}
|
||||
Reference in new issue
Block a user