Documentation
¶
Overview ¶
Package sshconn reaches a server over SSH for the channel's minion (docs: contracts/agentless-channels/): it dials the server, directly or through a proxy, logs in with the target's credentials (a key, a password) in turn, checks the host key it presents, and tells what came of it apart: nothing reached, something that is not an SSH server, a host key other than the one given, every login refused.
Index ¶
- Variables
- func CallFailure(ctx context.Context, err error, peer string) linkclient.Answer
- func Failure(ctx context.Context, err error) linkclient.Answer
- func ReadableKey(text string) (string, error)
- type Conn
- func (c *Conn) Alive(wait time.Duration) bool
- func (c *Conn) Close() error
- func (c *Conn) Closed() <-chan struct{}
- func (c *Conn) Dial(ctx context.Context, network, address string) (net.Conn, error)
- func (c *Conn) Fingerprint() string
- func (c *Conn) Listen(network, address string) (net.Listener, error)
- func (c *Conn) SFTP() (*sftp.Client, error)
- func (c *Conn) Session() (*ssh.Session, error)
- func (c *Conn) State(key any, create func() any) any
- func (c *Conn) Wait() error
- type HostKeyError
- type LoginError
- type NotSSHError
- type Pool
Constants ¶
This section is empty.
Variables ¶
var ErrClosed = errors.New("the connection closed")
ErrClosed is an open given up on because the connection closed.
var OpenWait = 15 * time.Second
OpenWait bounds opening a channel (a session, the SFTP client): a server answers an open at once, and a connection that went away under one can leave it unanswered for good (x/crypto/ssh: an open queued during a key exchange the connection did not live through).
Functions ¶
func CallFailure ¶
CallFailure is Failure for a call, which can say what answered when it is not an SSH server: core shows the target "not the minion", with it.
func Failure ¶
func Failure(ctx context.Context, err error) linkclient.Answer
Failure is the answer for a call or an open that met err: a failure of its kind (login and host_key ones an agentless channel's own).
func ReadableKey ¶
ReadableKey is a private key as the key parser reads it, from what a paste may have left of it: a one-line box drops a key's line breaks (Chrome) or makes them spaces (Firefox), JSON writes them "\n". The body is base64, which ignores where its lines break, so the block is made again: its markers on lines of their own, the body in lines of 70. A key with headers (the old encrypted PEM: Proc-Type, DEK-Info) is left as it is, as headers that lost their lines cannot be told from the body. The keys people paste by mistake are told apart: a public key, a PuTTY key.
Types ¶
type Conn ¶
type Conn struct {
SSH *ssh.Client
// HostKey is the key the server presented; Version the version string
// it sent (SSH-2.0-OpenSSH_9.6p1 …).
HostKey ssh.PublicKey
Version string
// Peer is the IP address the channel connected to: the session's
// external address. Empty through a proxy that resolved a name.
Peer string
// User is who the connection logged in as; Password the password it
// logged in with, when the login was a password's (a PLAINTEXT
// credential's): what a become's sudo asks for unless the task gives
// another. Never logged.
User string
Password string
// contains filtered or unexported fields
}
Conn is a server's SSH connection, logged in.
func Dial ¶
Dial reaches the target's server and logs in with its logins in turn, a connection each, until one is taken; each try within the target's connect timeout. Logins say how those tried fared: the refused ones, then the one taken. A refusal (or a credential that does not read) moves on to the next; anything else ends the dial, as the next would meet it too: the server not reached, another host key, not an SSH server.
func (*Conn) Close ¶
Close closes the connection, its SFTP client with it; what waits on the server (an open, an SFTP request, a command's output) gives up.
func (*Conn) Closed ¶
func (c *Conn) Closed() <-chan struct{}
Closed is closed once the connection is.
func (*Conn) Dial ¶ added in v0.6.0
Dial connects to address from the server (network "tcp": direct-tcpip, host:port; "unix": OpenSSH's direct-streamlocal, a socket's path), within ctx: the server connects as slowly as its destination answers, so OpenWait does not bound it, nor does it close the connection. It gives up with the connection too. A refusal is an *ssh.OpenChannelError.
func (*Conn) Fingerprint ¶
Fingerprint is the presented host key's SHA-256 fingerprint, as ssh-keygen -l prints it.
func (*Conn) Listen ¶ added in v0.6.0
Listen has the server listen at a tcp address (a remote forward, tcpip-forward: on the server's loopback unless its GatewayPorts lets it listen where asked; port 0, one it picks), within OpenWait.
func (*Conn) SFTP ¶
SFTP is the connection's SFTP client, opened the first time it is asked for, within OpenWait.
type HostKeyError ¶
type HostKeyError struct{ Presented, Want string }
HostKeyError: the server presented a host key other than the one the target gives.
func (*HostKeyError) Error ¶
func (e *HostKeyError) Error() string
type LoginError ¶
type LoginError struct{ Why string }
LoginError: the server refused the login, or the target gives none that can be tried.
func (*LoginError) Error ¶
func (e *LoginError) Error() string
type NotSSHError ¶
NotSSHError: what answered is not an SSH server; First is the start of what it sent.
func (*NotSSHError) Error ¶
func (e *NotSSHError) Error() string
type Pool ¶
type Pool struct {
// contains filtered or unexported fields
}
Pool keeps calls' SSH connections for the next call to the same server, each for its target's Reuse: a file goes a chunk a call, and a login for each would cost a handshake and a line in the server's log every time.
func NewPool ¶
func NewPool() *Pool
NewPool is an empty pool, closing what it keeps once its time is up.
func (*Pool) Close ¶
func (p *Pool) Close()
Close closes every connection the pool keeps, and stops it.