Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

expose MinTLSVersion config for TLS handshake #3103

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion cns/configuration/cns_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@
"MellanoxMonitorIntervalSecs": 30,
"AZRSettings": {
"PopulateHomeAzCacheRetryIntervalSecs": 60
}
},
"MinTLSVersion": "TLS 1.2"
}
5 changes: 5 additions & 0 deletions cns/configuration/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ type CNSConfig struct {
WatchPods bool `json:"-"`
WireserverIP string
GRPCSettings GRPCSettings
MinTLSVersion string
}

type TelemetrySettings struct {
Expand Down Expand Up @@ -229,6 +230,10 @@ func SetCNSConfigDefaults(config *CNSConfig) {
if config.GRPCSettings.Port == 0 {
config.GRPCSettings.Port = 8080
}

if config.MinTLSVersion == "" {
config.MinTLSVersion = "TLS 1.2"
}
config.GRPCSettings.Enable = false
config.WatchPods = config.EnableIPAMv2 || config.EnableSwiftV2
}
Expand Down
10 changes: 7 additions & 3 deletions cns/configuration/configuration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,10 @@ func TestReadConfigFromFile(t *testing.T) {
AZRSettings: AZRSettings{
PopulateHomeAzCacheRetryIntervalSecs: 60,
},
UseHTTPS: true,
UseMTLS: true,
WireserverIP: "168.63.129.16",
UseHTTPS: true,
UseMTLS: true,
WireserverIP: "168.63.129.16",
MinTLSVersion: "TLS 1.3",
},
wantErr: false,
},
Expand Down Expand Up @@ -220,6 +221,7 @@ func TestSetCNSConfigDefaults(t *testing.T) {
IPAddress: "localhost",
Port: 8080,
},
MinTLSVersion: "TLS 1.2",
},
},
{
Expand Down Expand Up @@ -250,6 +252,7 @@ func TestSetCNSConfigDefaults(t *testing.T) {
IPAddress: "192.168.1.1",
Port: 9090,
},
MinTLSVersion: "TLS 1.3",
},
want: CNSConfig{
ChannelMode: "Other",
Expand Down Expand Up @@ -279,6 +282,7 @@ func TestSetCNSConfigDefaults(t *testing.T) {
IPAddress: "192.168.1.1",
Port: 9090,
},
MinTLSVersion: "TLS 1.3",
},
},
}
Expand Down
3 changes: 2 additions & 1 deletion cns/configuration/testdata/good.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,6 @@
"WireserverIP": "168.63.129.16",
"AZRSettings": {
"PopulateHomeAzCacheRetryIntervalSecs": 60
}
},
"MinTLSVersion": "TLS 1.3"
}
28 changes: 26 additions & 2 deletions cns/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ const (
genericData = "com.microsoft.azure.network.generic"
)

var errTLSConfig = errors.New("unsupported TLS version name from config")

// Service defines Container Networking Service.
type Service struct {
*common.Service
Expand Down Expand Up @@ -179,10 +181,14 @@ func getTLSConfigFromFile(tlsSettings localtls.TlsSettings) (*tls.Config, error)
PrivateKey: privateKey,
Leaf: leafCertificate,
}
minTLSVersionNumber, err := parseTLSVersionName(tlsSettings.MinTLSVersion)
if err != nil {
return nil, errors.Wrap(err, "parsing MinTLSVersion from config")
}

