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

API client connection overhaul #5625

Merged
merged 28 commits into from
Mar 23, 2021
Merged

API client connection overhaul #5625

merged 28 commits into from
Mar 23, 2021

Conversation

Joerger
Copy link
Contributor

@Joerger Joerger commented Feb 18, 2021

This PR adds support for connecting client through proxy tunnel address and web proxy address, and fixes client initialization performance issues with concurrent connection attempts. A lot of code had to be moved around to enable proxy dialing while maintaining a very small go module in client/api.

Changes:

  • Added support for connecting to server via proxy tunnel address.a
    • Added NewTunnelDialer function to create an ssh tunnel dialer for the client.
    • Added SSHConfig method to Credentials, only IdentityCreds implements it fully.
    • Added barebones http client for retrieving PublicTunnelAddr from web proxy in findTunnelAddr().
    • Moved logic needed for ssh tunnel dialer to contextdialer.go, ssh.go, and chconn.go in the api/client package, and refactor moved code to reduce imports.
      • Moved SSH logic in Key methods to api/utils/ssh.go to be reused by IdentityFile.
      • Moved LoadIdentity from tsh/common to lib/client/interfaces.go as KeyFromIdentityFile. Moved logic specific to actually loading the identityFile to ReadIdentityFile.
  • Added synchronous connection logic to client constructor to concurrently try all connection options, either using the first connection to succeed, or returning all errors.
    • Completely refactored connect function to enable synchronous logic and improve separation of concerns.

To expand on the client initialization performance issue, the client takes a list of Credentials and a list of Addresses to connect the client to a server. The addresses can be web proxy, tunnel proxy, or auth server addresses. So each Credential+Address combination has to be dialed as each type of address, leading to 3nm performance where n is # of addrs and m is # of creds. In practice, both n and m should be low, but with a default dial timeout of 30 seconds, it quickly become unusable. Given the way the grpc dialer behaves, there isn't a good way (that I could come up with) to handle these combinations without dialing each one and testing the connection one my one. This led me to the solution of concurrently trying all combinations, which quickly hones in on a connection. I'm very open to other solution ideas as this feels a bit overly complicated for a normal API client.

Copy link
Contributor

@awly awly left a comment

Choose a reason for hiding this comment

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

Please also manually test that dialing auth directly and via a proxy works

api/client/client.go Outdated Show resolved Hide resolved
api/client/credentials_test.go Outdated Show resolved Hide resolved
api/client/identityfile.go Outdated Show resolved Hide resolved
api/client/tunneldialer.go Outdated Show resolved Hide resolved
api/client/tunneldialer.go Outdated Show resolved Hide resolved
api/utils/ssh.go Outdated Show resolved Hide resolved
lib/client/interfaces.go Outdated Show resolved Hide resolved
lib/client/interfaces.go Outdated Show resolved Hide resolved
lib/client/interfaces.go Outdated Show resolved Hide resolved
api/client/tunneldialer.go Outdated Show resolved Hide resolved
@Joerger Joerger force-pushed the joerger/api-proxy-dialer branch from a0419a8 to 1bcaa55 Compare February 19, 2021 01:37
@Joerger Joerger force-pushed the joerger/api-credential-providers branch from ccad89f to 556f49c Compare February 19, 2021 01:40
@Joerger Joerger force-pushed the joerger/api-proxy-dialer branch from 8c868d1 to 521d83f Compare February 19, 2021 18:24
api/client/client.go Outdated Show resolved Hide resolved
api/client/client.go Outdated Show resolved Hide resolved
api/client/contextdialer.go Outdated Show resolved Hide resolved
api/client/contextdialer.go Outdated Show resolved Hide resolved
api/client/credentials.go Show resolved Hide resolved
api/client/ssh.go Outdated Show resolved Hide resolved
@awly awly self-requested a review February 19, 2021 22:08
@russjones russjones added this to the 6.0.1 "Ides of March" milestone Feb 20, 2021
Base automatically changed from joerger/api-credential-providers to master February 23, 2021 00:43
@Joerger Joerger changed the title API proxy dialer API client connection refactor Mar 4, 2021
@Joerger Joerger marked this pull request as ready for review March 4, 2021 02:56
@Joerger Joerger changed the title API client connection refactor API client connection overhaul Mar 4, 2021
@russjones
Copy link
Contributor

