Skip to content

Commit

Permalink
Merge pull request #84 from uselagoon/sftp
Browse files Browse the repository at this point in the history
feat: add SFTP support
  • Loading branch information
smlx authored Jul 20, 2022
2 parents 85c4d37 + 0498a83 commit 9ddad5d
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 5 deletions.
5 changes: 4 additions & 1 deletion internal/sshserver/serve.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ import (
func Serve(ctx context.Context, log *zap.Logger, nc *nats.EncodedConn,
l net.Listener, c *k8s.Client, hostKeys [][]byte) error {
srv := ssh.Server{
Handler: sessionHandler(log, c),
Handler: sessionHandler(log, c, false),
SubsystemHandlers: map[string]ssh.SubsystemHandler{
"sftp": ssh.SubsystemHandler(sessionHandler(log, c, true)),
},
PublicKeyHandler: pubKeyAuth(log, nc, c),
}
for _, hk := range hostKeys {
Expand Down
20 changes: 16 additions & 4 deletions internal/sshserver/sessionhandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,37 @@ import (
var (
sessionTotal = promauto.NewCounter(prometheus.CounterOpts{
Name: "session_total",
Help: "The total number of ssh sessions",
Help: "The total number of ssh sessions started",
})
)

func sessionHandler(log *zap.Logger, c *k8s.Client) ssh.Handler {
// sessionHandler returns a ssh.Handler which connects the ssh session to the
// requested container.
//
// If sftp is true, the returned ssh.Handler can be type converted to a sftp
// ssh.SubsystemHandler. The only practical difference in the returned session
// handler is that the command is set to sftp-server. This implies that the
// target container must have a sftp-server binary installed for sftp to work.
// There is no support for a built-in sftp server.
func sessionHandler(log *zap.Logger, c *k8s.Client, sftp bool) ssh.Handler {
return func(s ssh.Session) {
sessionTotal.Inc()
sid, ok := s.Context().Value(ssh.ContextKeySessionID).(string)
if !ok {
log.Warn("couldn't get session ID")
return
}
// check if a pty was requested
_, _, pty := s.Pty()
// start the command
log.Debug("starting command exec",
zap.String("session-id", sid),
zap.Strings("raw command", s.Command()),
zap.String("subsystem", s.Subsystem()),
)
// parse the command line arguments to extract any service or container args
service, container, cmd := parseConnectionParams(s.Command())
if sftp {
cmd = []string{"sftp-server"}
}
// validate the service and container
if err := k8s.ValidateLabelValue(service); err != nil {
log.Debug("invalid service name",
Expand Down Expand Up @@ -79,6 +89,8 @@ func sessionHandler(log *zap.Logger, c *k8s.Client) ssh.Handler {
}
return
}
// check if a pty was requested
_, _, pty := s.Pty()
log.Info("executing command",
zap.String("namespace", s.User()),
zap.String("deployment", deployment),
Expand Down

0 comments on commit 9ddad5d

Please sign in to comment.