mirror of
https://github.com/gravitational/teleport.git
synced 2026-09-21 14:35:22 +08:00
Add debug logging to tsh when there is a SAN mismatch connecting to Auth via Proxy (#61059)
* Add debug logging to `tsh login` when there is a DNS SAN mismatch Signed-off-by: Chris Thach <chris.thach@goteleport.com> * Fix formatting so it is consistent Signed-off-by: Chris Thach <chris.thach@goteleport.com> * Filter for only proxy env vars. Improve message. Signed-off-by: Chris Thach <chris.thach@goteleport.com> * Add unit tests for formatCertError. Signed-off-by: Chris Thach <chris.thach@goteleport.com> * Revert copyright update * Pretty print proxy env and certificate Signed-off-by: Chris Thach <chris.thach@goteleport.com> * Print NotBefore Signed-off-by: Chris Thach <chris.thach@goteleport.com> * Add case where there is a network intermediary Signed-off-by: Chris Thach <chris.thach@goteleport.com> * Revert general HostnameError case. Add message for just the case of connecting to Auth. Signed-off-by: Chris Thach <chris.thach@goteleport.com> * Apply suggestions from code review Co-authored-by: Zac Bergquist <zac.bergquist@goteleport.com> * Fix missing deref. Only build in the special case. Signed-off-by: Chris Thach <chris.thach@goteleport.com> * Remove internal cluster domain and move hostname to debug info. Signed-off-by: Chris Thach <chris.thach@goteleport.com> * Add vertical space. Signed-off-by: Chris Thach <chris.thach@goteleport.com> --------- Signed-off-by: Chris Thach <chris.thach@goteleport.com> Co-authored-by: Zac Bergquist <zac.bergquist@goteleport.com>
This commit is contained in:
co-authored by
Zac Bergquist
parent
f31407ca75
commit
e16a7ad8ef
@@ -238,6 +238,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(),
|
||||
|
||||
@@ -20,6 +20,7 @@ package utils
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"testing"
|
||||
@@ -212,3 +213,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)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user