@@ -6,11 +6,46 @@ import (
6
6
"fmt"
7
7
"io/ioutil"
8
8
"net"
9
+ "strings"
9
10
"time"
10
11
11
12
"github.com/hashicorp/nomad/nomad/structs/config"
12
13
)
13
14
15
+ // supportedTLSVersions are the current TLS versions that Nomad supports
16
+ var supportedTLSVersions = map [string ]uint16 {
17
+ "tls10" : tls .VersionTLS10 ,
18
+ "tls11" : tls .VersionTLS11 ,
19
+ "tls12" : tls .VersionTLS12 ,
20
+ }
21
+
22
+ // supportedTLSCiphers are the complete list of TLS ciphers supported by Nomad
23
+ var supportedTLSCiphers = map [string ]uint16 {
24
+ "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305" : tls .TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 ,
25
+ "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305" : tls .TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 ,
26
+ "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" : tls .TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 ,
27
+ "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" : tls .TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 ,
28
+ "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" : tls .TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ,
29
+ "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" : tls .TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 ,
30
+ "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" : tls .TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 ,
31
+ "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA" : tls .TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA ,
32
+ "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256" : tls .TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 ,
33
+ "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA" : tls .TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA ,
34
+ "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA" : tls .TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA ,
35
+ "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA" : tls .TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA ,
36
+ "TLS_RSA_WITH_AES_128_GCM_SHA256" : tls .TLS_RSA_WITH_AES_128_GCM_SHA256 ,
37
+ "TLS_RSA_WITH_AES_256_GCM_SHA384" : tls .TLS_RSA_WITH_AES_256_GCM_SHA384 ,
38
+ "TLS_RSA_WITH_AES_128_CBC_SHA256" : tls .TLS_RSA_WITH_AES_128_CBC_SHA256 ,
39
+ "TLS_RSA_WITH_AES_128_CBC_SHA" : tls .TLS_RSA_WITH_AES_128_CBC_SHA ,
40
+ "TLS_RSA_WITH_AES_256_CBC_SHA" : tls .TLS_RSA_WITH_AES_256_CBC_SHA ,
41
+ }
42
+
43
+ // defaultTLSCiphers are the TLS Ciphers that are supported by default
44
+ var defaultTLSCiphers = []string {"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305" ,
45
+ "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" ,
46
+ "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" ,
47
+ }
48
+
14
49
// RegionSpecificWrapper is used to invoke a static Region and turns a
15
50
// RegionWrapper into a Wrapper type.
16
51
func RegionSpecificWrapper (region string , tlsWrap RegionWrapper ) Wrapper {
@@ -65,9 +100,26 @@ type Config struct {
65
100
66
101
// KeyLoader dynamically reloads TLS configuration.
67
102
KeyLoader * config.KeyLoader
103
+
104
+ // CipherSuites have a default safe configuration, or operators can override
105
+ // these values for acceptable safe alternatives.
106
+ CipherSuites []uint16
107
+
108
+ // MinVersion contains the minimum SSL/TLS version that is accepted.
109
+ MinVersion uint16
68
110
}
69
111
70
- func NewTLSConfiguration (newConf * config.TLSConfig ) * Config {
112
+ func NewTLSConfiguration (newConf * config.TLSConfig ) (* Config , error ) {
113
+ ciphers , err := ParseCiphers (newConf .TLSCipherSuites )
114
+ if err != nil {
115
+ return nil , err
116
+ }
117
+
118
+ minVersion , err := ParseMinVersion (newConf .TLSMinVersion )
119
+ if err != nil {
120
+ return nil , err
121
+ }
122
+
71
123
return & Config {
72
124
VerifyIncoming : true ,
73
125
VerifyOutgoing : true ,
@@ -76,7 +128,9 @@ func NewTLSConfiguration(newConf *config.TLSConfig) *Config {
76
128
CertFile : newConf .CertFile ,
77
129
KeyFile : newConf .KeyFile ,
78
130
KeyLoader : newConf .GetKeyLoader (),
79
- }
131
+ CipherSuites : ciphers ,
132
+ MinVersion : minVersion ,
133
+ }, nil
80
134
}
81
135
82
136
// AppendCA opens and parses the CA file and adds the certificates to
@@ -132,6 +186,8 @@ func (c *Config) OutgoingTLSConfig() (*tls.Config, error) {
132
186
tlsConfig := & tls.Config {
133
187
RootCAs : x509 .NewCertPool (),
134
188
InsecureSkipVerify : true ,
189
+ CipherSuites : c .CipherSuites ,
190
+ MinVersion : c .MinVersion ,
135
191
}
136
192
if c .VerifyServerHostname {
137
193
tlsConfig .InsecureSkipVerify = false
@@ -248,8 +304,10 @@ func WrapTLSClient(conn net.Conn, tlsConfig *tls.Config) (net.Conn, error) {
248
304
func (c * Config ) IncomingTLSConfig () (* tls.Config , error ) {
249
305
// Create the tlsConfig
250
306
tlsConfig := & tls.Config {
251
- ClientCAs : x509 .NewCertPool (),
252
- ClientAuth : tls .NoClientCert ,
307
+ ClientCAs : x509 .NewCertPool (),
308
+ ClientAuth : tls .NoClientCert ,
309
+ CipherSuites : c .CipherSuites ,
310
+ MinVersion : c .MinVersion ,
253
311
}
254
312
255
313
// Parse the CA cert if any
@@ -279,3 +337,42 @@ func (c *Config) IncomingTLSConfig() (*tls.Config, error) {
279
337
280
338
return tlsConfig , nil
281
339
}
340
+
341
+ // ParseCiphers parses ciphersuites from the comma-separated string into
342
+ // recognized slice
343
+ func ParseCiphers (cipherStr string ) ([]uint16 , error ) {
344
+ suites := []uint16 {}
345
+
346
+ cipherStr = strings .TrimSpace (cipherStr )
347
+
348
+ var ciphers []string
349
+ if cipherStr == "" {
350
+ ciphers = defaultTLSCiphers
351
+
352
+ } else {
353
+ ciphers = strings .Split (cipherStr , "," )
354
+ }
355
+ for _ , cipher := range ciphers {
356
+ c , ok := supportedTLSCiphers [cipher ]
357
+ if ! ok {
358
+ return suites , fmt .Errorf ("unsupported TLS cipher %q" , cipher )
359
+ }
360
+ suites = append (suites , c )
361
+ }
362
+
363
+ return suites , nil
364
+ }
365
+
366
+ // ParseMinVersion parses the specified minimum TLS version for the Nomad agent
367
+ func ParseMinVersion (version string ) (uint16 , error ) {
368
+ if version == "" {
369
+ return supportedTLSVersions ["tls12" ], nil
370
+ }
371
+
372
+ vers , ok := supportedTLSVersions [version ]
373
+ if ! ok {
374
+ return 0 , fmt .Errorf ("unsupported TLS version %q" , version )
375
+ }
376
+
377
+ return vers , nil
378
+ }
0 commit comments