Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attempt ssh connections with and without mfa at the same time #23865

Merged
merged 7 commits into from Apr 5, 2023

Conversation

rosstimothy
Copy link
Contributor

tsh ssh would fallback to doing the mfa ceremony if connecting to the node with the already provisioned certificates failed with an access denied error. This incurs the cost of a round trip to the target host when per session mfa is required. To combat the additional latency when per session mfa is required we can attempt both the connection with the certs on hand AND start the per session mfa flow at the same time. If per session mfa is not required the client won't attempt the mfa ceremony which adds no impact there. If per session mfa is required the initial connection to the host is going to fail so the mfa ceremony will need to be performed any how.

For this to work we need to ensure that users are not prompted for mfa if completing the mfa ceremony will not actually help the user gain access to the host. If users just flat out do not have access to the host we don't want to confuse them by prompting them to touch a hardware key. Since tsh first calls
proto.AuthService/IsMFARequired before initiating the mfa ceremony we are guaranteed not to initiate the mfa ceremony when not required.

@rosstimothy rosstimothy marked this pull request as ready for review March 30, 2023 21:22
@rosstimothy rosstimothy force-pushed the tross/connect_to_node_race branch 2 times, most recently from 8768a3b to f4bdad9 Compare March 31, 2023 12:52
lib/client/api.go Outdated Show resolved Hide resolved
lib/client/api.go Outdated Show resolved Hide resolved
Comment on lines 1486 to 1489
clt, err := tc.connectToNodeWithMFA(ctx, proxyClient, nodeDetails, user, details)
return clt, trace.Wrap(err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 It so much cleaner now.

lib/client/api.go Outdated Show resolved Hide resolved
@smallinsky smallinsky self-requested a review March 31, 2023 13:38
@smallinsky smallinsky self-requested a review March 31, 2023 14:15
Copy link
Contributor

@smallinsky smallinsky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems that UT is broken:

{"caller":"web/terminal.go:699","component":"websocket","error":"access denied to root connecting to a31f1bb3-4bdb-4d37-b592-9258578d6bd0:0, close tcp 127.0.0.1:60034-\u003e127.0.0.1:37117: use of closed network connection","level":"warning","message":"Unable to stream terminal - failure connecting to host","session_id":"89ef396c-f46b-4d49-874c-ab2a54720f8c","timestamp":"2023-03-31T13:44:13Z"}
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x58ba51e]

goroutine 31640 [running]:
github.com/gravitational/teleport/lib/client.(*NodeClient).RunInteractiveShell(0x0, {0x93c90d8, 0xc01dd3a330}, {0x7af6eaf, 0x4}, {0x0, 0x0})
	/__w/teleport/teleport/lib/client/client.go:1604 +0x11e
github.com/gravitational/teleport/lib/web.(*TerminalHandler).streamTerminal(0xc0099338c0, 0xc003ed7520?, 0xc0013c7860?)
	/__w/teleport/teleport/lib/web/terminal.go:705 +0x42b
created by github.com/gravitational/teleport/lib/web.(*TerminalHandler).handler
	/__w/teleport/teleport/lib/web/terminal.go:425 +0xbfa
FAIL	github.com/gravitational/teleport/lib/web	144.483s
===================================================
Makefile:617: recipe for target 'test-go-unit' failed

@rosstimothy rosstimothy force-pushed the tross/connect_to_node_race branch 3 times, most recently from 61b4c19 to dc1ff24 Compare April 4, 2023 13:59
@rosstimothy
Copy link
Contributor Author

@atburke PTAL

`tsh ssh` would fallback to doing the mfa ceremony if connecting
to the node with the already provisioned certificates failed with
an access denied error. This incurs the cost of a round trip to
the target host when per session mfa is required. To combat the
additional latency when per session mfa is required we can
attempt both the connection with the certs on hand AND start the
per session mfa flow at the same time. If per session mfa is not
required the client won't attempt the mfa ceremony which adds no
impact there. If per session mfa is required the initial connection
to the host is going to fail so the mfa ceremony will need to be
performed any how.

For this to work we need to ensure that users are not prompted for
mfa if completing the mfa ceremony will not actually help the user
gain access to the host. If users just flat out do not have access
to the host we don't want to confuse them by prompting them to
touch a hardware key. Since `tsh` first calls
`proto.AuthService/IsMFARequired` before initiating the mfa ceremony
we are guaranteed not to initiate the mfa ceremony when not required.
@rosstimothy rosstimothy added this pull request to the merge queue Apr 5, 2023
Merged via the queue into master with commit 3113cd2 Apr 5, 2023
18 checks passed
@rosstimothy rosstimothy deleted the tross/connect_to_node_race branch April 5, 2023 18:32
@@ -3849,6 +3849,7 @@ func (process *TeleportProcess) initProxyEndpoint(conn *Connector) error {
}

tlscfg := serverTLSConfig.Clone()
setupTLSConfigClientCAsForCluster(tlscfg, accessPoint, clusterName)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably not a big deal but setupTLSConfigClientCAsForCluster sets tlsClone.ClientAuth = tls.VerifyClientCertIfGiven which conflict with next line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will cause issues in tests that rely on insecure dev mode. The grpc clients will all be rejected due to a cert signed by unknown authority error and we will fall back to using ssh. I've fixed this in #24195.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants