Skip to content

Commit e40429e

Browse files
authored
Merge pull request #84 from satta/multi-forward
Implement selective event forwarding to multiple outputs
2 parents 077bf65 + bb35c0e commit e40429e

17 files changed

+418
-462
lines changed

cmd/fever/cmds/run.go

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,39 @@ func mainfunc(cmd *cobra.Command, args []string) {
140140
}()
141141
}
142142

143-
// Configure forwarding
144-
outputSocket := viper.GetString("output.socket")
145-
forward = (outputSocket != "")
146-
eventTypes := viper.GetStringSlice("forward.types")
147-
allTypes := viper.GetBool("forward.all")
148-
util.PrepareEventFilter(eventTypes, allTypes)
143+
// Get config from viper
144+
var multiForwardConf processing.MultiForwardConfiguration
145+
err = viper.Unmarshal(&multiForwardConf)
146+
if err != nil {
147+
log.Fatal(err)
148+
}
149+
// Keep supporting legacy config ("output" and "forward" sections)
150+
if len(multiForwardConf.Outputs) == 0 {
151+
log.Info("no multi-forwarder configuration, found, using legacy config")
152+
outSocketPath := viper.GetString("output.socket")
153+
if len(outSocketPath) > 0 {
154+
multiForwardConf.Outputs = make(map[string]processing.MultiForwardOutput)
155+
multiForwardConf.Outputs["default"] =
156+
processing.MultiForwardOutput{
157+
Socket: viper.GetString("output.socket"),
158+
All: viper.GetBool("forward.all"),
159+
Types: viper.GetStringSlice("forward.types"),
160+
}
161+
}
162+
} else {
163+
log.Info("found multi-forwarder configuration, ignoring legacy config")
164+
}
165+
166+
if len(multiForwardConf.Outputs) > 0 {
167+
forward = true
168+
}
169+
170+
if pse != nil {
171+
multiForwardConf.SubmitStats(pse)
172+
}
173+
multiFwdChan := make(chan types.Entry)
174+
reconnectTimes := viper.GetInt("reconnect-retries")
175+
multiForwardConf.Run(multiFwdChan, reconnectTimes)
149176

