Skip to content

Commit 907ce91

Browse files
KebreeJean-Baptiste GINTRAND
and
Jean-Baptiste GINTRAND
authored
enable sha mechanism for kafka authentication (#173)
Co-authored-by: Jean-Baptiste GINTRAND <[email protected]>
1 parent 2668c43 commit 907ce91

File tree

4 files changed

+64
-6
lines changed

4 files changed

+64
-6
lines changed

Diff for: README.md

+1
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ receivers:
341341
enable: true
342342
username: "kube-event-producer"
343343
password: "kube-event-producer-password"
344+
mechanism: "sha512"
344345
layout: #optional
345346
kind: "{{ .InvolvedObject.Kind }}"
346347
namespace: "{{ .InvolvedObject.Namespace }}"

Diff for: go.mod

+6-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ require (
2626
k8s.io/client-go v0.26.7
2727
)
2828

29+
require (
30+
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
31+
github.com/xdg-go/stringprep v1.0.4 // indirect
32+
)
33+
2934
require (
3035
cloud.google.com/go v0.107.0 // indirect
3136
cloud.google.com/go/compute v1.15.1 // indirect
@@ -41,7 +46,6 @@ require (
4146
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect
4247
github.com/eapache/queue v1.1.0 // indirect
4348
github.com/emicklei/go-restful/v3 v3.10.1 // indirect
44-
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
4549
github.com/fatih/color v1.15.0 // indirect
4650
github.com/go-kit/log v0.2.1 // indirect
4751
github.com/go-logfmt/logfmt v0.5.1 // indirect
@@ -98,6 +102,7 @@ require (
98102
github.com/sirupsen/logrus v1.9.0 // indirect
99103
github.com/spf13/cast v1.3.1 // indirect
100104
github.com/spf13/pflag v1.0.5 // indirect
105+
github.com/xdg-go/scram v1.1.2
101106
go.opencensus.io v0.24.0 // indirect
102107
golang.org/x/crypto v0.17.0 // indirect
103108
golang.org/x/net v0.17.0 // indirect

Diff for: go.sum

+7-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
6767
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
6868
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
6969
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
70-
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
7170
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
7271
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
7372
github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0=
@@ -299,6 +298,12 @@ github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
299298
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
300299
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
301300
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
301+
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
302+
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
303+
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
304+
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
305+
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
306+
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
302307
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
303308
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
304309
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
@@ -394,6 +399,7 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
394399
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
395400
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
396401
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
402+
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
397403
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
398404
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
399405
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=

Diff for: pkg/sinks/kafka.go

+50-4
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,19 @@ package sinks
22

33
import (
44
"context"
5+
"crypto/sha256"
6+
"crypto/sha512"
57
"crypto/tls"
68
"crypto/x509"
79
"encoding/json"
10+
"fmt"
811
"os"
912

1013
"github.com/Shopify/sarama"
1114
"github.com/resmoio/kubernetes-event-exporter/pkg/kube"
1215
"github.com/rs/zerolog/log"
16+
17+
"github.com/xdg-go/scram"
1318
)
1419

1520
// KafkaConfig is the Kafka producer configuration
@@ -28,9 +33,10 @@ type KafkaConfig struct {
2833
InsecureSkipVerify bool `yaml:"insecureSkipVerify"`
2934
} `yaml:"tls"`
3035
SASL struct {
31-
Enable bool `yaml:"enable"`
32-
Username string `yaml:"username"`
33-
Password string `yaml:"password"`
36+
Enable bool `yaml:"enable"`
37+
Username string `yaml:"username"`
38+
Password string `yaml:"password"`
39+
Mechanism string `yaml:"mechanism" default:"plain"`
3440
} `yaml:"sasl"`
3541
KafkaEncode Avro `yaml:"avro"`
3642
}
@@ -151,7 +157,7 @@ func createSaramaProducer(cfg *KafkaConfig) (sarama.SyncProducer, error) {
151157

152158
caCert, err := os.ReadFile(cfg.TLS.CaFile)
153159
if err != nil {
154-
return nil, err
160+
return nil, fmt.Errorf("error loading ca file: %w", err)
155161
}
156162

157163
caCertPool := x509.NewCertPool()
@@ -178,6 +184,17 @@ func createSaramaProducer(cfg *KafkaConfig) (sarama.SyncProducer, error) {
178184
saramaConfig.Net.SASL.Enable = true
179185
saramaConfig.Net.SASL.User = cfg.SASL.Username
180186
saramaConfig.Net.SASL.Password = cfg.SASL.Password
187+
if cfg.SASL.Mechanism == "sha512" {
188+
saramaConfig.Net.SASL.SCRAMClientGeneratorFunc = func() sarama.SCRAMClient { return &XDGSCRAMClient{HashGeneratorFcn: SHA512} }
189+
saramaConfig.Net.SASL.Mechanism = sarama.SASLTypeSCRAMSHA512
190+
} else if cfg.SASL.Mechanism == "sha256" {
191+
saramaConfig.Net.SASL.SCRAMClientGeneratorFunc = func() sarama.SCRAMClient { return &XDGSCRAMClient{HashGeneratorFcn: SHA256} }
192+
saramaConfig.Net.SASL.Mechanism = sarama.SASLTypeSCRAMSHA256
193+
} else if cfg.SASL.Mechanism == "plain" || cfg.SASL.Mechanism == "" {
194+
saramaConfig.Net.SASL.Mechanism = sarama.SASLTypePlaintext
195+
} else {
196+
return nil, fmt.Errorf("invalid scram sha mechanism: %s: can be one of 'sha256', 'sha512' or 'plain'", cfg.SASL.Mechanism)
197+
}
181198
}
182199

183200
// TODO: Find a generic way to override all other configs
@@ -190,3 +207,32 @@ func createSaramaProducer(cfg *KafkaConfig) (sarama.SyncProducer, error) {
190207

191208
return producer, nil
192209
}
210+
211+
var (
212+
SHA256 scram.HashGeneratorFcn = sha256.New
213+
SHA512 scram.HashGeneratorFcn = sha512.New
214+
)
215+
216+
type XDGSCRAMClient struct {
217+
*scram.Client
218+
*scram.ClientConversation
219+
scram.HashGeneratorFcn
220+
}
221+
222+
func (x *XDGSCRAMClient) Begin(userName, password, authzID string) (err error) {
223+
x.Client, err = x.HashGeneratorFcn.NewClient(userName, password, authzID)
224+
if err != nil {
225+
return err
226+
}
227+
x.ClientConversation = x.Client.NewConversation()
228+
return nil
229+
}
230+
231+
func (x *XDGSCRAMClient) Step(challenge string) (response string, err error) {
232+
response, err = x.ClientConversation.Step(challenge)
233+
return
234+
}
235+
236+
func (x *XDGSCRAMClient) Done() bool {
237+
return x.ClientConversation.Done()
238+
}

0 commit comments

Comments
 (0)