@awly @r0mant Can you review?

@Joerger Joerger requested a review from alex-kovoy as a code owner March 5, 2021 02:49
@Joerger Joerger force-pushed the joerger/api-proxy-dialer branch 2 times, most recently from 22f6534 to d8ca29a Compare March 6, 2021 01:03
@Joerger Joerger requested a review from andrejtokarcik March 9, 2021 18:21
@Joerger Joerger force-pushed the joerger/api-proxy-dialer branch 2 times, most recently from 390ac2c to 9b36d55 Compare March 9, 2021 21:05
api/client/client.go Outdated Show resolved Hide resolved
api/client/client.go Show resolved Hide resolved
api/client/client.go Outdated Show resolved Hide resolved
api/client/client.go Outdated Show resolved Hide resolved
api/client/client.go Outdated Show resolved Hide resolved
api/client/client.go Outdated Show resolved Hide resolved
api/client/contextdialer.go Show resolved Hide resolved
api/client/identityfile.go Outdated Show resolved Hide resolved
api/sshutils/conn.go Outdated Show resolved Hide resolved
api/sshutils/conn.go Outdated Show resolved Hide resolved
@russjones russjones modified the milestones: 6.0.1 "Ides of March", 6.1 Mar 10, 2021
Joerger added 2 commits March 10, 2021 12:04
… comment; Add nonblocking NewTLSAuthClient function for use in teleport libraries.
…urrent connection logic; Refactor lib/auth/clt.Client implementation to decouple the http client into its own struct.
@Joerger Joerger force-pushed the joerger/api-proxy-dialer branch from 9b36d55 to 1259daf Compare March 10, 2021 21:40
api/client/client.go Outdated Show resolved Hide resolved
api/client/webclient.go Outdated Show resolved Hide resolved
lib/client/weblogin.go Outdated Show resolved Hide resolved
Copy link
Contributor

@andrejtokarcik andrejtokarcik left a comment

Choose a reason for hiding this comment

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

A couple of minor remarks.

constants.go Show resolved Hide resolved
if err != nil {
return nil, trace.Wrap(err)
}

return configure(tlsConfig), nil
}

// SSHClientConfig returns SSH configuration used to connect to Proxy.
func (c *IdentityCreds) SSHClientConfig() (*ssh.ClientConfig, error) {
identityFile, err := ReadIdentityFile(c.path)
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a disadvantage to doing

type IdentityCreds struct {
  identityFile *IdentityFile
}

(or similar) right away?

api/client/credentials_test.go Outdated Show resolved Hide resolved
lib/client/interfaces.go Show resolved Hide resolved
@Joerger Joerger enabled auto-merge (squash) March 19, 2021 20:15
@Joerger
Copy link
Contributor Author

Joerger commented Mar 22, 2021

@russjones ready for bot.

Copy link
Contributor

@russjones russjones left a comment

Choose a reason for hiding this comment

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

Bot.

@Joerger Joerger merged commit 2beb991 into master Mar 23, 2021
@Joerger Joerger deleted the joerger/api-proxy-dialer branch March 23, 2021 21:39
Joerger added a commit that referenced this pull request Mar 26, 2021
* Added support for connecting API client through tunnel proxy and web proxy addresses (with identity file).

* Added concurrent dialing logic to dial several possible dialing combinations and seamlessly return the first client to connect.
Joerger added a commit that referenced this pull request Mar 29, 2021
* Added support for connecting API client through tunnel proxy and web proxy addresses (with identity file).

* Added concurrent dialing logic to dial several possible dialing combinations and seamlessly return the first client to connect.
Joerger added a commit that referenced this pull request Mar 30, 2021
* API client connection overhaul (#5625)

* Add Credential loader support for tsh profiles. (#5993)

* Profile credentials dialer fix (#6122)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants