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

Mutual TLS Auth server and clients #1528

Closed
wants to merge 5 commits into from
Closed

Mutual TLS Auth server and clients #1528

wants to merge 5 commits into from

Conversation

klizhentas
Copy link
Contributor

Description

This PR replaces SSH based Auth server authentication with TLS based mutual authentication. This PR is a first in a series of follow ups but is self-sufficient.

Included in the PR:

  • 2.5.0 Server will serve SSH and TLS on the same auth server socket serving legacy SSH client requests and TLS requests
  • Trusted clusters will upgrade and re-exchange certificates after upgrade
  • Nodes will re-register and receive new identities after auth server upgrade
  • Auth server switched to use mutual TLS client authentication
  • Added support for proxy line protocol. The protocol support is turned on by default, but can be turned off later.
  • No reconfiguration required, upgrade is fully automatic.

Not included in the PR

  • Some edge cases with additional tests
  • User/Admin upgrade and install documentation

@klizhentas klizhentas added this to the 2.5.0 milestone Dec 22, 2017
@klizhentas klizhentas force-pushed the sasha/x509 branch 2 times, most recently from b573946 to 456f166 Compare December 22, 2017 22:42
// per connections? E.g. what happens to session tickets. Benchmark this.
pool, err := t.AuthServer.ClientCertPool()
if err != nil {
log.Errorf("failed to retrieve client pool: %v", trace.DebugReport(err))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

make error message conformant

}
clientCert := peers[0]
if len(clientCert.Issuer.Organization) < 1 {
log.Warning("missing organization in issuer certificate %v", clientCert.Issuer)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

log.Warningf("Missing")...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

remove this extra check

lib/auth/clt.go Outdated
@@ -102,6 +178,24 @@ func NewClient(addr string, dialer Dialer, params ...roundtrip.ClientParam) (*Cl
}, nil
}

// GetDialer returns dialer that will connect to auth server API
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Add DELETE IN note

if a.Username == "" {
return trace.BadParameter("missing parameter 'username'")
}
if a.Pass == nil && a.U2F == nil && a.OTP == nil {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

add web session here as well

return nil, trace.Wrap(err)
}

if err := req.CheckAndSetDefaults(); err != nil {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

remove second check

// tryRemoteTLSClient tries creating TLS client and using it (the client may not be available
// due to older clusters), returns client if it is working properly
func (c *SessionContext) tryRemoteTLSClient(cluster reversetunnel.RemoteSite) (auth.ClientI, error) {
clt, err := c.newRemoteTLSClient(cluster)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

test this case

// build a ssh connection to the remote auth server
config := &ssh.ClientConfig{
User: principal,
Auth: []ssh.AuthMethod{authMethods},
User: cert.ValidPrincipals[0],
Copy link
Contributor Author

Choose a reason for hiding this comment

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

check at least one

return nil, trace.Wrap(err)
}
return session, nil
return s.proxyClient.AuthenticateWebUser(auth.AuthenticateUserRequest{
Copy link
Contributor Author

Choose a reason for hiding this comment

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

add deprecation note to SignIn

if err != nil {
return trace.Wrap(err, "failed to parse certificate at %v", certPath)
}
log.Infof("Securely joining remote cluster %v.", cert.Subject.CommonName)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

remove Securely

@@ -262,6 +275,56 @@ func (proxy *ProxyClient) isRecordingProxy() (bool, error) {
}
}

// dialAuthServer returns auth server connection forwarded via proxy
func (proxy *ProxyClient) dialAuthServer(ctx context.Context, clusterName string) (net.Conn, error) {
log.Infof("[CLIENT] client=%v connecting to auth server on cluster ", proxy.clientAddr, clusterName)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

remove square brackets

Copy link
Collaborator

@r0mant r0mant left a comment

Choose a reason for hiding this comment

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

Mostly typos and inconsistent log entries.

@@ -877,6 +923,26 @@ func (s *APIServer) registerNewAuthServer(auth ClientI, w http.ResponseWriter, r
return message("ok"), nil
}

type generateServerKeysReq struct {
HostID string `json:"host_id"`
Copy link
Collaborator

Choose a reason for hiding this comment

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

Godocs on exported fields are missing.

@@ -1119,7 +1185,7 @@ func (s *APIServer) createUserWithToken(auth ClientI, w http.ResponseWriter, r *
webSession, err = auth.CreateUserWithOTP(req.Token, req.Password, req.OTPToken)
}
if err != nil {
log.Error(trace.DebugReport(err))
log.Warningf("failed to create user: %v", err.Error())
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do you need to log this? If yes, make it conformant to our style.

lib/auth/auth.go Outdated
// GenerateUserCert generates user certificate, it takes pkey as a signing
// certs is a pair of SSH and TLS certificates
type certs struct {
// sshis PEM encoded SSH certificate
Copy link
Collaborator

Choose a reason for hiding this comment

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

"sshis" -> "ssh is"

lib/auth/auth.go Outdated
return certs.ssh, certs.tls, nil
}

// generateUserCert generates user certificate, it takes pkey as a signing
Copy link
Collaborator

Choose a reason for hiding this comment

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

Obsolete comment, as the method does not accept pkey.

lib/auth/auth.go Outdated
@@ -579,7 +724,7 @@ func (s *AuthServer) checkTokenTTL(token string) bool {
// If a token was generated with a TTL=0, it means it's a single-use token and it gets destroyed
// after a successful registration.
func (s *AuthServer) RegisterUsingToken(token, hostID string, nodeName string, role teleport.Role) (*PackedKeys, error) {
log.Infof("[AUTH] Node %q [%v] trying to join with role: %v", nodeName, hostID, role)
log.Infof("node %q [%v] trying to join with role: %v", nodeName, hostID, role)
Copy link
Collaborator

Choose a reason for hiding this comment

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

"Node", dot at the end.

storage := utils.NewFileAddrStorage(
filepath.Join(process.Config.DataDir, "authservers.json"))

authUser := identity.Cert.ValidPrincipals[0]
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is the ValidPrincipals length checked anywhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes auth/init.go:696

err := s.DeleteBucket([]string{}, tunnelConnectionsPrefix)
log.Debugf("Presence delete all tunnel connections: %v", err)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Log entries in this function look like debug leftovers.

@@ -473,10 +473,15 @@ func (s *PresenceService) DeleteTunnelConnections(clusterName string) error {

// DeleteAllTunnelConnections deletes all tunnel connections
func (s *PresenceService) DeleteAllTunnelConnections() error {
conns, _ := s.GetAllTunnelConnections()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Error is ignored.

if trace.IsNotFound(err) {
return nil
}
conns, _ = s.GetAllTunnelConnections()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Error is ignored. This actually, too, looks like a debug leftover. Getting tunnels in "delete" method?

if err := cs.trust.UpsertCertAuthority(ca); err != nil {
return nil, trace.Wrap(err)
}
return ca, err
Copy link
Collaborator

Choose a reason for hiding this comment

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

return ca, nil?

@klizhentas
Copy link
Contributor Author

closing it in favor of another branch with merged conflicts

@klizhentas klizhentas closed this Dec 27, 2017
@klizhentas klizhentas deleted the sasha/x509 branch December 27, 2017 22:05
@klizhentas klizhentas mentioned this pull request Feb 19, 2018
hatched pushed a commit that referenced this pull request Jan 30, 2023
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.

3 participants