Add tls option for Elliptic Curve Preferences
This commit is contained in:
parent
c5ec12cd56
commit
5a3e325742
10 changed files with 104 additions and 15 deletions
|
@ -274,6 +274,46 @@ spec:
|
||||||
With TLS 1.3, the cipher suites are not configurable (all supported cipher suites are safe in this case).
|
With TLS 1.3, the cipher suites are not configurable (all supported cipher suites are safe in this case).
|
||||||
<https://golang.org/doc/go1.12#tls_1_3>
|
<https://golang.org/doc/go1.12#tls_1_3>
|
||||||
|
|
||||||
|
### Curve Preferences
|
||||||
|
|
||||||
|
This option allows to set the preferred elliptic curves in a specific order.
|
||||||
|
|
||||||
|
The names of the curves defined by [`crypto`](https://godoc.org/crypto/tls#CurveID) (e.g. `CurveP521`) and the [RFC defined names](https://tools.ietf.org/html/rfc8446#section-4.2.7) (e. g. `secp521r1`) can be used.
|
||||||
|
|
||||||
|
See [CurveID](https://godoc.org/crypto/tls#CurveID) for more information.
|
||||||
|
|
||||||
|
```toml tab="File (TOML)"
|
||||||
|
# Dynamic configuration
|
||||||
|
|
||||||
|
[tls.options]
|
||||||
|
[tls.options.default]
|
||||||
|
curvePreferences = ["CurveP521", "CurveP384"]
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="File (YAML)"
|
||||||
|
# Dynamic configuration
|
||||||
|
|
||||||
|
tls:
|
||||||
|
options:
|
||||||
|
default:
|
||||||
|
curvePreferences:
|
||||||
|
- CurveP521
|
||||||
|
- CurveP384
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml tab="Kubernetes"
|
||||||
|
apiVersion: traefik.containo.us/v1alpha1
|
||||||
|
kind: TLSOption
|
||||||
|
metadata:
|
||||||
|
name: default
|
||||||
|
namespace: default
|
||||||
|
|
||||||
|
spec:
|
||||||
|
curvePreferences:
|
||||||
|
- CurveP521
|
||||||
|
- CurveP384
|
||||||
|
```
|
||||||
|
|
||||||
### Strict SNI Checking
|
### Strict SNI Checking
|
||||||
|
|
||||||
With strict SNI checking, Traefik won't allow connections from clients connections
|
With strict SNI checking, Traefik won't allow connections from clients connections
|
||||||
|
|
|
@ -321,6 +321,7 @@
|
||||||
maxVersion = "foobar"
|
maxVersion = "foobar"
|
||||||
cipherSuites = ["foobar", "foobar"]
|
cipherSuites = ["foobar", "foobar"]
|
||||||
sniStrict = true
|
sniStrict = true
|
||||||
|
curvePreferences = ["foobar", "foobar"]
|
||||||
[tls.options.Options0.clientAuth]
|
[tls.options.Options0.clientAuth]
|
||||||
caFiles = ["foobar", "foobar"]
|
caFiles = ["foobar", "foobar"]
|
||||||
clientAuthType = "foobar"
|
clientAuthType = "foobar"
|
||||||
|
@ -329,6 +330,7 @@
|
||||||
maxVersion = "foobar"
|
maxVersion = "foobar"
|
||||||
cipherSuites = ["foobar", "foobar"]
|
cipherSuites = ["foobar", "foobar"]
|
||||||
sniStrict = true
|
sniStrict = true
|
||||||
|
curvePreferences = ["foobar", "foobar"]
|
||||||
[tls.options.Options1.clientAuth]
|
[tls.options.Options1.clientAuth]
|
||||||
caFiles = ["foobar", "foobar"]
|
caFiles = ["foobar", "foobar"]
|
||||||
clientAuthType = "foobar"
|
clientAuthType = "foobar"
|
||||||
|
|
|
@ -353,6 +353,9 @@ tls:
|
||||||
cipherSuites:
|
cipherSuites:
|
||||||
- foobar
|
- foobar
|
||||||
- foobar
|
- foobar
|
||||||
|
curvePreferences:
|
||||||
|
- foobar
|
||||||
|
- foobar
|
||||||
clientAuth:
|
clientAuth:
|
||||||
caFiles:
|
caFiles:
|
||||||
- foobar
|
- foobar
|
||||||
|
@ -365,6 +368,9 @@ tls:
|
||||||
cipherSuites:
|
cipherSuites:
|
||||||
- foobar
|
- foobar
|
||||||
- foobar
|
- foobar
|
||||||
|
curvePreferences:
|
||||||
|
- foobar
|
||||||
|
- foobar
|
||||||
clientAuth:
|
clientAuth:
|
||||||
caFiles:
|
caFiles:
|
||||||
- foobar
|
- foobar
|
||||||
|
|
|
@ -481,9 +481,10 @@ func buildTLSOptions(ctx context.Context, client Client) map[string]tls.Options
|
||||||
}
|
}
|
||||||
|
|
||||||
tlsOptions[makeID(tlsOption.Namespace, tlsOption.Name)] = tls.Options{
|
tlsOptions[makeID(tlsOption.Namespace, tlsOption.Name)] = tls.Options{
|
||||||
MinVersion: tlsOption.Spec.MinVersion,
|
MinVersion: tlsOption.Spec.MinVersion,
|
||||||
MaxVersion: tlsOption.Spec.MaxVersion,
|
MaxVersion: tlsOption.Spec.MaxVersion,
|
||||||
CipherSuites: tlsOption.Spec.CipherSuites,
|
CipherSuites: tlsOption.Spec.CipherSuites,
|
||||||
|
CurvePreferences: tlsOption.Spec.CurvePreferences,
|
||||||
ClientAuth: tls.ClientAuth{
|
ClientAuth: tls.ClientAuth{
|
||||||
CAFiles: clientCAs,
|
CAFiles: clientCAs,
|
||||||
ClientAuthType: tlsOption.Spec.ClientAuth.ClientAuthType,
|
ClientAuthType: tlsOption.Spec.ClientAuth.ClientAuthType,
|
||||||
|
|
|
@ -19,11 +19,12 @@ type TLSOption struct {
|
||||||
|
|
||||||
// TLSOptionSpec configures TLS for an entry point
|
// TLSOptionSpec configures TLS for an entry point
|
||||||
type TLSOptionSpec struct {
|
type TLSOptionSpec struct {
|
||||||
MinVersion string `json:"minVersion,omitempty"`
|
MinVersion string `json:"minVersion,omitempty"`
|
||||||
MaxVersion string `json:"maxVersion,omitempty"`
|
MaxVersion string `json:"maxVersion,omitempty"`
|
||||||
CipherSuites []string `json:"cipherSuites,omitempty"`
|
CipherSuites []string `json:"cipherSuites,omitempty"`
|
||||||
ClientAuth ClientAuth `json:"clientAuth,omitempty"`
|
CurvePreferences []string `json:"curvePreferences,omitempty"`
|
||||||
SniStrict bool `json:"sniStrict,omitempty"`
|
ClientAuth ClientAuth `json:"clientAuth,omitempty"`
|
||||||
|
SniStrict bool `json:"sniStrict,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// +k8s:deepcopy-gen=true
|
// +k8s:deepcopy-gen=true
|
||||||
|
|
|
@ -803,6 +803,11 @@ func (in *TLSOptionSpec) DeepCopyInto(out *TLSOptionSpec) {
|
||||||
*out = make([]string, len(*in))
|
*out = make([]string, len(*in))
|
||||||
copy(*out, *in)
|
copy(*out, *in)
|
||||||
}
|
}
|
||||||
|
if in.CurvePreferences != nil {
|
||||||
|
in, out := &in.CurvePreferences, &out.CurvePreferences
|
||||||
|
*out = make([]string, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
in.ClientAuth.DeepCopyInto(&out.ClientAuth)
|
in.ClientAuth.DeepCopyInto(&out.ClientAuth)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,20 @@ var (
|
||||||
"TLS_CHACHA20_POLY1305_SHA256": tls.TLS_CHACHA20_POLY1305_SHA256,
|
"TLS_CHACHA20_POLY1305_SHA256": tls.TLS_CHACHA20_POLY1305_SHA256,
|
||||||
"TLS_FALLBACK_SCSV": tls.TLS_FALLBACK_SCSV,
|
"TLS_FALLBACK_SCSV": tls.TLS_FALLBACK_SCSV,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CurveIDs is a Map of TLS elliptic curves from crypto/tls
|
||||||
|
// Available CurveIDs defined at https://godoc.org/crypto/tls#CurveID,
|
||||||
|
// also allowing rfc names defined at https://tools.ietf.org/html/rfc8446#section-4.2.7
|
||||||
|
CurveIDs = map[string]tls.CurveID{
|
||||||
|
`secp256r1`: tls.CurveP256,
|
||||||
|
`CurveP256`: tls.CurveP256,
|
||||||
|
`secp384r1`: tls.CurveP384,
|
||||||
|
`CurveP384`: tls.CurveP384,
|
||||||
|
`secp521r1`: tls.CurveP521,
|
||||||
|
`CurveP521`: tls.CurveP521,
|
||||||
|
`x25519`: tls.X25519,
|
||||||
|
`X25519`: tls.X25519,
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Certificate holds a SSL cert/key pair
|
// Certificate holds a SSL cert/key pair
|
||||||
|
|
|
@ -16,11 +16,12 @@ type ClientAuth struct {
|
||||||
|
|
||||||
// Options configures TLS for an entry point
|
// Options configures TLS for an entry point
|
||||||
type Options struct {
|
type Options struct {
|
||||||
MinVersion string `json:"minVersion,omitempty" toml:"minVersion,omitempty" yaml:"minVersion,omitempty" export:"true"`
|
MinVersion string `json:"minVersion,omitempty" toml:"minVersion,omitempty" yaml:"minVersion,omitempty" export:"true"`
|
||||||
MaxVersion string `json:"maxVersion,omitempty" toml:"maxVersion,omitempty" yaml:"maxVersion,omitempty" export:"true"`
|
MaxVersion string `json:"maxVersion,omitempty" toml:"maxVersion,omitempty" yaml:"maxVersion,omitempty" export:"true"`
|
||||||
CipherSuites []string `json:"cipherSuites,omitempty" toml:"cipherSuites,omitempty" yaml:"cipherSuites,omitempty"`
|
CipherSuites []string `json:"cipherSuites,omitempty" toml:"cipherSuites,omitempty" yaml:"cipherSuites,omitempty"`
|
||||||
ClientAuth ClientAuth `json:"clientAuth,omitempty" toml:"clientAuth,omitempty" yaml:"clientAuth,omitempty"`
|
CurvePreferences []string `json:"curvePreferences,omitempty" toml:"curvePreferences,omitempty" yaml:"curvePreferences,omitempty"`
|
||||||
SniStrict bool `json:"sniStrict,omitempty" toml:"sniStrict,omitempty" yaml:"sniStrict,omitempty" export:"true"`
|
ClientAuth ClientAuth `json:"clientAuth,omitempty" toml:"clientAuth,omitempty" yaml:"clientAuth,omitempty"`
|
||||||
|
SniStrict bool `json:"sniStrict,omitempty" toml:"sniStrict,omitempty" yaml:"sniStrict,omitempty" export:"true"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// +k8s:deepcopy-gen=true
|
// +k8s:deepcopy-gen=true
|
||||||
|
|
|
@ -211,7 +211,7 @@ func buildTLSConfig(tlsOption Options) (*tls.Config, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the minimum TLS version if set in the config TOML
|
// Set the minimum TLS version if set in the config
|
||||||
if minConst, exists := MinVersion[tlsOption.MinVersion]; exists {
|
if minConst, exists := MinVersion[tlsOption.MinVersion]; exists {
|
||||||
conf.PreferServerCipherSuites = true
|
conf.PreferServerCipherSuites = true
|
||||||
conf.MinVersion = minConst
|
conf.MinVersion = minConst
|
||||||
|
@ -223,7 +223,7 @@ func buildTLSConfig(tlsOption Options) (*tls.Config, error) {
|
||||||
conf.MaxVersion = maxConst
|
conf.MaxVersion = maxConst
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the list of CipherSuites if set in the config TOML
|
// Set the list of CipherSuites if set in the config
|
||||||
if tlsOption.CipherSuites != nil {
|
if tlsOption.CipherSuites != nil {
|
||||||
// if our list of CipherSuites is defined in the entryPoint config, we can re-initialize the suites list as empty
|
// if our list of CipherSuites is defined in the entryPoint config, we can re-initialize the suites list as empty
|
||||||
conf.CipherSuites = make([]uint16, 0)
|
conf.CipherSuites = make([]uint16, 0)
|
||||||
|
@ -237,6 +237,20 @@ func buildTLSConfig(tlsOption Options) (*tls.Config, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the list of CurvePreferences/CurveIDs if set in the config
|
||||||
|
if tlsOption.CurvePreferences != nil {
|
||||||
|
conf.CurvePreferences = make([]tls.CurveID, 0)
|
||||||
|
// if our list of CurvePreferences/CurveIDs is defined in the config, we can re-initialize the list as empty
|
||||||
|
for _, curve := range tlsOption.CurvePreferences {
|
||||||
|
if curveID, exists := CurveIDs[curve]; exists {
|
||||||
|
conf.CurvePreferences = append(conf.CurvePreferences, curveID)
|
||||||
|
} else {
|
||||||
|
// CurveID listed in the toml does not exist in our listed
|
||||||
|
return nil, fmt.Errorf("invalid CurveID in curvePreferences: %s", curve)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return conf, nil
|
return conf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,11 @@ func (in *Options) DeepCopyInto(out *Options) {
|
||||||
*out = make([]string, len(*in))
|
*out = make([]string, len(*in))
|
||||||
copy(*out, *in)
|
copy(*out, *in)
|
||||||
}
|
}
|
||||||
|
if in.CurvePreferences != nil {
|
||||||
|
in, out := &in.CurvePreferences, &out.CurvePreferences
|
||||||
|
*out = make([]string, len(*in))
|
||||||
|
copy(*out, *in)
|
||||||
|
}
|
||||||
in.ClientAuth.DeepCopyInto(&out.ClientAuth)
|
in.ClientAuth.DeepCopyInto(&out.ClientAuth)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue