expose MinTLSVersion config for TLS handshake (#3103)

* expose MinTLSVersion config

* address comment

* use valid TLS version in config test
This commit is contained in:
ZetaoZhuang 2024-11-12 12:50:09 -08:00 коммит произвёл GitHub
Родитель 7997767d0b
Коммит 9b43fb7f8d
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
8 изменённых файлов: 78 добавлений и 8 удалений

Просмотреть файл

@ -33,5 +33,6 @@
"MellanoxMonitorIntervalSecs": 30, "MellanoxMonitorIntervalSecs": 30,
"AZRSettings": { "AZRSettings": {
"PopulateHomeAzCacheRetryIntervalSecs": 60 "PopulateHomeAzCacheRetryIntervalSecs": 60
} },
"MinTLSVersion": "TLS 1.2"
} }

Просмотреть файл

@ -54,6 +54,7 @@ type CNSConfig struct {
WatchPods bool `json:"-"` WatchPods bool `json:"-"`
WireserverIP string WireserverIP string
GRPCSettings GRPCSettings GRPCSettings GRPCSettings
MinTLSVersion string
} }
type TelemetrySettings struct { type TelemetrySettings struct {
@ -229,6 +230,10 @@ func SetCNSConfigDefaults(config *CNSConfig) {
if config.GRPCSettings.Port == 0 { if config.GRPCSettings.Port == 0 {
config.GRPCSettings.Port = 8080 config.GRPCSettings.Port = 8080
} }
if config.MinTLSVersion == "" {
config.MinTLSVersion = "TLS 1.2"
}
config.GRPCSettings.Enable = false config.GRPCSettings.Enable = false
config.WatchPods = config.EnableIPAMv2 || config.EnableSwiftV2 config.WatchPods = config.EnableIPAMv2 || config.EnableSwiftV2
} }

Просмотреть файл

@ -86,9 +86,10 @@ func TestReadConfigFromFile(t *testing.T) {
AZRSettings: AZRSettings{ AZRSettings: AZRSettings{
PopulateHomeAzCacheRetryIntervalSecs: 60, PopulateHomeAzCacheRetryIntervalSecs: 60,
}, },
UseHTTPS: true, UseHTTPS: true,
UseMTLS: true, UseMTLS: true,
WireserverIP: "168.63.129.16", WireserverIP: "168.63.129.16",
MinTLSVersion: "TLS 1.3",
}, },
wantErr: false, wantErr: false,
}, },
@ -220,6 +221,7 @@ func TestSetCNSConfigDefaults(t *testing.T) {
IPAddress: "localhost", IPAddress: "localhost",
Port: 8080, Port: 8080,
}, },
MinTLSVersion: "TLS 1.2",
}, },
}, },
{ {
@ -250,6 +252,7 @@ func TestSetCNSConfigDefaults(t *testing.T) {
IPAddress: "192.168.1.1", IPAddress: "192.168.1.1",
Port: 9090, Port: 9090,
}, },
MinTLSVersion: "TLS 1.3",
}, },
want: CNSConfig{ want: CNSConfig{
ChannelMode: "Other", ChannelMode: "Other",
@ -279,6 +282,7 @@ func TestSetCNSConfigDefaults(t *testing.T) {
IPAddress: "192.168.1.1", IPAddress: "192.168.1.1",
Port: 9090, Port: 9090,
}, },
MinTLSVersion: "TLS 1.3",
}, },
}, },
} }

3
cns/configuration/testdata/good.json поставляемый
Просмотреть файл

@ -34,5 +34,6 @@
"WireserverIP": "168.63.129.16", "WireserverIP": "168.63.129.16",
"AZRSettings": { "AZRSettings": {
"PopulateHomeAzCacheRetryIntervalSecs": 60 "PopulateHomeAzCacheRetryIntervalSecs": 60
} },
"MinTLSVersion": "TLS 1.3"
} }

Просмотреть файл

