Skip to content

Commit 38510ac

Browse files
authored
move cti expr helper to pkg/cticlient (#3696)
* move cti expr helper to pkg/cticlient * move cti expr helper to pkg/cticlient/ctiexpr thus removing the extra dependency on pkg/database which made the plugin binaries double in size from 1.6.3 to 1.6.4
1 parent 88e3b9b commit 38510ac

File tree

6 files changed

+133
-107
lines changed

6 files changed

+133
-107
lines changed

cmd/crowdsec-cli/clinotifications/notifications.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
3131
"github.com/crowdsecurity/crowdsec/pkg/csplugin"
3232
"github.com/crowdsecurity/crowdsec/pkg/csprofiles"
33+
"github.com/crowdsecurity/crowdsec/pkg/cticlient/ctiexpr"
3334
"github.com/crowdsecurity/crowdsec/pkg/database"
3435
"github.com/crowdsecurity/crowdsec/pkg/exprhelpers"
3536
"github.com/crowdsecurity/crowdsec/pkg/models"
@@ -291,7 +292,7 @@ func (cli *cliNotifications) newTestCmd() *cobra.Command {
291292

292293
if cfg.API.CTI != nil && cfg.API.CTI.Enabled != nil && *cfg.API.CTI.Enabled {
293294
log.Infof("Crowdsec CTI helper enabled")
294-
if err := exprhelpers.InitCrowdsecCTI(cfg.API.CTI.Key, cfg.API.CTI.CacheTimeout, cfg.API.CTI.CacheSize, cfg.API.CTI.LogLevel); err != nil {
295+
if err := ctiexpr.InitCrowdsecCTI(cfg.API.CTI.Key, cfg.API.CTI.CacheTimeout, cfg.API.CTI.CacheSize, cfg.API.CTI.LogLevel); err != nil {
295296
log.Errorf("failed to init crowdsec cti: %s", err)
296297
}
297298
}
@@ -419,7 +420,7 @@ cscli notifications reinject <alert_id> -a '{"remediation": true,"scenario":"not
419420

420421
if cfg.API.CTI != nil && cfg.API.CTI.Enabled != nil && *cfg.API.CTI.Enabled {
421422
log.Infof("Crowdsec CTI helper enabled")
422-
if err := exprhelpers.InitCrowdsecCTI(cfg.API.CTI.Key, cfg.API.CTI.CacheTimeout, cfg.API.CTI.CacheSize, cfg.API.CTI.LogLevel); err != nil {
423+
if err := ctiexpr.InitCrowdsecCTI(cfg.API.CTI.Key, cfg.API.CTI.CacheTimeout, cfg.API.CTI.CacheSize, cfg.API.CTI.LogLevel); err != nil {
423424
log.Errorf("failed to init crowdsec cti: %s", err)
424425
}
425426
}

cmd/crowdsec/serve.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717

1818
"github.com/crowdsecurity/crowdsec/pkg/apiclient"
1919
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
20+
"github.com/crowdsecurity/crowdsec/pkg/cticlient/ctiexpr"
2021
"github.com/crowdsecurity/crowdsec/pkg/cwhub"
2122
"github.com/crowdsecurity/crowdsec/pkg/database"
2223
"github.com/crowdsecurity/crowdsec/pkg/exprhelpers"
@@ -323,16 +324,20 @@ func HandleSignals(cConfig *csconfig.Config) error {
323324
if err == nil {
324325
log.Warning("Crowdsec service shutting down")
325326
}
327+
326328
if cConfig.API != nil && cConfig.API.Client != nil && cConfig.API.Client.UnregisterOnExit {
327329
log.Warning("Unregistering watcher")
330+
328331
lapiClient, err := apiclient.GetLAPIClient()
329332
if err != nil {
330333
return err
331334
}
335+
332336
_, err = lapiClient.Auth.UnregisterWatcher(context.TODO())
333337
if err != nil {
334338
return fmt.Errorf("failed to unregister watcher: %w", err)
335339
}
340+
336341
log.Warning("Watcher unregistered")
337342
}
338343

@@ -373,7 +378,7 @@ func Serve(cConfig *csconfig.Config, agentReady chan bool) error {
373378
if cConfig.API.CTI != nil && cConfig.API.CTI.Enabled != nil && *cConfig.API.CTI.Enabled {
374379
log.Infof("Crowdsec CTI helper enabled")
375380

376-
if err := exprhelpers.InitCrowdsecCTI(cConfig.API.CTI.Key, cConfig.API.CTI.CacheTimeout, cConfig.API.CTI.CacheSize, cConfig.API.CTI.LogLevel); err != nil {
381+
if err := ctiexpr.InitCrowdsecCTI(cConfig.API.CTI.Key, cConfig.API.CTI.CacheTimeout, cConfig.API.CTI.CacheSize, cConfig.API.CTI.LogLevel); err != nil {
377382
return fmt.Errorf("failed to init crowdsec cti: %w", err)
378383
}
379384
}

pkg/csplugin/helpers.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77

88
log "github.com/sirupsen/logrus"
99

10-
"github.com/crowdsecurity/crowdsec/pkg/exprhelpers"
10+
"github.com/crowdsecurity/crowdsec/pkg/cticlient/ctiexpr"
1111
"github.com/crowdsecurity/crowdsec/pkg/models"
1212
)
1313

@@ -24,7 +24,7 @@ var helpers = template.FuncMap{
2424
return metaValues
2525
},
2626
"CrowdsecCTI": func(x string) any {
27-
ret, err := exprhelpers.CrowdsecCTI(x)
27+
ret, err := ctiexpr.CrowdsecCTI(x)
2828
if err != nil {
2929
log.Warningf("error while calling CrowdsecCTI : %s", err)
3030
}

pkg/exprhelpers/crowdsec_cti.go renamed to pkg/cticlient/ctiexpr/expr.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package exprhelpers
1+
package ctiexpr
22

33
import (
44
"errors"
@@ -34,30 +34,39 @@ func InitCrowdsecCTI(key *string, ttl *time.Duration, size *int, logLevel *log.L
3434
log.Warningf("CTI API key not set or empty, CTI will not be available")
3535
return cticlient.ErrDisabled
3636
}
37+
3738
CTIApiKey = *key
39+
3840
if size == nil {
3941
size = new(int)
4042
*size = 1000
4143
}
44+
4245
if ttl == nil {
4346
ttl = new(time.Duration)
4447
*ttl = 5 * time.Minute
4548
}
49+
4650
clog := log.New()
4751
if err := types.ConfigureLogger(clog, logLevel); err != nil {
4852
return fmt.Errorf("while configuring datasource logger: %w", err)
4953
}
54+
5055
subLogger := clog.WithField("type", "crowdsec-cti")
56+
5157
CrowdsecCTIInitCache(*size, *ttl)
58+
5259
ctiClient = cticlient.NewCrowdsecCTIClient(cticlient.WithAPIKey(CTIApiKey), cticlient.WithLogger(subLogger))
5360
CTIApiEnabled = true
61+
5462
return nil
5563
}
5664

5765
func ShutdownCrowdsecCTI() {
5866
if CTICache != nil {
5967
CTICache.Purge()
6068
}
69+
6170
CTIApiKey = ""
6271
CTIApiEnabled = false
6372
}
@@ -76,31 +85,39 @@ func CrowdsecCTIInitCache(size int, ttl time.Duration) {
7685
// func CrowdsecCTI(ip string) (*cticlient.SmokeItem, error) {
7786
func CrowdsecCTI(params ...any) (any, error) {
7887
var ip string
88+
7989
if !CTIApiEnabled {
8090
return &cticlient.SmokeItem{}, cticlient.ErrDisabled
8191
}
92+
8293
var ok bool
94+
8395
if ip, ok = params[0].(string); !ok {
8496
return &cticlient.SmokeItem{}, fmt.Errorf("invalid type for ip : %T", params[0])
8597
}
8698

8799
if val, err := CTICache.Get(ip); err == nil && val != nil {
88100
ctiClient.Logger.Debugf("cti cache fetch for %s", ip)
101+
89102
ret, ok := val.(*cticlient.SmokeItem)
90103
if ok {
91104
return ret, nil
92105
}
106+
93107
ctiClient.Logger.Warningf("CrowdsecCTI: invalid type in cache, removing")
108+
94109
CTICache.Remove(ip)
95110
}
96111

97112
if !CTIBackOffUntil.IsZero() && time.Now().Before(CTIBackOffUntil) {
98-
//ctiClient.Logger.Warningf("Crowdsec CTI client is in backoff mode, ending in %s", time.Until(CTIBackOffUntil))
113+
// ctiClient.Logger.Warningf("Crowdsec CTI client is in backoff mode, ending in %s", time.Until(CTIBackOffUntil))
99114
return &cticlient.SmokeItem{}, cticlient.ErrLimit
100115
}
101116

102117
ctiClient.Logger.Infof("cti call for %s", ip)
118+
103119
before := time.Now()
120+
104121
ctiResp, err := ctiClient.GetIPInfo(ip)
105122
ctiClient.Logger.Debugf("request for %s took %v", ip, time.Since(before))
106123
if err != nil {

pkg/exprhelpers/crowdsec_cti_test.go renamed to pkg/cticlient/ctiexpr/expr_test.go

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package exprhelpers
1+
package ctiexpr
22

33
import (
44
"bytes"
@@ -18,8 +18,18 @@ import (
1818
"github.com/crowdsecurity/crowdsec/pkg/cticlient"
1919
)
2020

21+
const validApiKey = "my-api-key"
22+
23+
// RoundTripFunc .
24+
type RoundTripFunc func(req *http.Request) *http.Response
25+
26+
// RoundTrip .
27+
func (f RoundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) {
28+
return f(req), nil
29+
}
30+
2131
var sampledata = map[string]cticlient.SmokeItem{
22-
//1.2.3.4 is a known false positive
32+
// 1.2.3.4 is a known false positive
2333
"1.2.3.4": {
2434
Ip: "1.2.3.4",
2535
Classifications: cticlient.CTIClassifications{
@@ -31,7 +41,7 @@ var sampledata = map[string]cticlient.SmokeItem{
3141
},
3242
},
3343
},
34-
//1.2.3.5 is a known bad-guy, and part of FIRE
44+
// 1.2.3.5 is a known bad-guy, and part of FIRE
3545
"1.2.3.5": {
3646
Ip: "1.2.3.5",
3747
Classifications: cticlient.CTIClassifications{
@@ -44,7 +54,7 @@ var sampledata = map[string]cticlient.SmokeItem{
4454
},
4555
},
4656
},
47-
//1.2.3.6 is a bad guy (high bg noise), but not in FIRE
57+
// 1.2.3.6 is a bad guy (high bg noise), but not in FIRE
4858
"1.2.3.6": {
4959
Ip: "1.2.3.6",
5060
BackgroundNoiseScore: new(int),
@@ -56,18 +66,10 @@ var sampledata = map[string]cticlient.SmokeItem{
5666
{Name: "crowdsecurity/ssh-slow-bf", Label: "Example Attack"},
5767
},
5868
},
59-
//1.2.3.7 is a ok guy, but part of a bad range
69+
// 1.2.3.7 is a ok guy, but part of a bad range
6070
"1.2.3.7": {},
6171
}
6272

63-
const validApiKey = "my-api-key"
64-
65-
type RoundTripFunc func(req *http.Request) *http.Response
66-
67-
func (f RoundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) {
68-
return f(req), nil
69-
}
70-
7173
func smokeHandler(req *http.Request) *http.Response {
7274
apiKey := req.Header.Get("X-Api-Key")
7375
if apiKey != validApiKey {
@@ -127,7 +129,7 @@ func TestInvalidAuth(t *testing.T) {
127129
if err := InitCrowdsecCTI(ptr.Of("asdasd"), nil, nil, nil); err != nil {
128130
t.Fatalf("failed to init CTI : %s", err)
129131
}
130-
//Replace the client created by InitCrowdsecCTI with one that uses a custom transport
132+
// Replace the client created by InitCrowdsecCTI with one that uses a custom transport
131133
ctiClient = cticlient.NewCrowdsecCTIClient(cticlient.WithAPIKey("asdasd"), cticlient.WithHTTPClient(&http.Client{
132134
Transport: RoundTripFunc(smokeHandler),
133135
}))
@@ -137,7 +139,7 @@ func TestInvalidAuth(t *testing.T) {
137139
assert.False(t, CTIApiEnabled)
138140
assert.Equal(t, err, cticlient.ErrUnauthorized)
139141

140-
//CTI is now disabled, all requests should return empty
142+
// CTI is now disabled, all requests should return empty
141143
ctiClient = cticlient.NewCrowdsecCTIClient(cticlient.WithAPIKey(validApiKey), cticlient.WithHTTPClient(&http.Client{
142144
Transport: RoundTripFunc(smokeHandler),
143145
}))
@@ -153,7 +155,7 @@ func TestNoKey(t *testing.T) {
153155

154156
err := InitCrowdsecCTI(nil, nil, nil, nil)
155157
require.ErrorIs(t, err, cticlient.ErrDisabled)
156-
//Replace the client created by InitCrowdsecCTI with one that uses a custom transport
158+
// Replace the client created by InitCrowdsecCTI with one that uses a custom transport
157159
ctiClient = cticlient.NewCrowdsecCTIClient(cticlient.WithAPIKey("asdasd"), cticlient.WithHTTPClient(&http.Client{
158160
Transport: RoundTripFunc(smokeHandler),
159161
}))
@@ -171,7 +173,7 @@ func TestCache(t *testing.T) {
171173
if err := InitCrowdsecCTI(ptr.Of(validApiKey), &cacheDuration, nil, nil); err != nil {
172174
t.Fatalf("failed to init CTI : %s", err)
173175
}
174-
//Replace the client created by InitCrowdsecCTI with one that uses a custom transport
176+
// Replace the client created by InitCrowdsecCTI with one that uses a custom transport
175177
ctiClient = cticlient.NewCrowdsecCTIClient(cticlient.WithAPIKey(validApiKey), cticlient.WithHTTPClient(&http.Client{
176178
Transport: RoundTripFunc(smokeHandler),
177179
}))

0 commit comments

Comments
 (0)