Skip to content

Commit

Permalink
Feat: beelzebub cloud integrations (#117)
Browse files Browse the repository at this point in the history
* improve beelzebub cloud integration

* refactoring cloud integration, fix unit test

* add unit test get honeypots

* improve code coverage
  • Loading branch information
mariocandela authored Aug 1, 2024
1 parent cd28487 commit a1e9673
Show file tree
Hide file tree
Showing 12 changed files with 276 additions and 50 deletions.
16 changes: 16 additions & 0 deletions builder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"github.com/mariocandela/beelzebub/v3/parser"
"github.com/mariocandela/beelzebub/v3/plugins"
"github.com/mariocandela/beelzebub/v3/protocols"
"github.com/mariocandela/beelzebub/v3/protocols/strategies"
"github.com/mariocandela/beelzebub/v3/tracer"
Expand Down Expand Up @@ -112,6 +113,21 @@ Honeypot Framework, happy hacking!`)
// Init Tracer strategies, and set the trace strategy default HTTP
protocolManager := protocols.InitProtocolManager(b.traceStrategy, hypertextTransferProtocolStrategy)

if b.beelzebubCoreConfigurations.Core.BeelzebubCloud.Enabled {
conf := b.beelzebubCoreConfigurations.Core.BeelzebubCloud

beelzebubCloud := plugins.InitBeelzebubCloud(conf.URI, conf.AuthToken)

if honeypotsConfiguration, err := beelzebubCloud.GetHoneypotsConfigurations(); err != nil {
return err
} else {
if len(honeypotsConfiguration) == 0 {
return errors.New("No honeypots configuration found")
}
b.beelzebubServicesConfiguration = honeypotsConfiguration
}
}

for _, beelzebubServiceConfiguration := range b.beelzebubServicesConfiguration {
switch beelzebubServiceConfiguration.Protocol {
case "http":
Expand Down
4 changes: 2 additions & 2 deletions builder/director.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func (d *Director) BuildBeelzebub(beelzebubCoreConfigurations *parser.BeelzebubC
}
}

if beelzebubCoreConfigurations.Core.Tracings.BeelzebubCloud.Enabled {
if beelzebubCoreConfigurations.Core.BeelzebubCloud.Enabled {
d.builder.setTraceStrategy(d.beelzebubCloudStrategy)
}

Expand All @@ -58,7 +58,7 @@ func (d *Director) beelzebubCloudStrategy(event tracer.Event) {
"event": event,
}).Info("New Event")

conf := d.builder.beelzebubCoreConfigurations.Core.Tracings.BeelzebubCloud
conf := d.builder.beelzebubCoreConfigurations.Core.BeelzebubCloud

beelzebubCloud := plugins.InitBeelzebubCloud(conf.URI, conf.AuthToken)

Expand Down
9 changes: 4 additions & 5 deletions configurations/beelzebub.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@ core:
rabbit-mq:
enabled: false
uri: ""
beelzebub-cloud:
enabled: false
uri: ""
auth-token: ""
prometheus:
path: "/metrics"
port: ":2112"

beelzebub-cloud:
enabled: false
uri: ""
auth-token: ""
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ services:
- "22:22"
- "2222:2222"
- "8080:8080"
- "8081:8081"
- "80:80"
- "3306:3306"
- "2112:2112" # Prometheus openmetrics
Expand Down
22 changes: 5 additions & 17 deletions parser/configurations_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package parser

import (
"fmt"
"github.com/mariocandela/beelzebub/v3/plugins"
"os"
"path/filepath"
"strings"
Expand All @@ -15,9 +14,10 @@ import (
// BeelzebubCoreConfigurations is the struct that contains the configurations of the core
type BeelzebubCoreConfigurations struct {
Core struct {
Logging Logging `yaml:"logging"`
Tracings Tracings `yaml:"tracings"`
Prometheus Prometheus `yaml:"prometheus"`
Logging Logging `yaml:"logging"`
Tracings Tracings `yaml:"tracings"`
Prometheus Prometheus `yaml:"prometheus"`
BeelzebubCloud BeelzebubCloud `yaml:"beelzebub-cloud"`
}
}

Expand All @@ -31,8 +31,7 @@ type Logging struct {

// Tracings is the struct that contains the configurations of the tracings
type Tracings struct {
RabbitMQ `yaml:"rabbit-mq"`
BeelzebubCloud `yaml:"beelzebub-cloud"`
RabbitMQ `yaml:"rabbit-mq"`
}

type BeelzebubCloud struct {
Expand All @@ -55,17 +54,6 @@ type Plugin struct {
LLMModel string `yaml:"llmModel"`
}

func FromString(llmModel string) (plugins.LLMModel, error) {
switch llmModel {
case "llama3":
return plugins.LLAMA3, nil
case "gpt4-o":
return plugins.GPT4O, nil
default:
return -1, fmt.Errorf("model %s not found", llmModel)
}
}

// BeelzebubServiceConfiguration is the struct that contains the configurations of the honeypot service
type BeelzebubServiceConfiguration struct {
ApiVersion string `yaml:"apiVersion"`
Expand Down
28 changes: 7 additions & 21 deletions parser/configurations_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package parser

import (
"errors"
"github.com/mariocandela/beelzebub/v3/plugins"
"os"
"testing"

Expand All @@ -21,10 +20,10 @@ core:
rabbit-mq:
enabled: true
uri: "amqp://user:password@localhost/"
beelzebub-cloud:
enabled: true
uri: "amqp://user:password@localhost/"
auth-token: "iejfdjsl-aosdajosoidaj-dunfkjnfkjsdnkn"`)
beelzebub-cloud:
enabled: true
uri: "amqp://user:password@localhost/"
auth-token: "iejfdjsl-aosdajosoidaj-dunfkjnfkjsdnkn"`)
return configurationsCoreBytes, nil
}

Expand Down Expand Up @@ -95,9 +94,9 @@ func TestReadConfigurationsCoreValid(t *testing.T) {
assert.Equal(t, coreConfigurations.Core.Logging.LogsPath, "./logs")
assert.Equal(t, coreConfigurations.Core.Tracings.RabbitMQ.Enabled, true)
assert.Equal(t, coreConfigurations.Core.Tracings.RabbitMQ.URI, "amqp://user:password@localhost/")
assert.Equal(t, coreConfigurations.Core.Tracings.BeelzebubCloud.Enabled, true)
assert.Equal(t, coreConfigurations.Core.Tracings.BeelzebubCloud.URI, "amqp://user:password@localhost/")
assert.Equal(t, coreConfigurations.Core.Tracings.BeelzebubCloud.AuthToken, "iejfdjsl-aosdajosoidaj-dunfkjnfkjsdnkn")
assert.Equal(t, coreConfigurations.Core.BeelzebubCloud.Enabled, true)
assert.Equal(t, coreConfigurations.Core.BeelzebubCloud.URI, "amqp://user:password@localhost/")
assert.Equal(t, coreConfigurations.Core.BeelzebubCloud.AuthToken, "iejfdjsl-aosdajosoidaj-dunfkjnfkjsdnkn")
}

func TestReadConfigurationsServicesFail(t *testing.T) {
Expand Down Expand Up @@ -186,16 +185,3 @@ func TestReadFileBytesByFilePath(t *testing.T) {

assert.Equal(t, "", string(bytes))
}

func TestFromString(t *testing.T) {
model, err := FromString("llama3")
assert.Nil(t, err)
assert.Equal(t, plugins.LLAMA3, model)

model, err = FromString("gpt4-o")
assert.Nil(t, err)
assert.Equal(t, plugins.GPT4O, model)

model, err = FromString("beelzebub-model")
assert.Errorf(t, err, "model beelzebub-model not found")
}
54 changes: 53 additions & 1 deletion plugins/beelzebub-cloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ package plugins
import (
"encoding/json"
"errors"
"fmt"
"github.com/go-resty/resty/v2"
"github.com/mariocandela/beelzebub/v3/parser"
"github.com/mariocandela/beelzebub/v3/tracer"
log "github.com/sirupsen/logrus"
"gopkg.in/yaml.v3"
)

type beelzebubCloud struct {
Expand All @@ -14,6 +17,13 @@ type beelzebubCloud struct {
client *resty.Client
}

type HoneypotConfigResponseDTO struct {
ID string `json:"id"`
Config string `json:"config"`
TokenID string `json:"tokenId"`
LastUpdatedOn string `json:"lastUpdatedOn"`
}

func InitBeelzebubCloud(uri, authToken string) *beelzebubCloud {
return &beelzebubCloud{
URI: uri,
Expand All @@ -36,7 +46,8 @@ func (beelzebubCloud *beelzebubCloud) SendEvent(event tracer.Event) (bool, error
SetHeader("Content-Type", "application/json").
SetBody(requestJson).
SetHeader("Authorization", beelzebubCloud.AuthToken).
Post(beelzebubCloud.URI)
SetResult(&tracer.Event{}).
Post(fmt.Sprintf("%s/events", beelzebubCloud.URI))

log.Debug(response)

Expand All @@ -46,3 +57,44 @@ func (beelzebubCloud *beelzebubCloud) SendEvent(event tracer.Event) (bool, error

return response.StatusCode() == 200, nil
}

func (beelzebubCloud *beelzebubCloud) GetHoneypotsConfigurations() ([]parser.BeelzebubServiceConfiguration, error) {
if beelzebubCloud.AuthToken == "" {
return nil, errors.New("authToken is empty")
}

response, err := beelzebubCloud.client.R().
SetHeader("Content-Type", "application/json").
SetHeader("Authorization", beelzebubCloud.AuthToken).
SetResult([]HoneypotConfigResponseDTO{}).
Get(fmt.Sprintf("%s/honeypots", beelzebubCloud.URI))

if err != nil {
return nil, err
}

if response.StatusCode() != 200 {
return nil, errors.New(fmt.Sprintf("Response code: %v, error: %s", response.StatusCode(), string(response.Body())))
}

var honeypotsConfig []HoneypotConfigResponseDTO

if err = json.Unmarshal(response.Body(), &honeypotsConfig); err != nil {
return nil, err
}

var servicesConfiguration = make([]parser.BeelzebubServiceConfiguration, 0)

for _, honeypotConfig := range honeypotsConfig {
var honeypotsConfig parser.BeelzebubServiceConfiguration

if err = yaml.Unmarshal([]byte(honeypotConfig.Config), &honeypotsConfig); err != nil {
return nil, err
}
servicesConfiguration = append(servicesConfiguration, honeypotsConfig)
}

log.Debug(servicesConfiguration)

return servicesConfiguration, nil
}
Loading

0 comments on commit a1e9673

Please sign in to comment.