Add network activity map overlay and configurable monitoring filters
This commit is contained in:
76
traffic_monitoring.go
Normal file
76
traffic_monitoring.go
Normal file
@@ -0,0 +1,76 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Domain/path restrictions describe HTTP probes only. An IP-only rule also
|
||||
// matches conntrack initiators; a destination match never hides other clients.
|
||||
type MonitoringRule struct {
|
||||
IP string `json:"ip"`
|
||||
Domain string `json:"domain,omitempty"`
|
||||
PathPrefix string `json:"pathPrefix,omitempty"`
|
||||
}
|
||||
|
||||
func validateMonitoringRules(rules []MonitoringRule) ([]MonitoringRule, error) {
|
||||
if len(rules) > 32 {
|
||||
return nil, fmt.Errorf("Не более 32 правил мониторинга")
|
||||
}
|
||||
result := make([]MonitoringRule, 0, len(rules))
|
||||
for i, r := range rules {
|
||||
ip := net.ParseIP(strings.TrimSpace(r.IP))
|
||||
if ip == nil {
|
||||
return nil, fmt.Errorf("Правило %d: нужен точный IPv4/IPv6-адрес", i+1)
|
||||
}
|
||||
r.IP = ip.String()
|
||||
r.Domain = strings.ToLower(strings.TrimSpace(r.Domain))
|
||||
r.PathPrefix = strings.TrimSpace(r.PathPrefix)
|
||||
if len(r.Domain) > 253 || strings.ContainsAny(r.Domain, " /|\t\r\n") || len(r.PathPrefix) > 256 || strings.ContainsAny(r.PathPrefix, "|\r\n") || (r.PathPrefix != "" && !strings.HasPrefix(r.PathPrefix, "/")) {
|
||||
return nil, fmt.Errorf("Правило %d: проверьте домен и префикс пути (начинается с /)", i+1)
|
||||
}
|
||||
result = append(result, r)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
func isMonitoringRequest(e TrafficEvent, rules []MonitoringRule) bool {
|
||||
if e.Kind != "request" {
|
||||
return false
|
||||
}
|
||||
for _, r := range rules {
|
||||
if e.IP == r.IP && (r.Domain == "" || strings.EqualFold(e.Domain, r.Domain)) && strings.HasPrefix(e.Path, r.PathPrefix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
func isMonitoringFlow(f NetworkFlow, rules []MonitoringRule) bool {
|
||||
for _, r := range rules {
|
||||
if net.ParseIP(f.Source).Equal(net.ParseIP(r.IP)) && r.Domain == "" && r.PathPrefix == "" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
func monitoringSQL(rules []MonitoringRule) (string, []any) {
|
||||
var parts []string
|
||||
var args []any
|
||||
for _, r := range rules {
|
||||
p := "(ip=?"
|
||||
args = append(args, r.IP)
|
||||
if r.Domain != "" {
|
||||
p += " AND lower(domain)=?"
|
||||
args = append(args, r.Domain)
|
||||
}
|
||||
if r.PathPrefix != "" {
|
||||
p += " AND substr(path,1,length(?))=?"
|
||||
args = append(args, r.PathPrefix, r.PathPrefix)
|
||||
}
|
||||
parts = append(parts, p+")")
|
||||
}
|
||||
if len(parts) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
return " AND NOT (kind='request' AND (" + strings.Join(parts, " OR ") + "))", args
|
||||
}
|
||||
Reference in New Issue
Block a user