tlsConfig := &tls.Config{
MaxVersion: tls.VersionTLS13,
MinVersion: tls.VersionTLS12,
MinVersion: minTLSVersionNumber,
Certificates: []tls.Certificate{
tlsCert,
},
Expand Down Expand Up @@ -226,8 +232,13 @@ func getTLSConfigFromKeyVault(tlsSettings localtls.TlsSettings, errChan chan<- e
errChan <- cr.Refresh(ctx, tlsSettings.KeyVaultCertificateRefreshInterval)
}()

minTLSVersionNumber, err := parseTLSVersionName(tlsSettings.MinTLSVersion)
if err != nil {
return nil, errors.Wrap(err, "parsing MinTLSVersion from config")
}

tlsConfig := tls.Config{
MinVersion: tls.VersionTLS12,
MinVersion: minTLSVersionNumber,
MaxVersion: tls.VersionTLS13,
GetCertificate: func(_ *tls.ClientHelloInfo) (*tls.Certificate, error) {
return cr.GetCertificate(), nil
Expand Down Expand Up @@ -316,3 +327,16 @@ func (service *Service) SendErrorResponse(w http.ResponseWriter, errMsg error) {
err := acn.Encode(w, &resp)
logger.Errorf("[%s] %+v %s.", service.Name, &resp, err.Error())
}

// parseTLSVersionName returns the version number for the provided TLS version name
// (e.g. 0x0301)
func parseTLSVersionName(versionName string) (uint16, error) {
switch versionName {
case "TLS 1.2":
return tls.VersionTLS12, nil
case "TLS 1.3":
return tls.VersionTLS13, nil
default:
return 0, errors.Wrapf(errTLSConfig, "version name %s", versionName)
}
}
1 change: 1 addition & 0 deletions cns/service/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,7 @@ func main() {
MSIResourceID: cnsconfig.MSISettings.ResourceID,
KeyVaultCertificateRefreshInterval: time.Duration(cnsconfig.KeyVaultSettings.RefreshIntervalInHrs) * time.Hour,
UseMTLS: cnsconfig.UseMTLS,
MinTLSVersion: cnsconfig.MinTLSVersion,
}
}

Expand Down
35 changes: 34 additions & 1 deletion cns/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ func TestNewService(t *testing.T) {
TLSPort: "10091",
TLSSubjectName: "localhost",
TLSCertificatePath: testCertFilePath,
MinTLSVersion: "TLS 1.2",
}

svc, err := NewService(config.Name, config.Version, config.ChannelMode, config.Store)
Expand All @@ -94,10 +95,13 @@ func TestNewService(t *testing.T) {
err = svc.StartListener(config)
require.NoError(t, err)

minTLSVersionNumber, err := parseTLSVersionName(config.TLSSettings.MinTLSVersion)
require.NoError(t, err)

tlsClient := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
MinVersion: tls.VersionTLS12,
MinVersion: minTLSVersionNumber,
MaxVersion: tls.VersionTLS13,
ServerName: config.TLSSettings.TLSSubjectName,
// #nosec G402 for test purposes only
Expand Down Expand Up @@ -134,6 +138,7 @@ func TestNewService(t *testing.T) {
TLSSubjectName: "localhost",
TLSCertificatePath: testCertFilePath,
UseMTLS: true,
MinTLSVersion: "TLS 1.2",
}

svc, err := NewService(config.Name, config.Version, config.ChannelMode, config.Store)
Expand Down Expand Up @@ -322,3 +327,31 @@ func createTestCertificate(t *testing.T) string {

return testCertFilePath
}

func TestTLSVersionNumber(t *testing.T) {
jackieluc marked this conversation as resolved.
Show resolved Hide resolved
t.Run("unsupported ServerSettings.MinTLSVersion TLS 1.0", func(t *testing.T) {
versionNumber, err := parseTLSVersionName("TLS 1.0")
require.Equal(t, uint16(0), versionNumber)
require.Error(t, err)
require.ErrorContains(t, err, "unsupported TLS version name")
})

t.Run("unsupported ServerSettings.MinTLSVersion TLS 1.1", func(t *testing.T) {
versionNumber, err := parseTLSVersionName("TLS 1.1")
require.Equal(t, uint16(0), versionNumber)
require.Error(t, err)
require.ErrorContains(t, err, "unsupported TLS version name")
})
t.Run("unsupported ServerSettings.MinTLSVersion TLS 1.4", func(t *testing.T) {
versionNumber, err := parseTLSVersionName("TLS 1.4")
require.Equal(t, uint16(0), versionNumber)
require.Error(t, err)
require.ErrorContains(t, err, "unsupported TLS version name")
})

t.Run("valid ServerSettings.MinTLSVersion", func(t *testing.T) {
versionNumber, err := parseTLSVersionName("TLS 1.2")
require.Equal(t, uint16(tls.VersionTLS12), versionNumber)
require.NoError(t, err)
})
}
1 change: 1 addition & 0 deletions server/tls/tlscertificate_retriever.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type TlsSettings struct {
MSIResourceID string
KeyVaultCertificateRefreshInterval time.Duration
UseMTLS bool
MinTLSVersion string
}

func GetTlsCertificateRetriever(settings TlsSettings) (TlsCertificateRetriever, error) {
Expand Down
Loading