diff --git a/lib/service/service.go b/lib/service/service.go index 1136118da04c8..ea548262c13f5 100644 --- a/lib/service/service.go +++ b/lib/service/service.go @@ -5312,7 +5312,26 @@ func initSelfSignedHTTPSCert(cfg *servicecfg.Config) (err error) { } cfg.Log.Warningf("Generating self-signed key and cert to %v %v.", keyPath, certPath) - creds, err := cert.GenerateSelfSignedCert([]string{cfg.Hostname, "localhost"}) + hosts := []string{cfg.Hostname, "localhost"} + var ips []string + + // add web public address hosts to self-signed cert + for _, addr := range cfg.Proxy.PublicAddrs { + proxyHost, _, err := net.SplitHostPort(addr.String()) + if err != nil { + // log and skip error since this is a nice to have + cfg.Log.Errorf("Error parsing proxy.public_address %v, skipping adding to self-signed cert: %v", addr.String(), err) + continue + } + // If the address is a IP have it added as IP SAN + if ip := net.ParseIP(proxyHost); ip != nil { + ips = append(ips, proxyHost) + } else { + hosts = append(hosts, proxyHost) + } + } + + creds, err := cert.GenerateSelfSignedCert(hosts, ips) if err != nil { return trace.Wrap(err) } diff --git a/lib/srv/db/access_test.go b/lib/srv/db/access_test.go index b564c847cf40f..2c1dd061daaed 100644 --- a/lib/srv/db/access_test.go +++ b/lib/srv/db/access_test.go @@ -1853,7 +1853,7 @@ func (c *testContext) createUserAndRole(ctx context.Context, t *testing.T, userN // makeTLSConfig returns tls configuration for the test's tls listener. func (c *testContext) makeTLSConfig(t *testing.T) *tls.Config { - creds, err := cert.GenerateSelfSignedCert([]string{"localhost"}) + creds, err := cert.GenerateSelfSignedCert([]string{"localhost"}, []string{}) require.NoError(t, err) cert, err := tls.X509KeyPair(creds.Cert, creds.PrivateKey) require.NoError(t, err) diff --git a/lib/teleterm/gateway/db_middleware_test.go b/lib/teleterm/gateway/db_middleware_test.go index 5166d05086175..1101efbe83598 100644 --- a/lib/teleterm/gateway/db_middleware_test.go +++ b/lib/teleterm/gateway/db_middleware_test.go @@ -35,7 +35,7 @@ import ( ) func TestDBMiddleware_OnNewConnection(t *testing.T) { - testCert, err := cert.GenerateSelfSignedCert([]string{"localhost"}) + testCert, err := cert.GenerateSelfSignedCert([]string{"localhost"}, nil) require.NoError(t, err) tlsCert, err := keys.X509KeyPair(testCert.Cert, testCert.PrivateKey) require.NoError(t, err) diff --git a/lib/teleterm/grpccredentials.go b/lib/teleterm/grpccredentials.go index 45ee507e9ddcd..634b2199152cd 100644 --- a/lib/teleterm/grpccredentials.go +++ b/lib/teleterm/grpccredentials.go @@ -108,7 +108,7 @@ func generateAndSaveCert(targetPath string) (tls.Certificate, error) { } defer os.Remove(tempFile.Name()) - cert, err := cert.GenerateSelfSignedCert([]string{"localhost"}) + cert, err := cert.GenerateSelfSignedCert([]string{"localhost"}, nil) if err != nil { return tls.Certificate{}, trace.Wrap(err, "failed to generate the certificate") } diff --git a/lib/utils/cert/selfsigned.go b/lib/utils/cert/selfsigned.go index 4db640a3789fe..8957a018a3ae1 100644 --- a/lib/utils/cert/selfsigned.go +++ b/lib/utils/cert/selfsigned.go @@ -50,7 +50,7 @@ type Credentials struct { // GenerateSelfSignedCert generates a self-signed certificate that // is valid for given domain names and ips, returns PEM-encoded bytes with key and cert -func GenerateSelfSignedCert(hostNames []string) (*Credentials, error) { +func GenerateSelfSignedCert(hostNames []string, ipAddresses []string) (*Credentials, error) { priv, err := native.GenerateRSAPrivateKey() if err != nil { return nil, trace.Wrap(err) @@ -87,6 +87,14 @@ func GenerateSelfSignedCert(hostNames []string) (*Credentials, error) { if ips != nil { template.IPAddresses = append(ips, net.ParseIP("::1")) } + for _, ip := range ipAddresses { + ipParsed := net.ParseIP(ip) + if ipParsed == nil { + return nil, trace.Errorf("Unable to parse IP address for self-signed certificate (%v)", ip) + } + template.IPAddresses = append(template.IPAddresses, ipParsed) + } + derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) if err != nil { return nil, trace.Wrap(err) diff --git a/lib/utils/utils_test.go b/lib/utils/utils_test.go index 7b9bc8879a6bc..dcb50f8fb48f9 100644 --- a/lib/utils/utils_test.go +++ b/lib/utils/utils_test.go @@ -91,7 +91,7 @@ func TestHostUUIDRegenerateEmpty(t *testing.T) { func TestSelfSignedCert(t *testing.T) { t.Parallel() - creds, err := cert.GenerateSelfSignedCert([]string{"example.com"}) + creds, err := cert.GenerateSelfSignedCert([]string{"example.com"}, []string{}) require.NoError(t, err) require.NotNil(t, creds) require.Equal(t, 4, len(creds.PublicKey)/100)