Skip to content

Commit 0836cbf

Browse files
committed
Configure TLS
1 parent 553c409 commit 0836cbf

File tree

5 files changed

+195
-69
lines changed

5 files changed

+195
-69
lines changed

README.md

Lines changed: 65 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -64,67 +64,70 @@ See:
6464
kafka-proxy server [flags]
6565
6666
Flags:
67-
--auth-gateway-client-command string Path to authentication plugin binary
68-
--auth-gateway-client-enable Enable gateway client authentication
69-
--auth-gateway-client-log-level string Log level of the auth plugin (default "trace")
70-
--auth-gateway-client-magic uint Magic bytes sent in the handshake
71-
--auth-gateway-client-method string Authentication method
72-
--auth-gateway-client-param stringArray Authentication plugin parameter
73-
--auth-gateway-client-timeout duration Authentication timeout (default 10s)
74-
--auth-gateway-server-command string Path to authentication plugin binary
75-
--auth-gateway-server-enable Enable proxy server authentication
76-
--auth-gateway-server-log-level string Log level of the auth plugin (default "trace")
77-
--auth-gateway-server-magic uint Magic bytes sent in the handshake
78-
--auth-gateway-server-method string Authentication method
79-
--auth-gateway-server-param stringArray Authentication plugin parameter
80-
--auth-gateway-server-timeout duration Authentication timeout (default 10s)
81-
--auth-local-command string Path to authentication plugin binary
82-
--auth-local-enable Enable local SASL/PLAIN authentication performed by listener - SASL handshake will not be passed to kafka brokers
83-
--auth-local-log-level string Log level of the auth plugin (default "trace")
84-
--auth-local-param stringArray Authentication plugin parameter
85-
--auth-local-timeout duration Authentication timeout (default 10s)
86-
--bootstrap-server-mapping stringArray Mapping of Kafka bootstrap server address to local address (host:port,host:port(,advhost:advport))
87-
--debug-enable Enable Debug endpoint
88-
--debug-listen-address string Debug listen address (default "0.0.0.0:6060")
89-
--default-listener-ip string Default listener IP (default "127.0.0.1")
90-
--dynamic-listeners-disable Disable dynamic listeners.
91-
--external-server-mapping stringArray Mapping of Kafka server address to external address (host:port,host:port). A listener for the external address is not started
92-
--forbidden-api-keys intSlice Forbidden Kafka request types. The restriction should prevent some Kafka operations e.g. 20 - DeleteTopics
93-
-h, --help help for server
94-
--http-disable Disable HTTP endpoints
95-
--http-health-path string Path on which to health endpoint (default "/health")
96-
--http-listen-address string Address that kafka-proxy is listening on (default "0.0.0.0:9080")
97-
--http-metrics-path string Path on which to expose metrics (default "/metrics")
98-
--kafka-client-id string An optional identifier to track the source of requests (default "kafka-proxy")
99-
--kafka-connection-read-buffer-size int Size of the operating system's receive buffer associated with the connection. If zero, system default is used
100-
--kafka-connection-write-buffer-size int Sets the size of the operating system's transmit buffer associated with the connection. If zero, system default is used
101-
--kafka-dial-timeout duration How long to wait for the initial connection (default 15s)
102-
--kafka-keep-alive duration Keep alive period for an active network connection. If zero, keep-alives are disabled (default 1m0s)
103-
--kafka-max-open-requests int Maximal number of open requests pro tcp connection before sending on it blocks (default 256)
104-
--kafka-read-timeout duration How long to wait for a response (default 30s)
105-
--kafka-write-timeout duration How long to wait for a transmit (default 30s)
106-
--log-format string Log format text or json (default "text")
107-
--log-level string Log level debug, info, warning, error, fatal or panic (default "info")
108-
--proxy-listener-ca-chain-cert-file string PEM encoded CA's certificate file. If provided, client certificate is required and verified
109-
--proxy-listener-cert-file string PEM encoded file with server certificate
110-
--proxy-listener-keep-alive duration Keep alive period for an active network connection. If zero, keep-alives are disabled (default 1m0s)
111-
--proxy-listener-key-file string PEM encoded file with private key for the server certificate
112-
--proxy-listener-key-password string Password to decrypt rsa private key
113-
--proxy-listener-read-buffer-size int Size of the operating system's receive buffer associated with the connection. If zero, system default is used
114-
--proxy-listener-tls-enable Whether or not to use TLS listener
115-
--proxy-listener-write-buffer-size int Sets the size of the operating system's transmit buffer associated with the connection. If zero, system default is used
116-
--proxy-request-buffer-size int Request buffer size pro tcp connection (default 4096)
117-
--proxy-response-buffer-size int Response buffer size pro tcp connection (default 4096)
118-
--sasl-enable Connect using SASL/PLAIN
119-
--sasl-jaas-config-file string Location of JAAS config file with SASL username and password
120-
--sasl-password string SASL user password
121-
--sasl-username string SASL user name
122-
--tls-ca-chain-cert-file string PEM encoded CA's certificate file
123-
--tls-client-cert-file string PEM encoded file with client certificate
124-
--tls-client-key-file string PEM encoded file with private key for the client certificate
125-
--tls-client-key-password string Password to decrypt rsa private key
126-
--tls-enable Whether or not to use TLS when connecting to the broker
127-
--tls-insecure-skip-verify It controls whether a client verifies the server's certificate chain and host name
67+
--auth-gateway-client-command string Path to authentication plugin binary
68+
--auth-gateway-client-enable Enable gateway client authentication
69+
--auth-gateway-client-log-level string Log level of the auth plugin (default "trace")
70+
--auth-gateway-client-magic uint Magic bytes sent in the handshake
71+
--auth-gateway-client-method string Authentication method
72+
--auth-gateway-client-param stringArray Authentication plugin parameter
73+
--auth-gateway-client-timeout duration Authentication timeout (default 10s)
74+
--auth-gateway-server-command string Path to authentication plugin binary
75+
--auth-gateway-server-enable Enable proxy server authentication
76+
--auth-gateway-server-log-level string Log level of the auth plugin (default "trace")
77+
--auth-gateway-server-magic uint Magic bytes sent in the handshake
78+
--auth-gateway-server-method string Authentication method
79+
--auth-gateway-server-param stringArray Authentication plugin parameter
80+
--auth-gateway-server-timeout duration Authentication timeout (default 10s)
81+
--auth-local-command string Path to authentication plugin binary
82+
--auth-local-enable Enable local SASL/PLAIN authentication performed by listener - SASL handshake will not be passed to kafka brokers
83+
--auth-local-log-level string Log level of the auth plugin (default "trace")
84+
--auth-local-param stringArray Authentication plugin parameter
85+
--auth-local-timeout duration Authentication timeout (default 10s)
86+
--bootstrap-server-mapping stringArray Mapping of Kafka bootstrap server address to local address (host:port,host:port(,advhost:advport))
87+
--debug-enable Enable Debug endpoint
88+
--debug-listen-address string Debug listen address (default "0.0.0.0:6060")
89+
--default-listener-ip string Default listener IP (default "127.0.0.1")
90+
--dynamic-listeners-disable Disable dynamic listeners.
91+
--external-server-mapping stringArray Mapping of Kafka server address to external address (host:port,host:port). A listener for the external address is not started
92+
--forbidden-api-keys intSlice Forbidden Kafka request types. The restriction should prevent some Kafka operations e.g. 20 - DeleteTopics
93+
-h, --help help for server
94+
--http-disable Disable HTTP endpoints
95+
--http-health-path string Path on which to health endpoint (default "/health")
96+
--http-listen-address string Address that kafka-proxy is listening on (default "0.0.0.0:9080")
97+
--http-metrics-path string Path on which to expose metrics (default "/metrics")
98+
--kafka-client-id string An optional identifier to track the source of requests (default "kafka-proxy")
99+
--kafka-connection-read-buffer-size int Size of the operating system's receive buffer associated with the connection. If zero, system default is used
100+
--kafka-connection-write-buffer-size int Sets the size of the operating system's transmit buffer associated with the connection. If zero, system default is used
101+
--kafka-dial-timeout duration How long to wait for the initial connection (default 15s)
102+
--kafka-keep-alive duration Keep alive period for an active network connection. If zero, keep-alives are disabled (default 1m0s)
103+
--kafka-max-open-requests int Maximal number of open requests pro tcp connection before sending on it blocks (default 256)
104+
--kafka-read-timeout duration How long to wait for a response (default 30s)
105+
--kafka-write-timeout duration How long to wait for a transmit (default 30s)
106+
--log-format string Log format text or json (default "text")
107+
--log-level string Log level debug, info, warning, error, fatal or panic (default "info")
108+
--proxy-listener-ca-chain-cert-file string PEM encoded CA's certificate file. If provided, client certificate is required and verified
109+
--proxy-listener-cert-file string PEM encoded file with server certificate
110+
--proxy-listener-cipher-suites stringSlice List of supported cipher suites
111+
--proxy-listener-curve-preferences stringSlice List of curve preferences
112+
--proxy-listener-keep-alive duration Keep alive period for an active network connection. If zero, keep-alives are disabled (default 1m0s)
113+
--proxy-listener-key-file string PEM encoded file with private key for the server certificate
114+
--proxy-listener-key-password string Password to decrypt rsa private key
115+
--proxy-listener-read-buffer-size int Size of the operating system's receive buffer associated with the connection. If zero, system default is used
116+
--proxy-listener-tls-enable Whether or not to use TLS listener
117+
--proxy-listener-write-buffer-size int Sets the size of the operating system's transmit buffer associated with the connection. If zero, system default is used
118+
--proxy-request-buffer-size int Request buffer size pro tcp connection (default 4096)
119+
--proxy-response-buffer-size int Response buffer size pro tcp connection (default 4096)
120+
--sasl-enable Connect using SASL/PLAIN
121+
--sasl-jaas-config-file string Location of JAAS config file with SASL username and password
122+
--sasl-password string SASL user password
123+
--sasl-username string SASL user name
124+
--tls-ca-chain-cert-file string PEM encoded CA's certificate file
125+
--tls-client-cert-file string PEM encoded file with client certificate
126+
--tls-client-key-file string PEM encoded file with private key for the client certificate
127+
--tls-client-key-password string Password to decrypt rsa private key
128+
--tls-enable Whether or not to use TLS when connecting to the broker
129+
--tls-insecure-skip-verify It controls whether a client verifies the server's certificate chain and host name
130+
128131
129132
130133
### Usage example
@@ -317,7 +320,7 @@ spec:
317320
2. google-id method
318321
* [X] Registry for built-in plugins
319322
* [X] Client cert check
320-
* [ ] TLS server parameters like CipherSuites etc. - see ory/graceful/blob/master/http_defaults.go
323+
* [X] Set TLS server CipherSuites and CurvePreferences
321324
* [ ] Performance tests and tuning
322325
* [ ] Socket buffer sizing e.g. SO_RCVBUF = 32768, SO_SNDBUF = 131072
323326
* [ ] Kafka connect tests

