From 71dbd95f3fd1d3c78dc176a514f61908c127b726 Mon Sep 17 00:00:00 2001 From: Andrew Lytvynov Date: Mon, 11 May 2020 14:24:39 -0700 Subject: [PATCH] Improve error message for IoT node without a tunnel When a node doesn't have an active tunnel, the error should say so clearly. This is reflected in 2 places: - proxy error log - tsh user output Also, use trace.UserMessage instead of utils.UserMessageFromError. utils.UserMessageFromError will return a full stack trace when calling process (proxy) is in debug mode. The user shouldn't see this. --- lib/reversetunnel/api.go | 9 +++++++++ lib/reversetunnel/localsite.go | 7 ++++++- lib/srv/regular/sshserver.go | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/reversetunnel/api.go b/lib/reversetunnel/api.go index ae0b0c47ff8..8018ba051d9 100644 --- a/lib/reversetunnel/api.go +++ b/lib/reversetunnel/api.go @@ -18,6 +18,7 @@ package reversetunnel import ( "context" + "fmt" "net" "time" @@ -54,6 +55,14 @@ type DialParams struct { ServerID string } +func (params DialParams) String() string { + to := params.To.String() + if to == "" { + to = params.ServerID + } + return fmt.Sprintf("from: %q to: %q", params.From, to) +} + // RemoteSite represents remote teleport site that can be accessed via // teleport tunnel or directly by proxy // diff --git a/lib/reversetunnel/localsite.go b/lib/reversetunnel/localsite.go index f3f6db5dd70..68300e2f700 100644 --- a/lib/reversetunnel/localsite.go +++ b/lib/reversetunnel/localsite.go @@ -181,7 +181,7 @@ func (s *localSite) Dial(params DialParams) (net.Conn, error) { } func (s *localSite) DialTCP(params DialParams) (net.Conn, error) { - s.log.Debugf("Dialing from %v to %v.", params.From, params.To) + s.log.Debugf("Dialing %v.", params) conn, _, err := s.getConn(params) if err != nil { @@ -266,6 +266,11 @@ func (s *localSite) getConn(params DialParams) (conn net.Conn, useTunnel bool, e return nil, false, trace.Wrap(err) } + // This node can only be reached over a tunnel, don't attempt to dial + // remotely. + if params.To.String() == "" { + return nil, false, trace.ConnectionProblem(err, "node is offline, please try again later") + } // If no tunnel connection was found, dial to the target host. dialer := proxy.DialerFromEnvironment(params.To.String()) conn, err = dialer.DialTimeout(params.To.Network(), params.To.String(), defaults.DefaultDialTimeout) diff --git a/lib/srv/regular/sshserver.go b/lib/srv/regular/sshserver.go index b928973297c..437af0b01e5 100644 --- a/lib/srv/regular/sshserver.go +++ b/lib/srv/regular/sshserver.go @@ -1411,7 +1411,7 @@ func (s *Server) handleProxyJump(ccx *sshutils.ConnectionContext, identityContex func (s *Server) replyError(ch ssh.Channel, req *ssh.Request, err error) { log.Error(err) - message := []byte(utils.UserMessageFromError(err)) + message := []byte(trace.UserMessage(err)) ch.Stderr().Write(message) if req.WantReply { req.Reply(false, message)