Skip to content
Merged
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
45 changes: 45 additions & 0 deletions lib/utils/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,51 @@ func formatCertError(err error) string {

var hostnameErr x509.HostnameError
if errors.As(err, &hostnameErr) {
// Special case for connecting to Auth via Proxy using internal cluster domain.
if strings.HasSuffix(hostnameErr.Host, ".teleport.cluster.local") {
var proxyEnvBuilder strings.Builder
for _, key := range []string{
"https_proxy", "http_proxy", "no_proxy",
"HTTPS_PROXY", "HTTP_PROXY", "NO_PROXY",
} {
if val, ok := os.LookupEnv(key); ok {
fmt.Fprintf(&proxyEnvBuilder, " %s: %s\n", key, val)
}
}

return fmt.Sprintf(`Cannot connect to the Auth service via the Teleport Proxy.

There might be one or more network intermediaries (like a proxy or VPN) that are modifying your connection before it
reaches the Teleport Proxy. These intermediaries can alter how your connection is seen by the Teleport Proxy and
routed, leading to certificate mismatches.

To fix this, ensure that any network intermediaries are properly configured and not interfering with your connection.

DEBUG INFO:
Host: %s

Proxy Environment Variables:
%s
Server Certificate Details:
Subject: %s
Issuer: %s
Serial Number: %s
Not Before: %s
Not After: %s
DNS Names: %v
IP Addresses: %v`,
hostnameErr.Host,
proxyEnvBuilder.String(),
hostnameErr.Certificate.Subject,
hostnameErr.Certificate.Issuer,
hostnameErr.Certificate.SerialNumber,
hostnameErr.Certificate.NotBefore,
hostnameErr.Certificate.NotAfter,
hostnameErr.Certificate.DNSNames,
hostnameErr.Certificate.IPAddresses,
)
}

return fmt.Sprintf("Cannot establish https connection to %s:\n%s\n%s\n",
hostnameErr.Host,
hostnameErr.Error(),
Expand Down
43 changes: 43 additions & 0 deletions lib/utils/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ package utils
import (
"bytes"
"crypto/x509"
"errors"
"fmt"
"io"
"log/slog"
Expand Down Expand Up @@ -295,3 +296,45 @@ func TestFilterArguments(t *testing.T) {
require.Equal(t, tt.expected, FilterArguments(tt.args, app.Model()), fmt.Sprintf("test case %v", i))
}
}

// TestFormatCertError tests the formatCertError function for various x509 error types and messages.
func TestFormatCertError(t *testing.T) {
t.Run("UnknownAuthorityError", func(t *testing.T) {
err := x509.UnknownAuthorityError{}
msg := formatCertError(err)
require.Contains(t, msg, "The proxy you are connecting to has presented a certificate signed by a")
})

t.Run("HostnameErrorConnectingToAuth", func(t *testing.T) {
cert := &x509.Certificate{Raw: []byte("dummy")}
err := x509.HostnameError{Certificate: cert, Host: "99999999999999999999999999999999.teleport.cluster.local"}
msg := formatCertError(err)
require.Contains(t, msg, "Cannot connect to the Auth service via the Teleport Proxy.")
require.Contains(t, msg, "Host: 99999999999999999999999999999999.teleport.cluster.local")
})

t.Run("HostnameError", func(t *testing.T) {
cert := &x509.Certificate{Raw: []byte("dummy")}
err := x509.HostnameError{Certificate: cert, Host: "example.com"}
msg := formatCertError(err)
require.Contains(t, msg, "Cannot establish https connection to example.com")
})

t.Run("CertificateInvalidError", func(t *testing.T) {
err := x509.CertificateInvalidError{Reason: x509.Expired, Cert: &x509.Certificate{}}
msg := formatCertError(err)
require.Contains(t, msg, "The certificate presented by the proxy is invalid")
})

t.Run("CertificateNotTrustedError", func(t *testing.T) {
err := errors.New("certificate is not trusted")
msg := formatCertError(err)
require.Contains(t, msg, "The proxy you are connecting to has presented a certificate signed by")
})

t.Run("NoMatch", func(t *testing.T) {
err := errors.New("some other error")
msg := formatCertError(err)
require.Empty(t, msg)
})
}
Loading