Files
waf-platform/EdgeNode/internal/network-security/manager.go
2026-02-04 20:27:13 +08:00

136 lines
3.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright 2023 GoEdge CDN goedge.cdn@gmail.com. All rights reserved. Official site: https://goedge.cn .
//go:build plus && packet
package networksecurity
import (
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
teaconst "github.com/TeaOSLab/EdgeNode/internal/const"
"github.com/TeaOSLab/EdgeNode/internal/events"
"github.com/TeaOSLab/EdgeNode/internal/monitor"
"github.com/TeaOSLab/EdgeNode/internal/remotelogs"
"github.com/TeaOSLab/EdgeNode/internal/utils"
"github.com/TeaOSLab/EdgeNode/internal/utils/goman"
"github.com/TeaOSLab/EdgeNode/internal/utils/netpackets"
"github.com/iwind/TeaGo/Tea"
"github.com/iwind/TeaGo/maps"
"runtime"
"time"
)
var SharedManager = NewManager()
func init() {
if !teaconst.IsMain {
return
}
events.On(events.EventLoaded, func() {
nodeConfig, _ := nodeconfigs.SharedNodeConfig()
if nodeConfig != nil {
go SharedManager.Apply(nodeConfig.NetworkSecurityPolicy)
}
})
events.On(events.EventQuit, func() {
go SharedManager.Apply(nil)
})
goman.New(func() {
var ticker = time.NewTicker(1 * time.Minute)
for range ticker.C {
SharedManager.Upload()
}
})
}
type Manager struct {
listener *netpackets.Listener
isRunning bool
policy *nodeconfigs.NetworkSecurityPolicy
totalTCPPacketsMinutely uint64
totalUDPPacketsMinutely uint64
totalICMPPacketsMinutely uint64
}
func NewManager() *Manager {
return &Manager{}
}
// Apply 应用配置
// 非线程安全
func (this *Manager) Apply(policy *nodeconfigs.NetworkSecurityPolicy) {
if this.policy != nil && this.policy.IsSame(policy) {
return
}
this.policy = policy
if policy == nil ||
policy.Status == nodeconfigs.NetworkSecurityStatusOff ||
(policy.Status == nodeconfigs.NetworkSecurityStatusAuto && runtime.NumCPU() < 8) {
if this.listener != nil {
remotelogs.Println("NETWORK_SECURITY_MANAGER", "stop")
this.listener.Stop()
}
this.isRunning = false
return
}
if this.listener == nil {
this.listener = netpackets.NewListener()
// References:
// - https://biot.com/capstats/bpf.html
// - https://www.ibm.com/docs/en/qsip/7.4?topic=queries-berkeley-packet-filters
// - https://www.tcpdump.org/manpages/tcpdump.1.html
if Tea.IsTesting() || utils.IsDebugEnv() { // dev environment
this.listener.SetBPF("(tcp or udp or icmp) and not net 127 and not net ::1")
} else {
this.listener.SetBPF("(tcp or udp or icmp) and not src net 127 and not src net 192.168 and not src net 172.16 and not src net ::1 and not src net 10")
}
this.listener.AddFilter(this)
}
if !this.isRunning {
this.isRunning = true
remotelogs.Println("NETWORK_SECURITY_MANAGER", "start")
err := this.listener.Start() // long run function
if err != nil {
remotelogs.Error("NETWORK_SECURITY_MANAGER", "start listener failed: "+err.Error())
}
this.isRunning = false
}
}
func (this *Manager) FilterMeta(meta *netpackets.PacketMeta) {
switch meta.LayerType {
case netpackets.LayerTypeTCP:
// 这里不需要试用atomic因为数据不需要那么精确
this.totalTCPPacketsMinutely++
case netpackets.LayerTypeUDP:
this.totalUDPPacketsMinutely++
case netpackets.LayerTypeICMPv4, netpackets.LayerTypeICMPv6:
this.totalICMPPacketsMinutely++
}
}
func (this *Manager) Upload() {
if !this.isRunning {
return
}
monitor.SharedValueQueue.Add(nodeconfigs.NodeValueItemNetworkPackets, maps.Map{
"tcpInPPS": this.totalTCPPacketsMinutely / 60,
"udpInPPS": this.totalUDPPacketsMinutely / 60,
"icmpInPPS": this.totalICMPPacketsMinutely / 60,
})
this.totalTCPPacketsMinutely = 0
this.totalUDPPacketsMinutely = 0
this.totalICMPPacketsMinutely = 0
}