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

Forwarding Server #1482

Merged
merged 1 commit into from
Dec 5, 2017
Merged

Forwarding Server #1482

merged 1 commit into from
Dec 5, 2017

Conversation

russjones
Copy link
Contributor

@russjones russjones commented Nov 29, 2017

Purpose

To support recording sessions with OpenSSH nodes Teleport needs to create a in-memory SSH server in the proxy that forwards connections to a remote host. This PR creates this server but does not use it yet.

Implementation

  • Consolidate handlers between the regular and forwarding server further in lib/srv/authhandlers.go.
  • Created new forwarding server in lib/srv/forward/sshserver.go.

Related Issues

Fixes #1481
Fixes #1486
Fixes #1487

@@ -86,6 +86,11 @@ const (
ExecEventCode = "exitCode"
ExecEventError = "exitError"

// SubsystemEvent is the result of the execution of a subsystem.
SubsystemEvent = "subsystem"
SubsystemName = "subsystem.name"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should be name.


return 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.

Debug log here saying that we are bypassing security checks.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

How does this work when you can add a user CA, but not a host CA to a host?

if err != nil {
return trace.Wrap(err)
}

// if it's a forwarding node checking permissions, then we don't do any RBAC
Copy link
Contributor Author

Choose a reason for hiding this comment

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

  1. Instead create checkPermissionToLoginRBAC as well.
  2. Or remove it because the below RBAC check is against the proxy itself.

lib/srv/ctx.go Outdated
func (c *ServerContext) ProxyPublicAddress() string {
proxyHost := "<proxyhost>:3080"

if c.srv != 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.

Return here.

lib/srv/ctx.go Outdated
@@ -325,7 +363,8 @@ func closeAll(closers ...io.Closer) error {
if cl == nil {
continue
}
if e := cl.Close(); e != nil {

if e := cl.Close(); 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.

Revert and use trace.Aggregate.

serverContext: serverContext,
subsytemName: subsytemName,
ctx: ctx,
errorCh: make(chan error),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should have size 3.

// recording proxy mode.
err := s.handleAgentForwardProxy(req, ctx)
if err != nil {
log.Info(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.

Debugf.

}
err = s.reg.NotifyWinChange(*params, ctx)

// check if the users rbac role allows agent forwarding
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 if the user's RBAC role allows agent forwarding

lib/srv/term.go Outdated
if t.termType == "" {
t.termType = defaultTerm
}
if err := t.session.RequestPty(t.termType, t.params.W, t.params.H, ssh.TerminalModes{}); 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.

See if we get ssh.TerminalModes in the request.

lib/srv/term.go Outdated
Wpx: uint32(w * 8),
Hpx: uint32(h * 8),
}
_, err := t.session.SendRequest("window-change", false, ssh.Marshal(&req))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Constant.

}

// if we miss 3 in a row the connections dead, call cancel and cleanup
missed = missed + 1
Copy link
Contributor

Choose a reason for hiding this comment

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

why not missed += 1

@russjones
Copy link
Contributor Author

@r0mant Can you take a look at lib/auth/init.go I made some changes to how ClusterID is set.

// client) to see if this certificate can be allowed to login as user:login
// pair to requested server.
func (h *AuthHandlers) checkPermissionToLogin(cert *ssh.Certificate, clusterName string, teleportUser, osUser string) error {
h.Debugf("CheckPermsissionToLogin(%v, %v)", teleportUser, osUser)
func (h *AuthHandlers) canLoginOpenSSH(cert *ssh.Certificate, clusterName string, teleportUser, osUser string) error {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

canLoginWithoutRBAC

// canLoginTeleport checks the given certificate (supplied by a connected
// client) to see if this certificate can be allowed to login as user:login
// pair to requested server and if RBAC rules allow login.
func (h *AuthHandlers) canLoginTeleport(cert *ssh.Certificate, clusterName string, teleportUser, osUser string) error {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

canLoginWithRBAC

}
ctx.Debugf("Opening direct-tcpip channel from %v to %v", srcAddr, dstAddr)

conn, err := s.remoteClient.DialTCP("tcp", srcAddr, dstAddr)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Dial

// client. A manual timeout is needed here because SendRequest will wait for a
// response forever.
func (s *Server) sendKeepAliveWithTimeout(timeout time.Duration) bool {
errorCh := make(chan error)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

errorCh := make(chan error, 1)

lib/auth/init.go Outdated
// AuditLog is used for emitting events to audit log
AuditLog events.IAuditLog

// SessionRecording determines where the session is recorded: node, proxy, or off.
SessionRecording string
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Move to lib/config/configuration.go

const (
// HostKeyCheckOn is the default. The proxy will check the host key of the
// target node it connects to.
HostKeyCheckOn HostKeyCheckType = "on"
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

RecordAtProxy RecordingType = "proxy"

// RecordOff is used to disable session recording completely.
RecordOff RecordingType = "off"
)

// HostKeyCheckType holds how the recording proxy will check host keys.
type HostKeyCheckType string
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.

@@ -218,6 +264,9 @@ const ClusterConfigSpecSchemaTemplate = `{
"session_recording": {
"type": "string"
},
"proxy_checks_host_keys": {
"type": "string"
},
Copy link
Contributor Author

Choose a reason for hiding this comment

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

indent

// CheckPortForward checks if the certificate was signed by a valid certificate
// authority, fetches the appropriate roles, and checks if port forwarding is
// allowed.
func (h *AuthHandlers) CheckPortForward(ctx *ServerContext) error {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Get CA set and RoleSet and pass identity earlier.

// a valid public key
// if we are strictly checking host keys then reject this request right away
if clusterConfig.GetProxyChecksHostKeys() == services.HostKeyCheckOn {
return trace.AccessDenied("certificate not presented")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

proxy expects certificate signed by certificate authority, got public key


// if we are not stricting rejecting host keys, we need to log that we
// trusted a insecure key and then return nil
log.Infof("Strict host key checking disabled, allowing login without checking host key.")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Warn

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Insecure warning prefix.

// check if the role allows port forwarding for this user
err := s.authHandlers.CheckPortForward(ctx)
if err != nil {
s.log.Infof(err.Error())
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Warn

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Emit Audit Log.

// check if the role allows port forwarding for this user
err := s.authHandlers.CheckPortForward(ctx)
if err != nil {
log.Info(err.Error())
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Warn

events.LocalAddr: ctx.Conn.LocalAddr().String(),
events.RemoteAddr: ctx.Conn.RemoteAddr().String(),
})
h.Warnf("Port forwarding request denied: %v", systemErrorMessage)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

.

@russjones russjones merged commit e870a73 into master Dec 5, 2017
@russjones russjones deleted the rjones/fwd-srv branch December 5, 2017 01:33
hatched pushed a commit that referenced this pull request Jan 30, 2023
* Group all modal stories under ModalsHost

* Fix type of DialogClusterConnect, rename DialogBase to DialogNone
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.

2 participants