Movatterモバイル変換


[0]ホーム

URL:


ssh

package
v1.92.3Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 16, 2025 License:BSD-3-Clause, BSD-3-ClauseImports:19Imported by:7

Details

Repository

github.com/tailscale/tailscale

Links

README

gliderlabs/ssh

GoDocCircleCIGo Report CardOpenCollectiveSlackEmail Updates

The Glider Labs SSH server package is dope. —@bradfitz, Go team member

This Go package wraps thecrypto/sshpackage with a higher-level API forbuilding SSH servers. The goal of the API was to make it as simple as usingnet/http, so the API is very similar:

 package main import (     "tailscale.com/tempfork/gliderlabs/ssh"     "io"     "log" ) func main() {     ssh.Handle(func(s ssh.Session) {         io.WriteString(s, "Hello world\n")     })       log.Fatal(ssh.ListenAndServe(":2222", nil)) }

This package was built by@progrium after working on nearly a dozen projects at Glider Labs using SSH and collaborating with@shazow (known forssh-chat).

Examples

A bunch of great examples are in the_examples directory.

Usage

See GoDoc reference.

Contributing

Pull requests are welcome! However, since this project is very much about APIdesign, please submit API changes as issues to discuss before submitting PRs.

Also, you canjoin our Slack to discuss as well.

Roadmap

  • Non-session channel handlers
  • Cleanup callback API
  • 1.0 release
  • High-level client?

Sponsors

Become a sponsor and get your logo on our README on Github with a link to your site. [Become a sponsor]

License

BSD

Documentation

Overview

Package ssh wraps the crypto/ssh package with a higher-level API for buildingSSH servers. The goal of the API was to make it as simple as using net/http, sothe API is very similar.

You should be able to build any SSH server using only this package, which wrapsrelevant types and some functions from crypto/ssh. However, you still need touse crypto/ssh for building SSH clients.

ListenAndServe starts an SSH server with a given address, handler, and options. Thehandler 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 convenientexcept 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 theserver'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 environmentvariables, requesting PTY, and changing window size. These requests areprocessed, responded to, and any relevant state is updated. This state is thenexposed to you via the Session interface.

The one big feature missing from the Session abstraction is signals. This wasstarted, but not completed. Pull Requests welcome!

Index

Examples

Constants

This section is empty.

Variables