150177
// Optional profiling
151178
profileFile := viper.GetString("profile")
@@ -185,14 +212,10 @@ func mainfunc(cmd *cobra.Command, args []string) {
185212
s.Run(eventChan)
186213

187214
var forwardHandler processing.Handler
188-
reconnectTimes := viper.GetInt("reconnect-retries")
189215
// start forwarding
190216
if forward {
191-
forwardHandler = processing.MakeForwardHandler(int(reconnectTimes), outputSocket)
217+
forwardHandler = processing.MakeForwardHandler(multiFwdChan)
192218
fh := forwardHandler.(*processing.ForwardHandler)
193-
if pse != nil {
194-
fh.SubmitStats(pse)
195-
}
196219
rdns := viper.GetBool("active.rdns")
197220
if rdns {
198221
expiryPeriod := viper.GetDuration("active.rdns-cache-expiry")
@@ -202,7 +225,6 @@ func mainfunc(cmd *cobra.Command, args []string) {
202225
fh.RDNSHandler.EnableOnlyPrivateIPRanges()
203226
}
204227
}
205-
fh.Run()
206228

207229
stenosis := viper.GetBool("stenosis.enable")
208230
if stenosis {
@@ -236,12 +258,6 @@ func mainfunc(cmd *cobra.Command, args []string) {
236258

237259
addFields := viper.GetStringMapString("add-fields")
238260
fh.AddFields(addFields)
239-
240-
defer func() {
241-
c := make(chan bool)
242-
fh.Stop(c)
243-
<-c
244-
}()
245261
} else {
246262
// in this case we use a void handler that does nothing
247263
forwardHandler = processing.MakeVoidHandler()

fever.yaml

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,23 @@ input:
5454
# # Disables Redis pipelining.
5555
# nopipe: true
5656

57-
# Definition what event types to forward. Set 'all' to true to forward
58-
# everything received from Suricata, otherwise use the 'types' list to choose.
59-
# By default, we only forward alerts and stats events.
60-
forward:
61-
all: false
62-
types:
63-
- alert
64-
- stats
65-
66-
# Configuration for output of forwarded events (socket to e.g. Logstash).
67-
output:
68-
socket: /tmp/suri-forward.sock
57+
# Configure forwarding of events processed by FEVER, i.e. define what event
58+
# types to forward.
59+
multi-forward:
60+
# Set 'all' to true to forward everything received from Suricata, otherwise
61+
# use the 'types' list to choose. Example:
62+
# socketall:
63+
# socket: /tmp/out-all.sock
64+
# buffer-length: 100000
65+
# all: true
66+
# types: []
67+
socketalerts:
68+
socket: /tmp/suri-forward.sock
69+
all: false
70+
buffer-length: 1000
71+
types:
72+
- alert
73+
- stats
6974

7075
# Configuration for flow report submission.
7176
flowreport:

processing/bloom_handler.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ type BloomHandler struct {
3131
BloomFileIsCompressed bool
3232
DatabaseEventChan chan types.Entry
3333
ForwardHandler Handler
34-
DoForwardAlert bool
3534
AlertPrefix string
3635
Alertifier *util.Alertifier
3736
BlacklistIOCs map[string]struct{}
@@ -75,7 +74,6 @@ func MakeBloomHandler(iocBloom *bloom.BloomFilter,
7574
IocBloom: iocBloom,
7675
DatabaseEventChan: databaseChan,
7776
ForwardHandler: forwardHandler,
78-
DoForwardAlert: (util.ForwardAllEvents || util.AllowType("alert")),
7977
AlertPrefix: alertPrefix,
8078
Alertifier: util.MakeAlertifier(alertPrefix),
8179
BlacklistIOCs: make(map[string]struct{}),

processing/bloom_handler_test.go

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -278,9 +278,6 @@ func (h *CollectorHandler) GetEntries() map[string]bool {
278278
}
279279

280280
func TestBloomHandler(t *testing.T) {
281-
// make sure that alerts are forwarded
282-
util.PrepareEventFilter([]string{"alert"}, false)
283-
284281
// initalize Bloom filter and fill with 'interesting' values
285282
bf := bloom.Initialize(100000, 0.0000001)
286283
fillBloom(&bf)
@@ -394,9 +391,9 @@ func TestBloomHandler(t *testing.T) {
394391
e = makeBloomTLSEvent(s, ":::")
395392
bh.Consume(&e)
396393
case 3:
397-
f := fmt.Sprintf("%s", util.RndStringFromAlpha(6))
394+
f := util.RndStringFromAlpha(6)
398395
for bf.Check([]byte(f)) {
399-
f = fmt.Sprintf("%s", util.RndStringFromAlpha(6))
396+
f = util.RndStringFromAlpha(6)
400397
}
401398
e = makeBloomTLSEvent("foo.com", f)
402399
bh.Consume(&e)
@@ -695,8 +692,6 @@ func TestBloomHandlerURL(t *testing.T) {
695692
close(consumeWaitChan)
696693
}()
697694

698-
util.PrepareEventFilter([]string{"alert"}, false)
699-
700695
// initalize Bloom filter and fill with 'interesting' values
701696
bf := bloom.Initialize(100000, 0.0000001)
702697
bf.Add([]byte("/oddlyspecific"))
@@ -950,8 +945,6 @@ func TestBloomHandlerBlacklistedSkip(t *testing.T) {
950945
close(consumeWaitChan)
951946
}()
952947

953-
util.PrepareEventFilter([]string{"alert"}, false)
954-
955948
// handler to receive forwarded events
956949
fwhandler := &CollectorHandler{
957950
Entries: make(map[string]bool),
@@ -981,9 +974,6 @@ func TestBloomHandlerBlacklistedSkip(t *testing.T) {
981974
}
982975

983976
func TestBloomHandlerInvalidDNS(t *testing.T) {
984-
// make sure that alerts are forwarded
985-
util.PrepareEventFilter([]string{"alert"}, false)
986-
987977
// initalize Bloom filter and fill with 'interesting' values
988978
bf := bloom.Initialize(100000, 0.0000001)
989979

processing/flow_extractor_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ func makeFlowExtractorEvent(ipv6 bool) types.Entry {
3535
srcIP = fmt.Sprintf("10.0.0.%d", rand.Intn(50))
3636
destIP = fmt.Sprintf("10.0.0.%d", rand.Intn(50))
3737
} else {
38-
srcIP = fmt.Sprintf("2001:0db8:85a3:0000:0000:8a2e:0370:7334")
39-
destIP = fmt.Sprintf("2001:0db8:85a3:0000:0000:8a2e:0370:7334")
38+
srcIP = "2001:0db8:85a3:0000:0000:8a2e:0370:7334"
39+
destIP = "2001:0db8:85a3:0000:0000:8a2e:0370:7334"
4040
}
4141

4242
e := types.Entry{

0 commit comments

Comments
 (0)