From 3f8d1738dec358d15056e9f8a2809108a3af24d4 Mon Sep 17 00:00:00 2001 From: Gyuho Lee Date: Fri, 13 Apr 2018 13:53:34 -0700 Subject: [PATCH] pkg/transport: document how TLS reload works with IP only certs Signed-off-by: Gyuho Lee --- pkg/transport/listener.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/pkg/transport/listener.go b/pkg/transport/listener.go index 1725aaad400..d29d7f94b63 100644 --- a/pkg/transport/listener.go +++ b/pkg/transport/listener.go @@ -194,6 +194,26 @@ func SelfCert(lg *zap.Logger, dirpath string, hosts []string) (info TLSInfo, err return SelfCert(lg, dirpath, hosts) } +// baseConfig is called on initial TLS handshake start. +// +// Previously, +// 1. Server has non-empty (*tls.Config).Certificates on client hello +// 2. Server calls (*tls.Config).GetCertificate iff: +// - Server's (*tls.Config).Certificates is not empty, or +// - Client supplies SNI; non-empty (*tls.ClientHelloInfo).ServerName +// +// When (*tls.Config).Certificates is always populated on initial handshake, +// client is expected to provide a valid matching SNI to pass the TLS +// verification, thus trigger server (*tls.Config).GetCertificate to reload +// TLS assets. However, a cert whose SAN field does not include domain names +// but only IP addresses, has empty (*tls.ClientHelloInfo).ServerName, thus +// it was never able to trigger TLS reload on initial handshake; first +// ceritifcate object was being used, never being updated. +// +// Now, (*tls.Config).Certificates is created empty on initial TLS client +// handshake, in order to trigger (*tls.Config).GetCertificate and populate +// rest of the certificates on every new TLS connection, even when client +// SNI is empty (e.g. cert only includes IPs). func (info TLSInfo) baseConfig() (*tls.Config, error) { if info.KeyFile == "" || info.CertFile == "" { return nil, fmt.Errorf("KeyFile and CertFile must both be present[key: %v, cert: %v]", info.KeyFile, info.CertFile)