ssh package - github.com/gliderlabs/ssh - Go Packages (original) (raw)
Package ssh wraps the crypto/ssh package with a higher-level API for building SSH servers. The goal of the API was to make it as simple as using net/http, so the API is very similar.
You should be able to build any SSH server using only this package, which wraps relevant types and some functions from crypto/ssh. However, you still need to use crypto/ssh for building SSH clients.
ListenAndServe starts an SSH server with a given address, handler, and options. The handler is usually nil, which means to use DefaultHandler. Handle sets DefaultHandler:
ssh.Handle(func(s ssh.Session) { io.WriteString(s, "Hello world\n") })
log.Fatal(ssh.ListenAndServe(":2222", nil))
If you don't specify a host key, it will generate one every time. This is convenient except you'll have to deal with clients being confused that the host key is different. It's a better idea to generate or point to an existing key on your system:
log.Fatal(ssh.ListenAndServe(":2222", nil, ssh.HostKeyFile("/Users/progrium/.ssh/id_rsa")))
Although all options have functional option helpers, another way to control the server's behavior is by creating a custom Server:
s := &ssh.Server{ Addr: ":2222", Handler: sessionHandler, PublicKeyHandler: authHandler, } s.AddHostKey(hostKeySigner)
log.Fatal(s.ListenAndServe())
This package automatically handles basic SSH requests like setting environment variables, requesting PTY, and changing window size. These requests are processed, responded to, and any relevant state is updated. This state is then exposed to you via the Session interface.
The one big feature missing from the Session abstraction is signals. This was started, but not completed. Pull Requests welcome!
func DirectTCPIPHandler(srv *Server, conn *gossh.ServerConn, newChan gossh.NewChannel, ctx Context)
func ListenAndServe(addr string, handler Handler, options ...Option) error
func Serve(l net.Listener, handler Handler, options ...Option) error
- func (srv *Server) AddHostKey(key Signer)
- func (srv *Server) Close() error
- func (srv *Server) Handle(fn Handler)
- func (srv *Server) HandleConn(newConn net.Conn)
- func (srv *Server) ListenAndServe() error
- func (srv *Server) Serve(l net.Listener) error
- func (srv *Server) SetOption(option Option) error
- func (srv *Server) Shutdown(ctx context.Context) error
This section is empty.
var (
ContextKeyUser = &contextKey{"user"}
ContextKeySessionID = &contextKey{"session-id"}
ContextKeyPermissions = &contextKey{"permissions"}
ContextKeyClientVersion = &contextKey{"client-version"}
ContextKeyServerVersion = &contextKey{"server-version"}
ContextKeyLocalAddr = &contextKey{"local-addr"}
ContextKeyRemoteAddr = &contextKey{"remote-addr"}
ContextKeyServer = &contextKey{"ssh-server"}
ContextKeyConn = &contextKey{"ssh-conn"}
ContextKeyPublicKey = &contextKey{"public-key"})
ErrServerClosed is returned by the Server's Serve, ListenAndServe, and ListenAndServeTLS methods after a call to Shutdown or Close.
func AgentRequested(sess Session) bool
AgentRequested returns true if the client requested agent forwarding.
func DirectTCPIPHandler ¶ added in v0.2.0
DirectTCPIPHandler can be enabled by adding it to the server's ChannelHandlers under direct-tcpip.
ForwardAgentConnections takes connections from a listener to proxy into the session on the OpenSSH channel for agent connections. It blocks and services connections until the listener stop accepting.
func Handle ¶
func Handle(handler Handler)
Handle registers the handler as the DefaultHandler.
func KeysEqual(ak, bk PublicKey) bool
KeysEqual is constant time compare of the keys to avoid timing attacks.
func ListenAndServe ¶
ListenAndServe listens on the TCP network address addr and then calls Serve with handler to handle sessions on incoming connections. Handler is typically nil, in which case the DefaultHandler is used.
package main
import ( "io"
"github.com/gliderlabs/ssh")
func main() { ssh.ListenAndServe(":2222", func(s ssh.Session) { io.WriteString(s, "Hello world\n") }) }
NewAgentListener sets up a temporary Unix socket that can be communicated to the session environment and used for forwarding connections.
Serve accepts incoming SSH connections on the listener l, creating a new connection goroutine for each. The connection goroutines read requests and then calls handler to handle sessions. Handler is typically nil, in which case the DefaultHandler is used.
func SetAgentRequested(ctx Context)
SetAgentRequested sets up the session context so that AgentRequested returns true.
type BannerHandler ¶ added in v0.3.7
type BannerHandler func(ctx Context) string
BannerHandler is a callback for displaying the server banner.
ConnCallback is a hook for new connections before handling. It allows wrapping for timeouts and limiting by returning the net.Conn that will be used as the underlying connection.
type ConnectionFailedCallback func(conn net.Conn, err error)
ConnectionFailedCallback is a hook for reporting failed connections Please note: the net.Conn is likely to be closed at this point
Context is a package specific context interface. It exposes connection metadata and allows new values to be easily written to it. It's used in authentication handlers and callbacks, and its underlying context.Context is exposed on Session in the session Handler. A connection-scoped lock is also embedded in the context to make it easier to limit operations per-connection.
type ForwardedTCPHandler ¶ added in v0.2.0
type ForwardedTCPHandler struct { sync.Mutex
}
ForwardedTCPHandler can be enabled by creating a ForwardedTCPHandler and adding the HandleSSHRequest callback to the server's RequestHandlers under tcpip-forward and cancel-tcpip-forward.
type Handler ¶
type Handler func(Session)
Handler is a callback for handling established SSH sessions.
var DefaultHandler Handler
DefaultHandler is the default Handler used by Serve.
type KeyboardInteractiveHandler ¶ added in v0.1.2
KeyboardInteractiveHandler is a callback for performing keyboard-interactive authentication.
type LocalPortForwardingCallback func(ctx Context, destinationHost string, destinationPort uint32) bool
LocalPortForwardingCallback is a hook for allowing port forwarding
Option is a functional option handler for Server.
func HostKeyFile(filepath string) Option
HostKeyFile returns a functional option that adds HostSigners to the server from a PEM file at filepath.
package main
import ( "github.com/gliderlabs/ssh" )
func main() { ssh.ListenAndServe(":2222", nil, ssh.HostKeyFile("/path/to/host/key")) }
func HostKeyPEM(bytes []byte) Option
HostKeyPEM returns a functional option that adds HostSigners to the server from a PEM file as bytes.
func KeyboardInteractiveAuth(fn KeyboardInteractiveHandler) Option
NoPty returns a functional option that sets PtyCallback to return false, denying PTY requests.
package main
import ( "github.com/gliderlabs/ssh" )
func main() { ssh.ListenAndServe(":2222", nil, ssh.NoPty()) }
func PasswordAuth(fn PasswordHandler) Option
PasswordAuth returns a functional option that sets PasswordHandler on the server.
package main
import ( "github.com/gliderlabs/ssh" )
func main() { ssh.ListenAndServe(":2222", nil, ssh.PasswordAuth(func(ctx ssh.Context, pass string) bool { return pass == "secret" }), ) }
func PublicKeyAuth(fn PublicKeyHandler) Option
PublicKeyAuth returns a functional option that sets PublicKeyHandler on the server.
package main
import ( "os"
"github.com/gliderlabs/ssh")
func main() { ssh.ListenAndServe(":2222", nil, ssh.PublicKeyAuth(func(ctx ssh.Context, key ssh.PublicKey) bool { data, _ := os.ReadFile("/path/to/allowed/key.pub") allowed, _, _, _, _ := ssh.ParseAuthorizedKey(data) return ssh.KeysEqual(key, allowed) }), ) }
func WrapConn(fn ConnCallback) Option
WrapConn returns a functional option that sets ConnCallback on the server.
type PasswordHandler ¶
PasswordHandler is a callback for performing password authentication.
The Permissions type holds fine-grained permissions that are specific to a user or a specific authentication method for a user. Permissions, except for "source-address", must be enforced in the server application layer, after successful authentication.
type Pty struct { Term string Window Window }
Pty represents a PTY request and configuration.
type PtyCallback func(ctx Context, pty Pty) bool
PtyCallback is a hook for allowing PTY sessions.
PublicKey is an abstraction of different types of public keys.
ParseAuthorizedKey parses a public key from an authorized_keys file used in OpenSSH according to the sshd(8) manual page.
ParsePublicKey parses an SSH public key formatted for use in the SSH wire protocol according to RFC 4253, section 6.6.
type PublicKeyHandler ¶
type PublicKeyHandler func(ctx Context, key PublicKey) bool
PublicKeyHandler is a callback for performing public key authentication.
type ReversePortForwardingCallback func(ctx Context, bindHost string, bindPort uint32) bool
ReversePortForwardingCallback is a hook for allowing reverse port forwarding
type Server struct {
Addr string
Handler Handler
HostSigners []Signer
Version string
BannerHandler [BannerHandler](#BannerHandler)
KeyboardInteractiveHandler [KeyboardInteractiveHandler](#KeyboardInteractiveHandler)
PasswordHandler [PasswordHandler](#PasswordHandler)
PublicKeyHandler [PublicKeyHandler](#PublicKeyHandler)
PtyCallback [PtyCallback](#PtyCallback)
ConnCallback [ConnCallback](#ConnCallback)
LocalPortForwardingCallback [LocalPortForwardingCallback](#LocalPortForwardingCallback)
ReversePortForwardingCallback [ReversePortForwardingCallback](#ReversePortForwardingCallback)
ServerConfigCallback [ServerConfigCallback](#ServerConfigCallback)
SessionRequestCallback [SessionRequestCallback](#SessionRequestCallback)
ConnectionFailedCallback [ConnectionFailedCallback](#ConnectionFailedCallback)
IdleTimeout [time](/time).[Duration](/time#Duration)
MaxTimeout [time](/time).[Duration](/time#Duration)
ChannelHandlers map[[string](/builtin#string)][ChannelHandler](#ChannelHandler)
RequestHandlers map[[string](/builtin#string)][RequestHandler](#RequestHandler)
SubsystemHandlers map[[string](/builtin#string)][SubsystemHandler](#SubsystemHandler)}
Server defines parameters for running an SSH server. The zero value for Server is a valid configuration. When both PasswordHandler and PublicKeyHandler are nil, no client authentication is performed.
func (srv *Server) AddHostKey(key Signer)
AddHostKey adds a private key as a host key. If an existing host key exists with the same algorithm, it is overwritten. Each server config must have at least one host key.
Close immediately closes all active listeners and all active connections.
Close returns any error returned from closing the Server's underlying Listener(s).
func (*Server) Handle ¶
func (srv *Server) Handle(fn Handler)
Handle sets the Handler for the server.
func (*Server) ListenAndServe ¶
func (srv *Server) ListenAndServe() error
ListenAndServe listens on the TCP network address srv.Addr and then calls Serve to handle incoming connections. If srv.Addr is blank, ":22" is used. ListenAndServe always returns a non-nil error.
Serve accepts incoming connections on the Listener l, creating a new connection goroutine for each. The connection goroutines read requests and then calls srv.Handler to handle sessions.
Serve always returns a non-nil error.
func (srv *Server) SetOption(option Option) error
SetOption runs a functional option against the server.
Shutdown gracefully shuts down the server without interrupting any active connections. Shutdown works by first closing all open listeners, and then waiting indefinitely for connections to close. If the provided context expires before the shutdown is complete, then the context's error is returned.
ServerConfigCallback is a hook for creating custom default server configs
Session provides access to information about an SSH session and methods to read and write to the SSH channel with an embedded Channel interface from crypto/ssh.
When Command() returns an empty slice, the user requested a shell. Otherwise the user is performing an exec with those command arguments.
TODO: Signals
type SessionRequestCallback func(sess Session, requestType string) bool
SessionRequestCallback is a callback for allowing or denying SSH sessions.
const ( SIGABRT Signal = "ABRT" SIGALRM Signal = "ALRM" SIGFPE Signal = "FPE" SIGHUP Signal = "HUP" SIGILL Signal = "ILL" SIGINT Signal = "INT" SIGKILL Signal = "KILL" SIGPIPE Signal = "PIPE" SIGQUIT Signal = "QUIT" SIGSEGV Signal = "SEGV" SIGTERM Signal = "TERM" SIGUSR1 Signal = "USR1" SIGUSR2 Signal = "USR2" )
POSIX signals as listed in RFC 4254 Section 6.10.
A Signer can create signatures that verify against a public key.
type Window struct { Width int Height int }
Window represents the size of a PTY window.