Skip to content

Commit

Permalink
Added forwarding SSH server.
Browse files Browse the repository at this point in the history
  • Loading branch information
russjones committed Dec 5, 2017
1 parent cc4162e commit 7018852
Show file tree
Hide file tree
Showing 41 changed files with 2,253 additions and 533 deletions.
15 changes: 15 additions & 0 deletions constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ const (
// ComponentNode is SSH node (SSH server serving requests)
ComponentNode = "node"

// ComponentNode is SSH node (SSH server serving requests)
ComponentForwardingNode = "node:forward"

// ComponentProxy is SSH proxy (SSH server forwarding connections)
ComponentProxy = "proxy"

Expand All @@ -79,6 +82,15 @@ const (
// ComponentSubsystemProxy is the proxy subsystem.
ComponentSubsystemProxy = "subsystem:proxy"

// ComponentLocalTerm is a terminal on a regular SSH node.
ComponentLocalTerm = "term:local"

// ComponentRemoteTerm is a terminal on a forwarding SSH node.
ComponentRemoteTerm = "term:remote"

// ComponentRemoteSubsystem is subsystem on a forwarding SSH node.
ComponentRemoteSubsystem = "subsystem:remote"

// ComponentAuditLog is audit log component
ComponentAuditLog = "auditlog"

Expand Down Expand Up @@ -216,6 +228,9 @@ const (
TraitInternalRoleVariable = "{{internal.logins}}"
)

// SCP is Secure Copy.
const SCP = "scp"

// Root is *nix system administrator account name.
const Root = "root"

Expand Down
9 changes: 2 additions & 7 deletions integration/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,12 +253,7 @@ func (i *TeleInstance) CreateEx(trustedSecrets []*InstanceSecrets, tconf *servic
tconf = service.MakeDefaultConfig()
}
tconf.DataDir = dataDir
tconf.Auth.ClusterConfig, err = services.NewClusterConfig(services.ClusterConfigSpecV3{
SessionRecording: services.RecordAtNode,
})
if err != nil {
return trace.Wrap(err)
}
tconf.Auth.ClusterConfig = services.DefaultClusterConfig()
tconf.Auth.ClusterName, err = services.NewClusterName(services.ClusterNameSpecV2{
ClusterName: i.Secrets.SiteName,
})
Expand Down Expand Up @@ -353,7 +348,7 @@ func (i *TeleInstance) CreateEx(trustedSecrets []*InstanceSecrets, tconf *servic
if err != nil {
return trace.Wrap(err)
}
user.Key.Cert, err = auth.GenerateUserCert(user.Key.Pub, teleUser, logins, ttl, true, teleport.CompatibilityNone)
user.Key.Cert, err = auth.GenerateUserCert(user.Key.Pub, teleUser, logins, ttl, true, true, teleport.CompatibilityNone)
if err != nil {
return err
}
Expand Down
6 changes: 4 additions & 2 deletions lib/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ func (s *AuthServer) GenerateHostCert(hostPublicKey []byte, hostID, nodeName, cl

// GenerateUserCert generates user certificate, it takes pkey as a signing
// private key (user certificate authority)
func (s *AuthServer) GenerateUserCert(key []byte, user services.User, allowedLogins []string, ttl time.Duration, canForwardAgents bool, compatibility string) ([]byte, error) {
func (s *AuthServer) GenerateUserCert(key []byte, user services.User, allowedLogins []string, ttl time.Duration, canForwardAgents bool, canPortForward bool, compatibility string) ([]byte, error) {
domainName, err := s.GetDomainName()
if err != nil {
return nil, trace.Wrap(err)
Expand All @@ -256,6 +256,7 @@ func (s *AuthServer) GenerateUserCert(key []byte, user services.User, allowedLog
Roles: user.GetRoles(),
Compatibility: compatibility,
PermitAgentForwarding: canForwardAgents,
PermitPortForwarding: canPortForward,
})
if err != nil {
return nil, trace.Wrap(err)
Expand Down Expand Up @@ -742,7 +743,8 @@ func (s *AuthServer) NewWebSession(userName string) (services.WebSession, error)
AllowedLogins: allowedLogins,
TTL: bearerTokenTTL,
PermitAgentForwarding: roles.CanForwardAgents(),
Roles: user.GetRoles(),
PermitPortForwarding: roles.CanPortForward(),
Roles: user.GetRoles(),
})
if err != nil {
return nil, trace.Wrap(err)
Expand Down
2 changes: 1 addition & 1 deletion lib/auth/auth_with_roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,7 @@ func (a *AuthWithRoles) GenerateUserCert(key []byte, username string, ttl time.D
return nil, trace.Wrap(err)
}
return a.authServer.GenerateUserCert(
key, user, allowedLogins, sessionTTL, checker.CanForwardAgents(), compatibility)
key, user, allowedLogins, sessionTTL, checker.CanForwardAgents(), checker.CanPortForward(), compatibility)
}

func (a *AuthWithRoles) CreateSignupToken(user services.UserV1, ttl time.Duration) (token string, e error) {
Expand Down
6 changes: 3 additions & 3 deletions lib/auth/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,11 @@ type InitConfig struct {
// factor (off, otp, u2f) passed in from a configuration file.
AuthPreference services.AuthPreference

// ClusterConfig holds cluster level configuration.
ClusterConfig services.ClusterConfig

// AuditLog is used for emitting events to audit log
AuditLog events.IAuditLog

// ClusterConfig holds cluster level configuration.
ClusterConfig services.ClusterConfig
}

// Init instantiates and configures an instance of AuthServer
Expand Down
10 changes: 3 additions & 7 deletions lib/auth/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,6 @@ func (s *AuthInitSuite) TestAuthPreference(c *C) {
})
c.Assert(err, IsNil)

clusterConfig, err := services.NewClusterConfig(services.ClusterConfigSpecV3{
SessionRecording: services.RecordAtNode,
})
c.Assert(err, IsNil)
clusterName, err := services.NewClusterName(services.ClusterNameSpecV2{
ClusterName: "me.localhost",
})
Expand All @@ -197,7 +193,7 @@ func (s *AuthInitSuite) TestAuthPreference(c *C) {
NodeName: "foo",
Backend: bk,
Authority: testauthority.New(),
ClusterConfig: clusterConfig,
ClusterConfig: services.DefaultClusterConfig(),
ClusterName: clusterName,
StaticTokens: staticTokens,
AuthPreference: ap,
Expand Down Expand Up @@ -230,8 +226,8 @@ func (s *AuthInitSuite) TestClusterID(c *C) {
NodeName: "foo",
Backend: bk,
Authority: testauthority.New(),
ClusterName: clusterName,
ClusterConfig: services.DefaultClusterConfig(),
ClusterName: clusterName,
})
c.Assert(err, IsNil)

Expand All @@ -247,8 +243,8 @@ func (s *AuthInitSuite) TestClusterID(c *C) {
NodeName: "foo",
Backend: bk,
Authority: testauthority.New(),
ClusterName: clusterName,
ClusterConfig: services.DefaultClusterConfig(),
ClusterName: clusterName,
})
c.Assert(err, IsNil)

Expand Down
3 changes: 3 additions & 0 deletions lib/auth/native/native.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,9 @@ func (n *nauth) GenerateUserCert(c services.UserCertParams) ([]byte, error) {
if c.PermitAgentForwarding {
cert.Permissions.Extensions[teleport.CertExtensionPermitAgentForwarding] = ""
}
if !c.PermitPortForwarding {
delete(cert.Permissions.Extensions, teleport.CertExtensionPermitPortForwarding)
}
if len(c.Roles) != 0 {
// if we are requesting a certificate with support for older versions of OpenSSH
// don't add roles to certificate extensions, due to a bug in <= OpenSSH 7.1
Expand Down
1 change: 1 addition & 0 deletions lib/auth/native/native_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ func (s *NativeSuite) TestUserCertCompatibility(c *C) {
Roles: []string{"foo"},
Compatibility: tt.inCompatibility,
PermitAgentForwarding: true,
PermitPortForwarding: true,
})
c.Assert(err, IsNil, comment)

Expand Down
9 changes: 8 additions & 1 deletion lib/auth/oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,14 @@ func (a *AuthServer) ValidateOIDCAuthCallback(q url.Values) (*OIDCAuthResponse,
if err != nil {
return nil, trace.Wrap(err)
}
cert, err := a.GenerateUserCert(req.PublicKey, user, allowedLogins, certTTL, roles.CanForwardAgents(), req.Compatibility)
cert, err := a.GenerateUserCert(
req.PublicKey,
user,
allowedLogins,
certTTL,
roles.CanForwardAgents(),
roles.CanPortForward(),
req.Compatibility)
if err != nil {
return nil, trace.Wrap(err)
}
Expand Down
1 change: 1 addition & 0 deletions lib/auth/permissions.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ func GetCheckerForBuiltinRole(clusterConfig services.ClusterConfig, role telepor
services.NewRule(services.KindAuthServer, services.RO()),
services.NewRule(services.KindReverseTunnel, services.RO()),
services.NewRule(services.KindTunnelConnection, services.RO()),
services.NewRule(services.KindClusterConfig, services.RO()),
},
},
})
Expand Down
2 changes: 1 addition & 1 deletion lib/auth/saml.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ func (a *AuthServer) ValidateSAMLResponse(samlResponse string) (*SAMLAuthRespons
if err != nil {
return nil, trace.Wrap(err)
}
cert, err := a.GenerateUserCert(request.PublicKey, user, allowedLogins, certTTL, roles.CanForwardAgents(), request.Compatibility)
cert, err := a.GenerateUserCert(request.PublicKey, user, allowedLogins, certTTL, roles.CanForwardAgents(), roles.CanPortForward(), request.Compatibility)
if err != nil {
return nil, trace.Wrap(err)
}
Expand Down
10 changes: 8 additions & 2 deletions lib/auth/test/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ func (s *AuthSuite) GenerateUserCert(c *C) {
AllowedLogins: []string{"centos", "root"},
TTL: time.Hour,
PermitAgentForwarding: true,
PermitPortForwarding: true,
})
c.Assert(err, IsNil)

Expand All @@ -100,6 +101,7 @@ func (s *AuthSuite) GenerateUserCert(c *C) {
AllowedLogins: []string{"root"},
TTL: -20,
PermitAgentForwarding: true,
PermitPortForwarding: true,
})
c.Assert(err, NotNil)

Expand All @@ -109,7 +111,9 @@ func (s *AuthSuite) GenerateUserCert(c *C) {
Username: "user",
AllowedLogins: []string{"root"},
TTL: 0,
PermitAgentForwarding: true})
PermitAgentForwarding: true,
PermitPortForwarding: true,
})
c.Assert(err, NotNil)