View Source
var (// ContextKeyUser is a context key for use with Contexts in this package.// The associated value will be of type string.ContextKeyUser = &contextKey{"user"}// ContextKeySessionID is a context key for use with Contexts in this package.// The associated value will be of type string.ContextKeySessionID = &contextKey{"session-id"}// ContextKeyPermissions is a context key for use with Contexts in this package.// The associated value will be of type *Permissions.ContextKeyPermissions = &contextKey{"permissions"}// ContextKeyClientVersion is a context key for use with Contexts in this package.// The associated value will be of type string.ContextKeyClientVersion = &contextKey{"client-version"}// ContextKeyServerVersion is a context key for use with Contexts in this package.// The associated value will be of type string.ContextKeyServerVersion = &contextKey{"server-version"}// ContextKeyLocalAddr is a context key for use with Contexts in this package.// The associated value will be of type net.Addr.ContextKeyLocalAddr = &contextKey{"local-addr"}// ContextKeyRemoteAddr is a context key for use with Contexts in this package.// The associated value will be of type net.Addr.ContextKeyRemoteAddr = &contextKey{"remote-addr"}// ContextKeyServer is a context key for use with Contexts in this package.// The associated value will be of type *Server.ContextKeyServer = &contextKey{"ssh-server"}// ContextKeyConn is a context key for use with Contexts in this package.// The associated value will be of type gossh.ServerConn.ContextKeyConn = &contextKey{"ssh-conn"}// ContextKeyPublicKey is a context key for use with Contexts in this package.// The associated value will be of type PublicKey.ContextKeyPublicKey = &contextKey{"public-key"})
View Source
var DefaultChannelHandlers = map[string]ChannelHandler{"session":DefaultSessionHandler,}
View Source
var DefaultRequestHandlers = map[string]RequestHandler{}
View Source
var DefaultSubsystemHandlers = map[string]SubsystemHandler{}
View Source
var ErrServerClosed =errors.New("ssh: Server closed")

ErrServerClosed is returned by the Server's Serve, ListenAndServe,and ListenAndServeTLS methods after a call to Shutdown or Close.

Functions

funcAgentRequested

func AgentRequested(sessSession)bool

AgentRequested returns true if the client requested agent forwarding.

funcDefaultSessionHandler

func DefaultSessionHandler(srv *Server, conn *gossh.ServerConn, newChangossh.NewChannel, ctxContext)

funcDirectTCPIPHandler

func DirectTCPIPHandler(srv *Server, conn *gossh.ServerConn, newChangossh.NewChannel, ctxContext)

DirectTCPIPHandler can be enabled by adding it to the server'sChannelHandlers under direct-tcpip.

funcForwardAgentConnections

func ForwardAgentConnections(lnet.Listener, sSession)

ForwardAgentConnections takes connections from a listener to proxy into thesession on the OpenSSH channel for agent connections. It blocks and servicesconnections until the listener stop accepting.

funcHandle

func Handle(handlerHandler)

Handle registers the handler as the DefaultHandler.

funcKeysEqual

func KeysEqual(ak, bkPublicKey)bool

KeysEqual is constant time compare of the keys to avoid timing attacks.

funcListenAndServe

func ListenAndServe(addrstring, handlerHandler, options ...Option)error

ListenAndServe listens on the TCP network address addr and then calls Servewith handler to handle sessions on incoming connections. Handler is typicallynil, in which case the DefaultHandler is used.

Example
package mainimport ("io""tailscale.com/tempfork/gliderlabs/ssh")func main() {ssh.ListenAndServe(":2222", func(s ssh.Session) {io.WriteString(s, "Hello world\n")})}

funcNewAgentListener

func NewAgentListener() (net.Listener,error)

NewAgentListener sets up a temporary Unix socket that can be communicatedto the session environment and used for forwarding connections.

funcServe

func Serve(lnet.Listener, handlerHandler, options ...Option)error

Serve accepts incoming SSH connections on the listener l, creating a newconnection goroutine for each. The connection goroutines read requests andthen calls handler to handle sessions. Handler is typically nil, in whichcase the DefaultHandler is used.

funcSetAgentRequested

func SetAgentRequested(ctxContext)

SetAgentRequested sets up the session context so that AgentRequestedreturns true.

Types

typeBannerHandleradded inv1.32.0

type BannerHandler func(ctxContext)string

typeChannelHandler

type ChannelHandler func(srv *Server, conn *gossh.ServerConn, newChangossh.NewChannel, ctxContext)

typeConnCallback

type ConnCallback func(ctxContext, connnet.Conn)net.Conn

ConnCallback is a hook for new connections before handling.It allows wrapping for timeouts and limiting by returningthe net.Conn that will be used as the underlying connection.

typeConnectionFailedCallback

type ConnectionFailedCallback func(connnet.Conn, errerror)

ConnectionFailedCallback is a hook for reporting failed connectionsPlease note: the net.Conn is likely to be closed at this point

typeContext

type Context interface {context.Contextsync.Locker// User returns the username used when establishing the SSH connection.User()string// SessionID returns the session hash.SessionID()string// ClientVersion returns the version reported by the client.ClientVersion()string// ServerVersion returns the version reported by the server.ServerVersion()string// RemoteAddr returns the remote address for this connection.RemoteAddr()net.Addr// LocalAddr returns the local address for this connection.LocalAddr()net.Addr// Permissions returns the Permissions object used for this connection.Permissions() *Permissions// SetValue allows you to easily write new values into the underlying context.SetValue(key, value interface{})}

Context is a package specific context interface. It exposes connectionmetadata and allows new values to be easily written to it. It's used inauthentication handlers and callbacks, and its underlying context.Context isexposed on Session in the session Handler. A connection-scoped lock is alsoembedded in the context to make it easier to limit operations per-connection.

typeForwardedTCPHandler

type ForwardedTCPHandler struct {sync.Mutex// contains filtered or unexported fields}

ForwardedTCPHandler can be enabled by creating a ForwardedTCPHandler andadding the HandleSSHRequest callback to the server's RequestHandlers undertcpip-forward and cancel-tcpip-forward.

func (*ForwardedTCPHandler)HandleSSHRequest

func (h *ForwardedTCPHandler) HandleSSHRequest(ctxContext, srv *Server, req *gossh.Request) (bool, []byte)

typeHandler

type Handler func(Session)

Handler is a callback for handling established SSH sessions.

var DefaultHandlerHandler

DefaultHandler is the default Handler used by Serve.

typeKeyboardInteractiveHandler

type KeyboardInteractiveHandler func(ctxContext, challengergossh.KeyboardInteractiveChallenge)bool

KeyboardInteractiveHandler is a callback for performing keyboard-interactive authentication.

typeLocalPortForwardingCallback

type LocalPortForwardingCallback func(ctxContext, destinationHoststring, destinationPortuint32)bool

LocalPortForwardingCallback is a hook for allowing port forwarding

typeNoClientAuthHandleradded inv1.32.0

type NoClientAuthHandler func(ctxContext)error

typeOption

type Option func(*Server)error

Option is a functional option handler for Server.

funcHostKeyFile

func HostKeyFile(filepathstring)Option

HostKeyFile returns a functional option that adds HostSigners to the serverfrom a PEM file at filepath.

Example
package mainimport ("tailscale.com/tempfork/gliderlabs/ssh")func main() {ssh.ListenAndServe(":2222", nil, ssh.HostKeyFile("/path/to/host/key"))}

funcHostKeyPEM

func HostKeyPEM(bytes []byte)Option

HostKeyPEM returns a functional option that adds HostSigners to the serverfrom a PEM file as bytes.

funcNoPty

func NoPty()Option

NoPty returns a functional option that sets PtyCallback to return false,denying PTY requests.

Example
package mainimport ("tailscale.com/tempfork/gliderlabs/ssh")func main() {ssh.ListenAndServe(":2222", nil, ssh.NoPty())}

funcPasswordAuth

func PasswordAuth(fnPasswordHandler)Option

PasswordAuth returns a functional option that sets PasswordHandler on the server.

Example
package mainimport ("tailscale.com/tempfork/gliderlabs/ssh")func main() {ssh.ListenAndServe(":2222", nil,ssh.PasswordAuth(func(ctx ssh.Context, pass string) bool {return pass == "secret"}),)}

funcPublicKeyAuth

func PublicKeyAuth(fnPublicKeyHandler)Option

PublicKeyAuth returns a functional option that sets PublicKeyHandler on the server.

Example
package mainimport ("errors""os""tailscale.com/tempfork/gliderlabs/ssh")func main() {ssh.ListenAndServe(":2222", nil,ssh.PublicKeyAuth(func(ctx ssh.Context, key ssh.PublicKey) error {data, err := os.ReadFile("/path/to/allowed/key.pub")if err != nil {return err}allowed, _, _, _, err := ssh.ParseAuthorizedKey(data)if err != nil {return err}if !ssh.KeysEqual(key, allowed) {return errors.New("some error")}return nil}),)}

funcWrapConn

func WrapConn(fnConnCallback)Option

WrapConn returns a functional option that sets ConnCallback on the server.

typePasswordHandler

type PasswordHandler func(ctxContext, passwordstring)bool

PasswordHandler is a callback for performing password authentication.

typePermissions

type Permissions struct {*gossh.Permissions}

The Permissions type holds fine-grained permissions that are specific to auser or a specific authentication method for a user. Permissions, except for"source-address", must be enforced in the server application layer, aftersuccessful authentication.

typePty

type Pty struct {// Term is the TERM environment variable value.Termstring// Window is the Window sent as part of the pty-req.WindowWindow// Modes represent a mapping of Terminal Mode opcode to value as it was// requested by the client as part of the pty-req. These are outlined as// part ofhttps://datatracker.ietf.org/doc/html/rfc4254#section-8.//// The opcodes are defined as constants in golang.org/x/crypto/ssh (VINTR,VQUIT,etc.).// Boolean opcodes have values 0 or 1.Modesgossh.TerminalModes}

Pty represents a PTY request and configuration.

typePtyCallback

type PtyCallback func(ctxContext, ptyPty)bool

PtyCallback is a hook for allowing PTY sessions.

typePublicKey

type PublicKey interface {gossh.PublicKey}

PublicKey is an abstraction of different types of public keys.

funcParseAuthorizedKey

func ParseAuthorizedKey(in []byte) (outPublicKey, commentstring, options []string, rest []byte, errerror)

ParseAuthorizedKey parses a public key from an authorized_keys file used inOpenSSH according to the sshd(8) manual page.

funcParsePublicKey

func ParsePublicKey(in []byte) (outPublicKey, errerror)

ParsePublicKey parses an SSH public key formatted for use inthe SSH wire protocol according toRFC 4253, section 6.6.

typePublicKeyHandler

type PublicKeyHandler func(ctxContext, keyPublicKey)error

PublicKeyHandler is a callback for performing public key authentication.

typeRequestHandler

type RequestHandler func(ctxContext, srv *Server, req *gossh.Request) (okbool, payload []byte)

typeReversePortForwardingCallback

type ReversePortForwardingCallback func(ctxContext, bindHoststring, bindPortuint32)bool

ReversePortForwardingCallback is a hook for allowing reverse port forwarding

typeServer

type Server struct {Addrstring// TCP address to listen on, ":22" if emptyHandlerHandler// handler to invoke, ssh.DefaultHandler if nilHostSigners []Signer// private keys for the host key, must have at least oneVersionstring// server version to be sent before the initial handshakeKeyboardInteractiveHandlerKeyboardInteractiveHandler// keyboard-interactive authentication handlerPasswordHandlerPasswordHandler// password authentication handlerPublicKeyHandlerPublicKeyHandler// public key authentication handlerNoClientAuthHandlerNoClientAuthHandler// no client authentication handlerPtyCallbackPtyCallback// callback for allowing PTY sessions, allows all if nilConnCallbackConnCallback// optional callback for wrapping net.Conn before handlingLocalPortForwardingCallbackLocalPortForwardingCallback// callback for allowing local port forwarding, denies all if nilReversePortForwardingCallbackReversePortForwardingCallback// callback for allowing reverse port forwarding, denies all if nilServerConfigCallbackServerConfigCallback// callback for configuring detailed SSH optionsSessionRequestCallbackSessionRequestCallback// callback for allowing or denying SSH sessionsConnectionFailedCallbackConnectionFailedCallback// callback to report connection failuresIdleTimeouttime.Duration// connection timeout when no activity, none if emptyMaxTimeouttime.Duration// absolute connection timeout, none if empty// ChannelHandlers allow overriding the built-in session handlers or provide// extensions to the protocol, such as tcpip forwarding. By default only the// "session" handler is enabled.ChannelHandlers map[string]ChannelHandler// RequestHandlers allow overriding the server-level request handlers or// provide extensions to the protocol, such as tcpip forwarding. By default// no handlers are enabled.RequestHandlers map[string]RequestHandler// SubsystemHandlers are handlers which are similar to the usual SSH command// handlers, but handle named subsystems.SubsystemHandlers map[string]SubsystemHandler// contains filtered or unexported fields}

Server defines parameters for running an SSH server. The zero value forServer is a valid configuration. When both PasswordHandler andPublicKeyHandler are nil, no client authentication is performed.

func (*Server)AddHostKey

func (srv *Server) AddHostKey(keySigner)

AddHostKey adds a private key as a host key. If an existing host key existswith the same algorithm, it is overwritten. Each server config must have atleast one host key.

func (*Server)Close

func (srv *Server) Close()error

Close immediately closes all active listeners and all activeconnections.

Close returns any error returned from closing the Server'sunderlying Listener(s).

func (*Server)Handle

func (srv *Server) Handle(fnHandler)

Handle sets the Handler for the server.

func (*Server)HandleConn

func (srv *Server) HandleConn(newConnnet.Conn)

func (*Server)ListenAndServe

func (srv *Server) ListenAndServe()error

ListenAndServe listens on the TCP network address srv.Addr and then callsServe to handle incoming connections. If srv.Addr is blank, ":22" is used.ListenAndServe always returns a non-nil error.

func (*Server)Serve

func (srv *Server) Serve(lnet.Listener)error

Serve accepts incoming connections on the Listener l, creating a newconnection goroutine for each. The connection goroutines read requests and thencalls srv.Handler to handle sessions.

Serve always returns a non-nil error.

func (*Server)SetOption

func (srv *Server) SetOption(optionOption)error

SetOption runs a functional option against the server.

func (*Server)Shutdown

func (srv *Server) Shutdown(ctxcontext.Context)error

Shutdown gracefully shuts down the server without interrupting anyactive connections. Shutdown works by first closing all openlisteners, 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.

typeServerConfigCallback

type ServerConfigCallback func(ctxContext) *gossh.ServerConfig

ServerConfigCallback is a hook for creating custom default server configs

typeSession

type Session interface {gossh.Channel// User returns the username used when establishing the SSH connection.User()string// RemoteAddr returns the net.Addr of the client side of the connection.RemoteAddr()net.Addr// LocalAddr returns the net.Addr of the server side of the connection.LocalAddr()net.Addr// Environ returns a copy of strings representing the environment set by the// user for this session, in the form "key=value".Environ() []string// Exit sends an exit status and then closes the session.Exit(codeint)error// Command returns a shell parsed slice of arguments that were provided by the// user. Shell parsing splits the command string according to POSIX shell rules,// which considers quoting not just whitespace.Command() []string// RawCommand returns the exact command that was provided by the user.RawCommand()string// Subsystem returns the subsystem requested by the user.Subsystem()string// PublicKey returns the PublicKey used to authenticate. If a public key was not// used it will return nil.PublicKey()PublicKey// Context returns the connection's context. The returned context is always// non-nil and holds the same data as the Context passed into auth// handlers and callbacks.//// The context is canceled when the client's connection closes or I/O// operation fails.Context()context.Context// Permissions returns a copy of the Permissions object that was available for// setup in the auth handlers via the Context.Permissions()Permissions// Pty returns PTY information, a channel of window size changes, and a boolean// of whether or not a PTY was accepted for this session.Pty() (Pty, <-chanWindow,bool)// Signals registers a channel to receive signals sent from the client. The// channel must handle signal sends or it will block the SSH request loop.// Registering nil will unregister the channel from signal sends. During the// time no channel is registered signals are buffered up to a reasonable amount.// If there are buffered signals when a channel is registered, they will be// sent in order on the channel immediately after registering.Signals(c chan<-Signal)// Break regisers a channel to receive notifications of break requests sent// from the client. The channel must handle break requests, or it will block// the request handling loop. Registering nil will unregister the channel.// During the time that no channel is registered, breaks are ignored.Break(c chan<-bool)// DisablePTYEmulation disables the session's default minimal PTY emulation.// If you're setting the pty's termios settings from the Pty request, use// this method to avoid corruption.// Currently (2022-03-12) the only emulation implemented is NL-to-CRNL translation (`\n`=>`\r\n`).// A call of DisablePTYEmulation must precede any call to Write.DisablePTYEmulation()}

Session provides access to information about an SSH session and methodsto read and write to the SSH channel with an embedded Channel interface fromcrypto/ssh.

When Command() returns an empty slice, the user requested a shell. Otherwisethe user is performing an exec with those command arguments.

TODO: Signals

typeSessionRequestCallback

type SessionRequestCallback func(sessSession, requestTypestring)bool

SessionRequestCallback is a callback for allowing or denying SSH sessions.

typeSignal

type Signalstring
const (SIGABRTSignal = "ABRT"SIGALRMSignal = "ALRM"SIGFPESignal = "FPE"SIGHUPSignal = "HUP"SIGILLSignal = "ILL"SIGINTSignal = "INT"SIGKILLSignal = "KILL"SIGPIPESignal = "PIPE"SIGQUITSignal = "QUIT"SIGSEGVSignal = "SEGV"SIGTERMSignal = "TERM"SIGUSR1Signal = "USR1"SIGUSR2Signal = "USR2")

POSIX signals as listed inRFC 4254 Section 6.10.

typeSigner

type Signer interface {gossh.Signer}

A Signer can create signatures that verify against a public key.

typeSubsystemHandler

type SubsystemHandler func(sSession)

typeWindow

type Window struct {// Width is the number of columns.// It overrides WidthPixels.Widthint// Height is the number of rows.// It overrides HeightPixels.Heightint// WidthPixels is the drawable width of the window, in pixels.WidthPixelsint// HeightPixels is the drawable height of the window, in pixels.HeightPixelsint}

Window represents the size of a PTY window.

Seehttps://datatracker.ietf.org/doc/html/rfc4254#section-6.2

Zero dimension parameters MUST be ignored. The character/row dimensionsoverride the pixel dimensions (when nonzero). Pixel dimensions referto the drawable area of the window.

Source Files

View all Source files

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f orF : Jump to
y orY : Canonical URL
go.dev uses cookies from Google to deliver and enhance the quality of its services and to analyze traffic.Learn more.

[8]ページ先頭

©2009-2025 Movatter.jp