cmd/kafka-proxy/server.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ func init() {
8282
Server.Flags().StringVar(&c.Proxy.TLS.ListenerKeyFile, "proxy-listener-key-file", "", "PEM encoded file with private key for the server certificate")
8383
Server.Flags().StringVar(&c.Proxy.TLS.ListenerKeyPassword, "proxy-listener-key-password", "", "Password to decrypt rsa private key")
8484
Server.Flags().StringVar(&c.Proxy.TLS.CAChainCertFile, "proxy-listener-ca-chain-cert-file", "", "PEM encoded CA's certificate file. If provided, client certificate is required and verified")
85+
Server.Flags().StringSliceVar(&c.Proxy.TLS.ListenerCipherSuites, "proxy-listener-cipher-suites", []string{}, "List of supported cipher suites")
86+
Server.Flags().StringSliceVar(&c.Proxy.TLS.ListenerCurvePreferences, "proxy-listener-curve-preferences", []string{}, "List of curve preferences")
8587

8688
// local authentication plugin
8789
Server.Flags().BoolVar(&c.Auth.Local.Enable, "auth-local-enable", false, "Enable local SASL/PLAIN authentication performed by listener - SASL handshake will not be passed to kafka brokers")

config/config.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,13 @@ type Config struct {
5252
ListenerKeepAlive time.Duration
5353

5454
TLS struct {
55-
Enable bool
56-
ListenerCertFile string
57-
ListenerKeyFile string
58-
ListenerKeyPassword string
59-
CAChainCertFile string
55+
Enable bool
56+
ListenerCertFile string
57+
ListenerKeyFile string
58+
ListenerKeyPassword string
59+
CAChainCertFile string
60+
ListenerCipherSuites []string
61+
ListenerCurvePreferences []string
6062
}
6163
}
6264
Auth struct {

proxy/tls.go

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,47 @@ import (
77
"github.com/grepplabs/kafka-proxy/config"
88
"github.com/pkg/errors"
99
"io/ioutil"
10+
"strings"
11+
)
12+
13+
var (
14+
defaultCurvePreferences = []tls.CurveID{
15+
tls.CurveP256,
16+
tls.X25519,
17+
}
18+
19+
supportedCurvesMap = map[string]tls.CurveID{
20+
"X25519": tls.X25519,
21+
"P256": tls.CurveP256,
22+
"P384": tls.CurveP384,
23+
"P521": tls.CurveP521,
24+
}
25+
26+
defaultCipherSuites = []uint16{
27+
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
28+
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
29+
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
30+
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
31+
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
32+
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
33+
}
34+
// https://github.com/mholt/caddy/blob/master/caddytls/config.go
35+
supportedCiphersMap = map[string]uint16{
36+
"ECDHE-ECDSA-AES256-GCM-SHA384": tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
37+
"ECDHE-RSA-AES256-GCM-SHA384": tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
38+
"ECDHE-ECDSA-AES128-GCM-SHA256": tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
39+
"ECDHE-RSA-AES128-GCM-SHA256": tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
40+
"ECDHE-ECDSA-WITH-CHACHA20-POLY1305": tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
41+
"ECDHE-RSA-WITH-CHACHA20-POLY1305": tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
42+
"ECDHE-RSA-AES256-CBC-SHA": tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
43+
"ECDHE-RSA-AES128-CBC-SHA": tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
44+
"ECDHE-ECDSA-AES256-CBC-SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
45+
"ECDHE-ECDSA-AES128-CBC-SHA": tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
46+
"RSA-AES256-CBC-SHA": tls.TLS_RSA_WITH_AES_256_CBC_SHA,
47+
"RSA-AES128-CBC-SHA": tls.TLS_RSA_WITH_AES_128_CBC_SHA,
48+
"ECDHE-RSA-3DES-EDE-CBC-SHA": tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
49+
"RSA-3DES-EDE-CBC-SHA": tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
50+
}
1051
)
1152

1253
func newTLSListenerConfig(conf *config.Config) (*tls.Config, error) {
@@ -31,9 +72,22 @@ func newTLSListenerConfig(conf *config.Config) (*tls.Config, error) {
3172
if err != nil {
3273
return nil, err
3374
}
75+
cipherSuites, err := getCipherSuites(opts.ListenerCipherSuites)
76+
if err != nil {
77+
return nil, err
78+
}
79+
curvePreferences, err := getCurvePreferences(opts.ListenerCurvePreferences)
80+
if err != nil {
81+
return nil, err
82+
}
83+
3484
cfg := &tls.Config{
35-
Certificates: []tls.Certificate{cert},
36-
ClientAuth: tls.NoClientCert,
85+
Certificates: []tls.Certificate{cert},
86+
ClientAuth: tls.NoClientCert,
87+
PreferServerCipherSuites: true,
88+
MinVersion: tls.VersionTLS12,
89+
CurvePreferences: curvePreferences,
90+
CipherSuites: cipherSuites,
3791
}
3892
if opts.CAChainCertFile != "" {
3993
caCertPEMBlock, err := ioutil.ReadFile(opts.CAChainCertFile)
@@ -50,7 +104,38 @@ func newTLSListenerConfig(conf *config.Config) (*tls.Config, error) {
50104
return cfg, nil
51105
}
52106

107+
func getCipherSuites(enabledCipherSuites []string) ([]uint16, error) {
108+
suites := make([]uint16, 0)
109+
for _, suite := range enabledCipherSuites {
110+
cipher, ok := supportedCiphersMap[strings.TrimSpace(suite)]
111+
if !ok {
112+
return nil, errors.Errorf("invalid cipher suite '%s' selected", suite)
113+
}
114+
suites = append(suites, cipher)
115+
}
116+
if len(suites) == 0 {
117+
return defaultCipherSuites, nil
118+
}
119+
return suites, nil
120+
}
121+
122+
func getCurvePreferences(enabledCurvePreferences []string) ([]tls.CurveID, error) {
123+
curvePreferences := make([]tls.CurveID, 0)
124+
for _, curveID := range enabledCurvePreferences {
125+
curvePreference, ok := supportedCurvesMap[strings.TrimSpace(curveID)]
126+
if !ok {
127+
return nil, errors.Errorf("invalid curveID '%s' selected", curveID)
128+
}
129+
curvePreferences = append(curvePreferences, curvePreference)
130+
}
131+
if len(curvePreferences) == 0 {
132+
return defaultCurvePreferences, nil
133+
}
134+
return curvePreferences, nil
135+
}
136+
53137
func newTLSClientConfig(conf *config.Config) (*tls.Config, error) {
138+
// https://blog.cloudflare.com/exposing-go-on-the-internet/
54139
opts := conf.Kafka.TLS
55140

56141
cfg := &tls.Config{InsecureSkipVerify: opts.InsecureSkipVerify}

0 commit comments

Comments
 (0)