Files
beelzebub/tracer/tracer.go

151 lines
3.3 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 (
log "github.com/sirupsen/logrus"
"sync"
2022-05-19 23:20:20 +02:00
"time"
2022-06-04 17:14:46 +02:00
"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 string
Cookies string
UserAgent string
HostHTTPRequest string
Body string
HTTPMethod string
RequestURI string
Description 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()
}