Skip to content

Commit 9ef8b19

Browse files
committed
Improve gssapi auth
1 parent 802ef5d commit 9ef8b19

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+7713
-1494
lines changed

README.md

Lines changed: 107 additions & 109 deletions
Large diffs are not rendered by default.

cmd/kafka-proxy/server.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -164,15 +164,18 @@ func initFlags() {
164164
Server.Flags().StringVar(&c.Kafka.SASL.Username, "sasl-username", "", "SASL user name")
165165
Server.Flags().StringVar(&c.Kafka.SASL.Password, "sasl-password", "", "SASL user password")
166166
Server.Flags().StringVar(&c.Kafka.SASL.JaasConfigFile, "sasl-jaas-config-file", "", "Location of JAAS config file with SASL username and password")
167-
Server.Flags().StringVar(&c.Kafka.SASL.Method, "sasl-method", "PLAIN", "SASL method to use (PLAIN, SCRAM-SHA-256, SCRAM-SHA-512")
167+
Server.Flags().StringVar(&c.Kafka.SASL.Method, "sasl-method", "PLAIN", "SASL method to use (PLAIN, SCRAM-SHA-256, SCRAM-SHA-512, GSSAPI")
168168

169169
// SASL GSSAPI
170-
Server.Flags().BoolVar(&c.Kafka.GSSAPI.Enable, "gssapi-enable", false, "Connect using SASL_GSSAPI")
171-
Server.Flags().StringVar(&c.Kafka.GSSAPI.ServiceName, "gssapi-servicename", "kafka", "ServiceName")
172-
Server.Flags().StringVar(&c.Kafka.GSSAPI.Username, "gssapi-username", "kafka", "Username")
173-
Server.Flags().StringVar(&c.Kafka.GSSAPI.Realm, "gssapi-realm", "", "Realm")
174-
Server.Flags().StringVar(&c.Kafka.GSSAPI.KerberosConfigPath, "gssapi-krb5", "/etc/krb5.conf", "krb5.conf file path, default: /etc/krb5.conf")
175-
Server.Flags().StringVar(&c.Kafka.GSSAPI.KeyTabPath, "gssapi-keytab", "", "KeyTabPath")
170+
Server.Flags().StringVar(&c.Kafka.SASL.GSSAPI.AuthType, "gssapi-auth-type", config.KRB5_KEYTAB_AUTH, "GSSAPI auth type: KEYTAB or USER")
171+
Server.Flags().StringVar(&c.Kafka.SASL.GSSAPI.ServiceName, "gssapi-servicename", "kafka", "ServiceName")
172+
Server.Flags().StringVar(&c.Kafka.SASL.GSSAPI.Username, "gssapi-username", "kafka", "Username")
173+
Server.Flags().StringVar(&c.Kafka.SASL.GSSAPI.Password, "gssapi-password", "", "Password for auth type USER")
174+
Server.Flags().StringVar(&c.Kafka.SASL.GSSAPI.Realm, "gssapi-realm", "", "Realm")
175+
Server.Flags().StringVar(&c.Kafka.SASL.GSSAPI.KerberosConfigPath, "gssapi-krb5", "/etc/krb5.conf", "krb5.conf file path, default: /etc/krb5.conf")
176+
Server.Flags().StringVar(&c.Kafka.SASL.GSSAPI.KeyTabPath, "gssapi-keytab", "", "krb5.keytab file location")
177+
Server.Flags().BoolVar(&c.Kafka.SASL.GSSAPI.DisablePAFXFAST, "gssapi-disable-pa-fx-fast", false, "Used to configure the client to not use PA_FX_FAST.")
178+
Server.Flags().StringToStringVar(&c.Kafka.SASL.GSSAPI.SPNHostsMapping, "gssapi-spn-host-mapping", map[string]string{}, "Mapping of Kafka servers address to SPN hosts")
176179

177180
// SASL by Proxy plugin
178181
Server.Flags().BoolVar(&c.Kafka.SASL.Plugin.Enable, "sasl-plugin-enable", false, "Use plugin for SASL authentication")

config/config.go

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ import (
1111
"github.com/pkg/errors"
1212
)
1313

14-
const defaultClientID = "kafka-proxy"
14+
const (
15+
defaultClientID = "kafka-proxy"
16+
KRB5_USER_AUTH = "USER"
17+
KRB5_KEYTAB_AUTH = "KEYTAB"
18+
)
1519

1620
var (
1721
// Version is the current version of the app, generated at build time
@@ -30,6 +34,18 @@ type DialAddressMapping struct {
3034
DestinationAddress string
3135
}
3236

37+
type GSSAPIConfig struct {
38+
AuthType string
39+
KeyTabPath string
40+
KerberosConfigPath string
41+
ServiceName string
42+
Username string
43+
Password string
44+
Realm string
45+
DisablePAFXFAST bool
46+
SPNHostsMapping map[string]string
47+
}
48+
3349
type Config struct {
3450
Http struct {
3551
ListenAddress string
@@ -144,14 +160,7 @@ type Config struct {
144160
LogLevel string
145161
Timeout time.Duration
146162
}
147-
}
148-
GSSAPI struct {
149-
Enable bool
150-
KeyTabPath string
151-
KerberosConfigPath string
152-
ServiceName string
153-
Username string
154-
Realm string
163+
GSSAPI GSSAPIConfig
155164
}
156165
Producer struct {
157166
Acks0Disabled bool
@@ -288,8 +297,32 @@ func (c *Config) Validate() error {
288297
return errors.New("Mechanism OAUTHBEARER is required when Kafka.SASL.Plugin.Enable is enabled")
289298
}
290299
} else {
291-
if c.Kafka.SASL.Username == "" || c.Kafka.SASL.Password == "" {
292-
return errors.New("SASL.Username and SASL.Password are required when SASL is enabled and plugin is not used")
300+
if c.Kafka.SASL.Method == "GSSAPI" {
301+
switch c.Kafka.SASL.GSSAPI.AuthType {
302+
case KRB5_USER_AUTH:
303+
if c.Kafka.SASL.GSSAPI.Password == "" {
304+
return errors.New("GSSAPI.Password is required for GSSAPI.AuthType USER")
305+
}
306+
case KRB5_KEYTAB_AUTH:
307+
if c.Kafka.SASL.GSSAPI.KeyTabPath == "" {
308+
return errors.New("GSSAPI.KeyTabPath is required for GSSAPI.AuthType KEYTAB")
309+
}
310+
default:
311+
return errors.Errorf("Unsupported GSSAPI.AuthType %s", c.Kafka.SASL.GSSAPI.AuthType)
312+
}
313+
if c.Kafka.SASL.GSSAPI.KerberosConfigPath == "" {
314+
return errors.New("GSSAPI KerberosConfigPath must not be empty")
315+
}
316+
if c.Kafka.SASL.GSSAPI.Username == "" {
317+
return errors.New("GSSAPI Username must not be empty")
318+
}
319+
if c.Kafka.SASL.GSSAPI.Realm == "" {
320+
return errors.New("GSSAPI Realm must not be empty")
321+
}
322+
} else {
323+
if c.Kafka.SASL.Username == "" || c.Kafka.SASL.Password == "" {
324+
return errors.New("SASL.Username and SASL.Password are required when SASL is enabled and plugin is not used")
325+
}
293326
}
294327
}
295328
} else {

go.mod

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ require (
1919
github.com/pkg/errors v0.9.1
2020
github.com/prometheus/client_golang v1.11.1
2121
github.com/sirupsen/logrus v1.6.0
22-
github.com/spf13/cobra v0.0.1
22+
github.com/spf13/cobra v1.6.1
2323
github.com/spf13/viper v1.0.2
2424
github.com/stretchr/testify v1.8.0
2525
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c
@@ -42,7 +42,7 @@ require (
4242
github.com/hashicorp/go-uuid v1.0.3 // indirect
4343
github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce // indirect
4444
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect
45-
github.com/inconshreveable/mousetrap v1.0.0 // indirect
45+
github.com/inconshreveable/mousetrap v1.0.1 // indirect
4646
github.com/jcmturner/aescts/v2 v2.0.0 // indirect
4747
github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect
4848
github.com/jcmturner/rpc/v2 v2.0.3 // indirect
@@ -59,7 +59,7 @@ require (
5959
github.com/spf13/afero v1.1.1 // indirect
6060
github.com/spf13/cast v1.2.0 // indirect
6161
github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec // indirect
62-
github.com/spf13/pflag v1.0.0 // indirect
62+
github.com/spf13/pflag v1.0.5 // indirect
6363
github.com/xdg/stringprep v1.0.0 // indirect
6464
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa // indirect
6565
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect

go.sum

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ github.com/cenkalti/backoff v1.1.0 h1:QnvVp8ikKCDWOsFheytRCoYWYPO/ObCTBGxT19Hc+y
1919
github.com/cenkalti/backoff v1.1.0/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
2020
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
2121
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
22+
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
2223
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2324
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
2425
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -77,8 +78,8 @@ github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce h1:xdsDDbiBDQTKASoGE
7778
github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w=
7879
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ=
7980
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
80-
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
81-
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
81+
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
82+
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
8283
github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=
8384
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
8485
github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo=
@@ -148,6 +149,7 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT
148149
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
149150
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
150151
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
152+
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
151153
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
152154
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
153155
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
@@ -156,12 +158,12 @@ github.com/spf13/afero v1.1.1 h1:Lt3ihYMlE+lreX1GS4Qw4ZsNpYQLxIXKBTEOXm3nt6I=
156158
github.com/spf13/afero v1.1.1/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
157159
github.com/spf13/cast v1.2.0 h1:HHl1DSRbEQN2i8tJmtS6ViPyHx35+p51amrdsiTCrkg=
158160
github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg=
159-
github.com/spf13/cobra v0.0.1 h1:zZh3X5aZbdnoj+4XkaBxKfhO4ot82icYdhhREIAXIj8=
160-
github.com/spf13/cobra v0.0.1/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
161+
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
162+
github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
161163
github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec h1:2ZXvIUGghLpdTVHR1UfvfrzoVlZaE/yOWC5LueIHZig=
162164
github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
163-
github.com/spf13/pflag v1.0.0 h1:oaPbdDe/x0UncahuwiPxW1GYJyilRAdsPnq3e1yaPcI=
164-
github.com/spf13/pflag v1.0.0/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
165+
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
166+
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
165167
github.com/spf13/viper v1.0.2 h1:Ncr3ZIuJn322w2k1qmzXDnkLAdQMlJqBa9kfAH+irso=
166168
github.com/spf13/viper v1.0.2/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM=
167169
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=

plugin/local-auth/proto/auth.pb.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugin/token-info/proto/token-info.pb.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugin/token-provider/proto/token-provider.pb.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

proxy/auth.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ type AuthClient struct {
2121
tokenProvider apis.TokenProvider
2222
}
2323

24-
//TODO: reset deadlines after method - ok
24+
// TODO: reset deadlines after method - ok
2525
func (b *AuthClient) sendAndReceiveGatewayAuth(conn DeadlineReaderWriter) error {
2626
//TODO: timeout
2727
// ctx, cancel := context.WithTimeout(context.Background(), time.Duration(p.timeout)*time.Second)
@@ -77,7 +77,7 @@ type AuthServer struct {
7777
tokenInfo apis.TokenInfo
7878
}
7979

80-
//TODO: reset deadlines after method - ok
80+
// TODO: reset deadlines after method - ok
8181
func (b *AuthServer) receiveAndSendGatewayAuth(conn DeadlineReaderWriter) error {
8282
err := conn.SetDeadline(time.Now().Add(b.timeout))
8383
if err != nil {

proxy/client.go

Lines changed: 9 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ type Client struct {
2828
// Kafka Net configuration
2929
config *config.Config
3030

31-
// Config of Proxy request-response processor (instance p)
31+
// config of Proxy request-response processor (instance p)
3232
processorConfig ProcessorConfig
3333

3434
dialer Dialer
@@ -39,7 +39,6 @@ type Client struct {
3939

4040
saslAuthByProxy SASLAuthByProxy
4141
authClient *AuthClient
42-
gssapiKerberosAuth *GSSAPIKerberosAuth
4342

4443
dialAddressMapping map[string]config.DialAddressMapping
4544

@@ -118,32 +117,24 @@ func NewClient(conns *ConnSet, c *config.Config, netAddressMappingFunc config.Ne
118117
password: c.Kafka.SASL.Password,
119118
mechanism: c.Kafka.SASL.Method,
120119
}
120+
} else if c.Kafka.SASL.Method == SASLSGSSAPI {
121+
saslAuthByProxy = &SASLGSSAPIAuth{
122+
writeTimeout: c.Kafka.WriteTimeout,
123+
readTimeout: c.Kafka.ReadTimeout,
124+
gssapiConfig: &c.Kafka.SASL.GSSAPI,
125+
}
121126
} else {
122127
return nil, errors.Errorf("SASL Mechanism not valid '%s'", c.Kafka.SASL.Method)
123128
}
124129
}
125130

126-
var gssapiKerberosAuth *GSSAPIKerberosAuth
127-
if c.Kafka.GSSAPI.Enable {
128-
gssapiKerberosAuth = &GSSAPIKerberosAuth{
129-
Config: &GSSAPIConfig{
130-
KeyTabPath: c.Kafka.GSSAPI.KeyTabPath,
131-
KerberosConfigPath: c.Kafka.GSSAPI.KerberosConfigPath,
132-
ServiceName: c.Kafka.GSSAPI.ServiceName,
133-
Username: c.Kafka.GSSAPI.Username,
134-
Realm: c.Kafka.GSSAPI.Realm,
135-
},
136-
}
137-
}
138-
139131
dialAddressMapping, err := getAddressToDialAddressMapping(c)
140132
if err != nil {
141133
return nil, err
142134
}
143135

144136
return &Client{conns: conns, config: c, dialer: dialer, tcpConnOptions: tcpConnOptions, stopRun: make(chan struct{}, 1),
145-
saslAuthByProxy: saslAuthByProxy,
146-
gssapiKerberosAuth: gssapiKerberosAuth,
137+
saslAuthByProxy: saslAuthByProxy,
147138
authClient: &AuthClient{
148139
enabled: c.Auth.Gateway.Client.Enable,
149140
magic: c.Auth.Gateway.Client.Magic,
@@ -339,19 +330,7 @@ func (c *Client) auth(conn net.Conn, brokerAddress string) error {
339330
}
340331
}
341332
if c.config.Kafka.SASL.Enable {
342-
err := c.saslAuthByProxy.sendAndReceiveSASLAuth(conn)
343-
if err != nil {
344-
_ = conn.Close()
345-
return err
346-
}
347-
if err := conn.SetDeadline(time.Time{}); err != nil {
348-
_ = conn.Close()
349-
return err
350-
}
351-
}
352-
353-
if c.config.Kafka.GSSAPI.Enable {
354-
err := c.gssapiKerberosAuth.sendAndReceiveGSSAPIAuth(conn, brokerAddress)
333+
err := c.saslAuthByProxy.sendAndReceiveSASLAuth(conn, brokerAddress)
355334
if err != nil {
356335
_ = conn.Close()
357336
return err

0 commit comments

Comments
 (0)