_, err = s.A.GenerateUserCert(services.UserCertParams{
Expand All @@ -119,6 +123,7 @@ func (s *AuthSuite) GenerateUserCert(c *C) {
AllowedLogins: []string{"root"},
TTL: time.Hour,
PermitAgentForwarding: true,
PermitPortForwarding: true,
})
c.Assert(err, IsNil)

Expand All @@ -130,7 +135,8 @@ func (s *AuthSuite) GenerateUserCert(c *C) {
AllowedLogins: []string{"root"},
TTL: time.Hour,
PermitAgentForwarding: true,
Roles: inRoles,
PermitPortForwarding: true,
Roles: inRoles,
})
c.Assert(err, IsNil)
parsedKey, _, _, _, err := ssh.ParseAuthorizedKey(cert)
Expand Down
3 changes: 3 additions & 0 deletions lib/auth/testauthority/testauthority.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ func (n *Keygen) GenerateUserCert(c services.UserCertParams) ([]byte, error) {
if c.PermitAgentForwarding {
cert.Permissions.Extensions[teleport.CertExtensionPermitAgentForwarding] = ""
}
if !c.PermitPortForwarding {
delete(cert.Permissions.Extensions, teleport.CertExtensionPermitPortForwarding)
}
if len(c.Roles) != 0 {
roles, err := services.MarshalCertRoles(c.Roles)
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions lib/client/keyagent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ func makeKey(username string, allowedLogins []string, ttl time.Duration) (*Key,
AllowedLogins: allowedLogins,
TTL: ttl,
PermitAgentForwarding: true,
PermitPortForwarding: true,
})
if err != nil {
return nil, err
Expand Down
1 change: 1 addition & 0 deletions lib/client/keystore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ func (s *KeyStoreTestSuite) makeSignedKey(c *check.C, makeExpired bool) *Key {
AllowedLogins: allowedLogins,
TTL: ttl,
PermitAgentForwarding: false,
PermitPortForwarding: true,
})
c.Assert(err, check.IsNil)
return &Key{
Expand Down
2 changes: 1 addition & 1 deletion lib/client/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ func (ns *NodeSession) updateTerminalSize(s *ssh.Session) {
}
// send the new window size to the server
_, err = s.SendRequest(
sshutils.WindowChangeReq, false,
sshutils.WindowChangeRequest, false,
ssh.Marshal(sshutils.WinChangeReqParams{
W: uint32(winSize.Width),
H: uint32(winSize.Height),
Expand Down
8 changes: 5 additions & 3 deletions lib/config/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,12 +406,14 @@ func ApplyFileConfig(fc *FileConfig, cfg *service.Config) error {
}
}

// read in and set session recording
clusterConfig, err := fc.Auth.SessionRecording.Parse()
// build cluster config from session recording and host key checking preferences
cfg.Auth.ClusterConfig, err = services.NewClusterConfig(services.ClusterConfigSpecV3{
SessionRecording: fc.Auth.SessionRecording,
ProxyChecksHostKeys: fc.Auth.ProxyChecksHostKeys,
})
if err != nil {
return trace.Wrap(err)
}
cfg.Auth.ClusterConfig = clusterConfig

// read in and set the license file path (not used in open-source version)
licenseFile := fc.Auth.LicenseFile
Expand Down
Loading

0 comments on commit 7018852

Please sign in to comment.