2023-10-15 20:54:53 +02:00
|
|
|
// Package tracer is responsible for tracing the events that occur in the honeypots
|
2022-05-09 23:16:59 +02:00
|
|
|
package tracer
|
|
|
|
|
|
|
|
import (
|
2023-10-09 01:16:53 +02:00
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
"sync"
|
2022-05-19 23:20:20 +02:00
|
|
|
"time"
|
2022-06-04 17:14:46 +02:00
|
|
|
|
2023-03-31 20:03:42 +02:00
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
|
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
|
|
|
)
|
2022-05-09 23:16:59 +02:00
|
|
|
|
2023-10-15 20:54:53 +02:00
|
|
|
// Workers is the number of workers that will
|
2023-08-30 23:04:35 +02:00
|
|
|
const Workers = 5
|
|
|
|
|
2022-05-09 23:16:59 +02:00
|
|
|
type Event struct {
|
2022-05-19 23:20:20 +02:00
|
|
|
DateTime string
|
2022-05-10 22:50:29 +02:00
|
|
|
RemoteAddr string
|
2022-05-17 23:32:00 +02:00
|
|
|
Protocol string
|
2022-05-10 22:50:29 +02:00
|
|
|
Command string
|
2023-04-14 22:35:11 +02:00
|
|
|
CommandOutput string
|
2022-05-17 23:32:00 +02:00
|
|
|
Status string
|
2022-05-10 22:50:29 +02:00
|
|
|
Msg string
|
|
|
|
ID string
|
|
|
|
Environ string
|
|
|
|
User string
|
|
|
|
Password string
|
|
|
|
Client string
|
2022-05-29 16:18:40 +02:00
|
|
|
Headers string
|
|
|
|
Cookies string
|
2022-05-10 22:50:29 +02:00
|
|
|
UserAgent string
|
|
|
|
HostHTTPRequest string
|
|
|
|
Body string
|
|
|
|
HTTPMethod string
|
|
|
|
RequestURI string
|
2022-05-31 22:39:56 +02:00
|
|
|
Description string
|
2022-05-09 23:16:59 +02:00
|
|
|
}
|
|
|
|
|
2023-06-26 11:55:49 -05:00
|
|
|
type (
|
|
|
|
Protocol int
|
2023-08-30 23:04:35 +02:00
|
|
|
Status int
|
2023-06-26 11:55:49 -05:00
|
|
|
)
|
2022-05-10 22:50:29 +02:00
|
|
|
|
|
|
|
const (
|
|
|
|
HTTP Protocol = iota
|
|
|
|
SSH
|
2022-07-03 17:15:38 +02:00
|
|
|
TCP
|
2022-05-10 22:50:29 +02:00
|
|
|
)
|
|
|
|
|
2023-10-09 01:16:53 +02:00
|
|
|
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]
|
|
|
|
}
|
2023-03-31 20:03:42 +02:00
|
|
|
|
|
|
|
type Strategy func(event Event)
|
|
|
|
|
|
|
|
type Tracer interface {
|
|
|
|
TraceEvent(event Event)
|
|
|
|
}
|
|
|
|
|
|
|
|
type tracer struct {
|
2023-10-09 01:16:53 +02:00
|
|
|
strategy Strategy
|
|
|
|
eventsChan chan Event
|
|
|
|
eventsTotal prometheus.Counter
|
|
|
|
eventsSSHTotal prometheus.Counter
|
|
|
|
eventsTCPTotal prometheus.Counter
|
|
|
|
eventsHTTPTotal prometheus.Counter
|
2023-03-31 20:03:42 +02:00
|
|
|
}
|
|
|
|
|
2023-10-09 01:16:53 +02:00
|
|
|
var lock = &sync.Mutex{}
|
|
|
|
var singleton *tracer
|
|
|
|
|
2023-10-15 20:54:53 +02:00
|
|
|
func GetInstance(defaultStrategy Strategy) *tracer {
|
2023-10-09 01:16:53 +02:00
|
|
|
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{
|
2023-10-15 20:54:53 +02:00
|
|
|
strategy: defaultStrategy,
|
2023-10-09 01:16:53 +02:00
|
|
|
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",
|
|
|
|
}),
|
|
|
|
}
|
2023-08-30 23:04:35 +02:00
|
|
|
|
2023-10-09 01:16:53 +02:00
|
|
|
for i := 0; i < Workers; i++ {
|
|
|
|
go func(i int) {
|
2023-10-15 20:54:53 +02:00
|
|
|
log.Debug("Trace worker: ", i)
|
2023-10-09 01:16:53 +02:00
|
|
|
for event := range singleton.eventsChan {
|
|
|
|
singleton.strategy(event)
|
|
|
|
}
|
|
|
|
}(i)
|
2023-08-30 23:04:35 +02:00
|
|
|
}
|
2023-10-09 01:16:53 +02:00
|
|
|
}
|
2023-03-31 20:03:42 +02:00
|
|
|
}
|
2023-08-30 23:04:35 +02:00
|
|
|
|
2023-10-09 01:16:53 +02:00
|
|
|
return singleton
|
2023-08-30 23:04:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (tracer *tracer) setStrategy(strategy Strategy) {
|
|
|
|
tracer.strategy = strategy
|
2023-03-31 20:03:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (tracer *tracer) TraceEvent(event Event) {
|
|
|
|
event.DateTime = time.Now().UTC().Format(time.RFC3339)
|
|
|
|
|
2023-08-30 23:04:35 +02:00
|
|
|
tracer.eventsChan <- event
|
2023-03-31 20:03:42 +02:00
|
|
|
|
2023-10-09 01:16:53 +02:00
|
|
|
tracer.updatePrometheusCounters(event.Protocol)
|
|
|
|
}
|
2023-03-31 20:03:42 +02:00
|
|
|
|
2023-10-09 01:16:53 +02:00
|
|
|
func (tracer *tracer) updatePrometheusCounters(protocol string) {
|
|
|
|
switch protocol {
|
2023-03-31 20:03:42 +02:00
|
|
|
case HTTP.String():
|
2023-10-09 01:16:53 +02:00
|
|
|
tracer.eventsHTTPTotal.Inc()
|
2023-03-31 20:03:42 +02:00
|
|
|
case SSH.String():
|
2023-10-09 01:16:53 +02:00
|
|
|
tracer.eventsSSHTotal.Inc()
|
2023-03-31 20:03:42 +02:00
|
|
|
case TCP.String():
|
2023-10-09 01:16:53 +02:00
|
|
|
tracer.eventsTCPTotal.Inc()
|
2023-03-31 20:03:42 +02:00
|
|
|
}
|
2023-10-09 01:16:53 +02:00
|
|
|
tracer.eventsTotal.Inc()
|
2023-03-31 20:03:42 +02:00
|
|
|
}
|