136 lines
3.5 KiB
Go
136 lines
3.5 KiB
Go
// 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
|
||
}
|