@ -28,6 +28,8 @@ const (
genericData = "com.microsoft.azure.network.generic" genericData = "com.microsoft.azure.network.generic"
) )
var errTLSConfig = errors.New("unsupported TLS version name from config")
// Service defines Container Networking Service. // Service defines Container Networking Service.
type Service struct { type Service struct {
*common.Service *common.Service
@ -179,10 +181,14 @@ func getTLSConfigFromFile(tlsSettings localtls.TlsSettings) (*tls.Config, error)
PrivateKey: privateKey, PrivateKey: privateKey,
Leaf: leafCertificate, Leaf: leafCertificate,
} }
minTLSVersionNumber, err := parseTLSVersionName(tlsSettings.MinTLSVersion)
if err != nil {
return nil, errors.Wrap(err, "parsing MinTLSVersion from config")
}
tlsConfig := &tls.Config{ tlsConfig := &tls.Config{
MaxVersion: tls.VersionTLS13, MaxVersion: tls.VersionTLS13,
MinVersion: tls.VersionTLS12, MinVersion: minTLSVersionNumber,
Certificates: []tls.Certificate{ Certificates: []tls.Certificate{
tlsCert, tlsCert,
}, },
@ -226,8 +232,13 @@ func getTLSConfigFromKeyVault(tlsSettings localtls.TlsSettings, errChan chan<- e
errChan <- cr.Refresh(ctx, tlsSettings.KeyVaultCertificateRefreshInterval) 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{ tlsConfig := tls.Config{
MinVersion: tls.VersionTLS12, MinVersion: minTLSVersionNumber,
MaxVersion: tls.VersionTLS13, MaxVersion: tls.VersionTLS13,
GetCertificate: func(_ *tls.ClientHelloInfo) (*tls.Certificate, error) { GetCertificate: func(_ *tls.ClientHelloInfo) (*tls.Certificate, error) {
return cr.GetCertificate(), nil return cr.GetCertificate(), nil
@ -316,3 +327,16 @@ func (service *Service) SendErrorResponse(w http.ResponseWriter, errMsg error) {
err := acn.Encode(w, &resp) err := acn.Encode(w, &resp)
logger.Errorf("[%s] %+v %s.", service.Name, &resp, err.Error()) 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)
}
}

Просмотреть файл

@ -776,6 +776,7 @@ func main() {
MSIResourceID: cnsconfig.MSISettings.ResourceID, MSIResourceID: cnsconfig.MSISettings.ResourceID,
KeyVaultCertificateRefreshInterval: time.Duration(cnsconfig.KeyVaultSettings.RefreshIntervalInHrs) * time.Hour, KeyVaultCertificateRefreshInterval: time.Duration(cnsconfig.KeyVaultSettings.RefreshIntervalInHrs) * time.Hour,
UseMTLS: cnsconfig.UseMTLS, UseMTLS: cnsconfig.UseMTLS,
MinTLSVersion: cnsconfig.MinTLSVersion,
} }
} }

Просмотреть файл

@ -76,6 +76,7 @@ func TestNewService(t *testing.T) {
TLSPort: "10091", TLSPort: "10091",
TLSSubjectName: "localhost", TLSSubjectName: "localhost",
TLSCertificatePath: testCertFilePath, TLSCertificatePath: testCertFilePath,
MinTLSVersion: "TLS 1.2",
} }
svc, err := NewService(config.Name, config.Version, config.ChannelMode, config.Store) svc, err := NewService(config.Name, config.Version, config.ChannelMode, config.Store)
@ -94,10 +95,13 @@ func TestNewService(t *testing.T) {
err = svc.StartListener(config) err = svc.StartListener(config)
require.NoError(t, err) require.NoError(t, err)
minTLSVersionNumber, err := parseTLSVersionName(config.TLSSettings.MinTLSVersion)
require.NoError(t, err)
tlsClient := &http.Client{ tlsClient := &http.Client{
Transport: &http.Transport{ Transport: &http.Transport{
TLSClientConfig: &tls.Config{ TLSClientConfig: &tls.Config{
MinVersion: tls.VersionTLS12, MinVersion: minTLSVersionNumber,
MaxVersion: tls.VersionTLS13, MaxVersion: tls.VersionTLS13,
ServerName: config.TLSSettings.TLSSubjectName, ServerName: config.TLSSettings.TLSSubjectName,
// #nosec G402 for test purposes only // #nosec G402 for test purposes only
@ -134,6 +138,7 @@ func TestNewService(t *testing.T) {
TLSSubjectName: "localhost", TLSSubjectName: "localhost",
TLSCertificatePath: testCertFilePath, TLSCertificatePath: testCertFilePath,
UseMTLS: true, UseMTLS: true,
MinTLSVersion: "TLS 1.2",
} }
svc, err := NewService(config.Name, config.Version, config.ChannelMode, config.Store) svc, err := NewService(config.Name, config.Version, config.ChannelMode, config.Store)
@ -322,3 +327,31 @@ func createTestCertificate(t *testing.T) string {
return testCertFilePath return testCertFilePath
} }
func TestTLSVersionNumber(t *testing.T) {
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)
})
}

Просмотреть файл

@ -14,6 +14,7 @@ type TlsSettings struct {
MSIResourceID string MSIResourceID string
KeyVaultCertificateRefreshInterval time.Duration KeyVaultCertificateRefreshInterval time.Duration
UseMTLS bool UseMTLS bool
MinTLSVersion string
} }
func GetTlsCertificateRetriever(settings TlsSettings) (TlsCertificateRetriever, error) { func GetTlsCertificateRetriever(settings TlsSettings) (TlsCertificateRetriever, error) {