Files
beelzebub/tracer/tracer.go

155 lines
3.4 KiB
Go
Raw Normal View History

// Package tracer is responsible for tracing the events that occur in the honeypots
2022-05-09 23:16:59 +02:00
package tracer
import (
"sync"
2022-05-19 23:20:20 +02:00
"time"
2022-06-04 17:14:46 +02:00
log "github.com/sirupsen/logrus"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)
2022-05-09 23:16:59 +02:00
// Workers is the number of workers that will
const Workers = 5
2022-05-09 23:16:59 +02:00
type Event struct {
2022-05-19 23:20:20 +02:00
DateTime string
RemoteAddr string
2022-05-17 23:32:00 +02:00
Protocol string
Command string
CommandOutput string
2022-05-17 23:32:00 +02:00
Status string
Msg string
ID string
Environ string
User string
Password string
Client string
Headers map[string][]string
Cookies string
UserAgent string
HostHTTPRequest string
Body string
HTTPMethod string
RequestURI string
Description string
SourceIp string
SourcePort string
TLSServerName string
2022-05-09 23:16:59 +02:00
}
type (
Protocol int
Status int
)
const (
HTTP Protocol = iota
SSH
2022-07-03 17:15:38 +02:00
TCP
)
func (protocol Protocol) String() string {
return [...]string{"HTTP", "SSH", "TCP"}[protocol]
2022-05-17 23:32:00 +02:00
}
2022-05-09 23:16:59 +02:00
const (
Start Status = iota
End
Stateless
Interaction
)
func (status Status) String() string {
return [...]string{"Start", "End", "Stateless", "Interaction"}[status]
}
type Strategy func(event Event)
type Tracer interface {
TraceEvent(event Event)
}
type tracer struct {
strategy Strategy
eventsChan chan Event
eventsTotal prometheus.Counter
eventsSSHTotal prometheus.Counter
eventsTCPTotal prometheus.Counter
eventsHTTPTotal prometheus.Counter
}
var lock = &sync.Mutex{}
var singleton *tracer
func GetInstance(defaultStrategy Strategy) *tracer {
if singleton == nil {
lock.Lock()
defer lock.Unlock()
// This is to prevent expensive lock operations every time the GetInstance method is called
if singleton == nil {
singleton = &tracer{
strategy: defaultStrategy,
eventsChan: make(chan Event, Workers),
eventsTotal: promauto.NewCounter(prometheus.CounterOpts{
Namespace: "beelzebub",
Name: "events_total",
Help: "The total number of events",
}),
eventsSSHTotal: promauto.NewCounter(prometheus.CounterOpts{
Namespace: "beelzebub",
Name: "ssh_events_total",
Help: "The total number of SSH events",
}),
eventsTCPTotal: promauto.NewCounter(prometheus.CounterOpts{
Namespace: "beelzebub",
Name: "tcp_events_total",
Help: "The total number of TCP events",
}),
eventsHTTPTotal: promauto.NewCounter(prometheus.CounterOpts{
Namespace: "beelzebub",
Name: "http_events_total",
Help: "The total number of HTTP events",
}),
}
for i := 0; i < Workers; i++ {
go func(i int) {
log.Debug("Trace worker: ", i)
for event := range singleton.eventsChan {
singleton.strategy(event)
}
}(i)
}
}
}
return singleton
}
func (tracer *tracer) setStrategy(strategy Strategy) {
tracer.strategy = strategy
}
func (tracer *tracer) TraceEvent(event Event) {
event.DateTime = time.Now().UTC().Format(time.RFC3339)
tracer.eventsChan <- event
tracer.updatePrometheusCounters(event.Protocol)
}
func (tracer *tracer) updatePrometheusCounters(protocol string) {
switch protocol {
case HTTP.String():
tracer.eventsHTTPTotal.Inc()
case SSH.String():
tracer.eventsSSHTotal.Inc()
case TCP.String():
tracer.eventsTCPTotal.Inc()
}
tracer.eventsTotal.Inc()
}