or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

acme.mdencryption.mdhashing.mdindex.mdnacl.mdopenpgp.mdpublic-key.mdssh.mdutilities.md
tile.json

ssh.mddocs/

SSH Protocol Implementation

The SSH packages provide complete client and server implementation of the SSH protocol, including transport security, authentication, and application-level protocols like remote command execution, port forwarding, and agent protocol support.

Package: golang.org/x/crypto/ssh

Complete SSH protocol implementation supporting both client and server operations.

Constants

Certificate Algorithms

const (
    CertAlgoRSAv01         = "ssh-rsa-cert-v01@openssh.com"
    InsecureCertAlgoDSAv01 = "ssh-dss-cert-v01@openssh.com"
    CertAlgoECDSA256v01    = "ecdsa-sha2-nistp256-cert-v01@openssh.com"
    CertAlgoECDSA384v01    = "ecdsa-sha2-nistp384-cert-v01@openssh.com"
    CertAlgoECDSA521v01    = "ecdsa-sha2-nistp521-cert-v01@openssh.com"
    CertAlgoSKECDSA256v01  = "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com"
    CertAlgoED25519v01     = "ssh-ed25519-cert-v01@openssh.com"
    CertAlgoSKED25519v01   = "sk-ssh-ed25519-cert-v01@openssh.com"
    CertAlgoRSASHA256v01   = "rsa-sha2-256-cert-v01@openssh.com"
    CertAlgoRSASHA512v01   = "rsa-sha2-512-cert-v01@openssh.com"
)

const (
    UserCert = 1
    HostCert = 2
)

const CertTimeInfinity = 1<<64 - 1

Cipher Algorithms

const (
    CipherAES128GCM            = "aes128-gcm@openssh.com"
    CipherAES256GCM            = "aes256-gcm@openssh.com"
    CipherChaCha20Poly1305     = "chacha20-poly1305@openssh.com"
    CipherAES128CTR            = "aes128-ctr"
    CipherAES192CTR            = "aes192-ctr"
    CipherAES256CTR            = "aes256-ctr"
    InsecureCipherAES128CBC    = "aes128-cbc"
    InsecureCipherTripleDESCBC = "3des-cbc"
    InsecureCipherRC4          = "arcfour"
    InsecureCipherRC4128       = "arcfour128"
    InsecureCipherRC4256       = "arcfour256"
)

Key Exchange Algorithms

const (
    InsecureKeyExchangeDH1SHA1   = "diffie-hellman-group1-sha1"
    InsecureKeyExchangeDH14SHA1  = "diffie-hellman-group14-sha1"
    KeyExchangeDH14SHA256        = "diffie-hellman-group14-sha256"
    KeyExchangeDH16SHA512        = "diffie-hellman-group16-sha512"
    KeyExchangeECDHP256          = "ecdh-sha2-nistp256"
    KeyExchangeECDHP384          = "ecdh-sha2-nistp384"
    KeyExchangeECDHP521          = "ecdh-sha2-nistp521"
    KeyExchangeCurve25519        = "curve25519-sha256"
    InsecureKeyExchangeDHGEXSHA1 = "diffie-hellman-group-exchange-sha1"
    KeyExchangeDHGEXSHA256       = "diffie-hellman-group-exchange-sha256"
    KeyExchangeMLKEM768X25519    = "mlkem768x25519-sha256"
)

MAC Algorithms

const (
    HMACSHA256ETM      = "hmac-sha2-256-etm@openssh.com"
    HMACSHA512ETM      = "hmac-sha2-512-etm@openssh.com"
    HMACSHA256         = "hmac-sha2-256"
    HMACSHA512         = "hmac-sha2-512"
    HMACSHA1           = "hmac-sha1"
    InsecureHMACSHA196 = "hmac-sha1-96"
)

Host Key Algorithms

const (
    KeyAlgoRSA         = "ssh-rsa"
    InsecureKeyAlgoDSA = "ssh-dss"
    KeyAlgoECDSA256    = "ecdsa-sha2-nistp256"
    KeyAlgoSKECDSA256  = "sk-ecdsa-sha2-nistp256@openssh.com"
    KeyAlgoECDSA384    = "ecdsa-sha2-nistp384"
    KeyAlgoECDSA521    = "ecdsa-sha2-nistp521"
    KeyAlgoED25519     = "ssh-ed25519"
    KeyAlgoSKED25519   = "sk-ssh-ed25519@openssh.com"
    KeyAlgoRSASHA256   = "rsa-sha2-256"
    KeyAlgoRSASHA512   = "rsa-sha2-512"
)

Variables

var ErrNoAuth = errors.New("ssh: no auth passed yet")

Client Operations

// Client is an authenticated SSH client connection.
type Client struct {
    Conn
    // contains unexported fields
}

// Dial starts a client connection to the given SSH server.
func Dial(network, addr string, config *ClientConfig) (*Client, error)

// NewClient creates a Client on top of the given connection.
func NewClient(c Conn, chans <-chan NewChannel, reqs <-chan *Request) *Client

// NewSession opens a new Session for the client.
func (c *Client) NewSession() (*Session, error)

// Close closes the client connection.
func (c *Client) Close() error

// Wait waits for the remote end to close the connection.
func (c *Client) Wait() error

// HandleChannelOpen registers a Handler for a particular channel type.
func (c *Client) HandleChannelOpen(channelType string) <-chan NewChannel

// Dial initiates a connection to the addr from the remote host.
// Used for port forwarding from the remote side.
func (c *Client) Dial(n, addr string) (net.Conn, error)

// DialContext is like Dial but uses a context.
func (c *Client) DialContext(ctx context.Context, n, addr string) (net.Conn, error)

// DialTCP connects to the remote address raddr on the network net
// through the secure channel.
func (c *Client) DialTCP(n string, laddr, raddr *net.TCPAddr) (net.Conn, error)

// Listen initiates a tcpip-forward on the remote side.
// Used for port forwarding from the client side.
func (c *Client) Listen(n, addr string) (net.Listener, error)

// ListenTCP requests the remote peer open a listening socket on raddr.
func (c *Client) ListenTCP(laddr *net.TCPAddr) (net.Listener, error)

// ListenUnix requests a Unix socket from the remote side.
func (c *Client) ListenUnix(socketPath string) (net.Listener, error)

Client Configuration

// ClientConfig holds configuration for SSH clients.
type ClientConfig struct {
    Config

    // User contains the username to authenticate as.
    User string

    // Auth contains authentication methods.
    Auth []AuthMethod

    // HostKeyCallback is called during the cryptographic handshake
    // to validate the server's host key.
    HostKeyCallback HostKeyCallback

    // BannerCallback is called when the server sends a banner message.
    BannerCallback BannerCallback

    // ClientVersion contains the version identification string
    // to send to the server.
    ClientVersion string

    // HostKeyAlgorithms lists the key types that the client will accept
    // from the server.
    HostKeyAlgorithms []string

    // Timeout is the maximum time for the TCP connection to establish.
    Timeout time.Duration
}

// Config contains common configuration for SSH clients and servers.
type Config struct {
    // Rand provides a source of entropy for cryptographic primitives.
    Rand io.Reader

    // RekeyThreshold is the number of bytes transmitted or received
    // after which the session key is renegotiated.
    RekeyThreshold uint64

    // KeyExchanges specifies the allowed key exchange algorithms.
    KeyExchanges []string

    // Ciphers specifies the allowed ciphers.
    Ciphers []string

    // MACs specifies the allowed MAC algorithms.
    MACs []string
}

// SetDefaults sets sensible values for unset fields in config.
func (c *Config) SetDefaults()

Authentication Methods

// AuthMethod is the interface implemented by different authentication methods.
type AuthMethod interface {
    // contains unexported methods
}

// Password returns an AuthMethod using the given password.
func Password(secret string) AuthMethod

// PasswordCallback returns an AuthMethod that interactively fetches a password.
func PasswordCallback(prompt func() (secret string, err error)) AuthMethod

// PublicKeys returns an AuthMethod that uses the given signers to authenticate.
func PublicKeys(signers ...Signer) AuthMethod

// PublicKeysCallback returns an AuthMethod that dynamically fetches signers.
func PublicKeysCallback(getSigners func() (signers []Signer, err error)) AuthMethod

// KeyboardInteractive returns an AuthMethod using a function to handle challenges.
func KeyboardInteractive(challenge KeyboardInteractiveChallenge) AuthMethod

// KeyboardInteractiveChallenge is the function signature for keyboard-interactive challenges.
type KeyboardInteractiveChallenge func(name, instruction string, questions []string, echos []bool) (answers []string, err error)

// GSSAPIWithMICAuthMethod returns an AuthMethod using GSSAPI authentication.
func GSSAPIWithMICAuthMethod(gssAPIClient GSSAPIClient, target string) AuthMethod

// RetryableAuthMethod wraps an AuthMethod to retry on failure.
func RetryableAuthMethod(auth AuthMethod, maxTries int) AuthMethod

Host Key Verification

// HostKeyCallback is called during the cryptographic handshake
// to validate the server's host key.
type HostKeyCallback func(hostname string, remote net.Addr, key PublicKey) error

// InsecureIgnoreHostKey returns a function that accepts any host key.
// WARNING: This should only be used for testing.
func InsecureIgnoreHostKey() HostKeyCallback

// FixedHostKey returns a function that only accepts the given host key.
func FixedHostKey(key PublicKey) HostKeyCallback

Session Management

// Session is a remote execution session.
type Session struct {
    Stdin  io.WriteCloser
    Stdout io.Reader
    Stderr io.Reader
    // contains unexported fields
}

// Run runs cmd on the remote host.
func (s *Session) Run(cmd string) error

// Start starts the execution of cmd on the remote host.
func (s *Session) Start(cmd string) error

// Wait waits for the remote command to exit.
func (s *Session) Wait() error

// Output runs cmd on the remote host and returns its stdout.
func (s *Session) Output(cmd string) ([]byte, error)

// CombinedOutput runs cmd and returns its combined stdout and stderr.
func (s *Session) CombinedOutput(cmd string) ([]byte, error)

// Shell starts a login shell on the remote host.
func (s *Session) Shell() error

// Close closes the session.
func (s *Session) Close() error

// RequestPty requests a pseudo-terminal with the given dimensions.
func (s *Session) RequestPty(term string, h, w int, termmodes TerminalModes) error

// WindowChange informs the remote host about a terminal resize.
func (s *Session) WindowChange(h, w int) error

// Signal sends a signal to the remote process.
func (s *Session) Signal(sig Signal) error

// SendRequest sends an out-of-band channel request.
func (s *Session) SendRequest(name string, wantReply bool, payload []byte) (bool, error)

// StdinPipe returns a pipe that will be connected to the remote command's stdin.
func (s *Session) StdinPipe() (io.WriteCloser, error)

// StdoutPipe returns a pipe that will be connected to the remote command's stdout.
func (s *Session) StdoutPipe() (io.Reader, error)

// StderrPipe returns a pipe that will be connected to the remote command's stderr.
func (s *Session) StderrPipe() (io.Reader, error)

// Setenv sets an environment variable for the session.
func (s *Session) Setenv(name, value string) error

Server Operations

// ServerConfig holds server specific configuration data.
type ServerConfig struct {
    Config

    // NoClientAuth determines whether a client must authenticate.
    NoClientAuth bool

    // MaxAuthTries specifies the maximum authentication attempts.
    MaxAuthTries int

    // PasswordCallback is called when a user attempts password authentication.
    PasswordCallback func(conn ConnMetadata, password []byte) (*Permissions, error)

    // PublicKeyCallback is called when a client offers a public key.
    PublicKeyCallback func(conn ConnMetadata, key PublicKey) (*Permissions, error)

    // KeyboardInteractiveCallback is called for keyboard-interactive authentication.
    KeyboardInteractiveCallback func(conn ConnMetadata, client KeyboardInteractiveChallenge) (*Permissions, error)

    // AuthLogCallback is called to log authentication attempts.
    AuthLogCallback func(conn ConnMetadata, method string, err error)

    // ServerVersion is the version identification string.
    ServerVersion string

    // BannerCallback is called before authentication to display a banner.
    BannerCallback func(conn ConnMetadata) string

    // GSSAPIWithMICConfig contains GSSAPI configuration.
    GSSAPIWithMICConfig *GSSAPIWithMICConfig
}

// NewServerConn starts a server connection over the given transport.
func NewServerConn(c net.Conn, config *ServerConfig) (*ServerConn, <-chan NewChannel, <-chan *Request, error)

// ServerConn is an authenticated SSH server connection.
type ServerConn struct {
    Conn
    // contains unexported fields
}

// Permissions represents permissions that may be applied to users.
type Permissions struct {
    // CriticalOptions indicate restrictions to the default permissions.
    CriticalOptions map[string]string

    // Extensions are extra functionality that the user is allowed to access.
    Extensions map[string]string
}

Key Management

// PublicKey is an abstraction of different types of public keys.
type PublicKey interface {
    Type() string
    Marshal() []byte
    Verify(data []byte, sig *Signature) error
}

// Signer is an interface for signing data with a private key.
type Signer interface {
    PublicKey() PublicKey
    Sign(rand io.Reader, data []byte) (*Signature, error)
}

// AlgorithmSigner allows specifying a signature algorithm.
type AlgorithmSigner interface {
    Signer
    SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error)
}

// Signature represents a cryptographic signature.
type Signature struct {
    Format string
    Blob   []byte
    Rest   []byte
}

// NewSignerFromKey returns a Signer from a crypto.PrivateKey.
func NewSignerFromKey(key interface{}) (Signer, error)

// NewSignerFromSigner returns a Signer from a crypto.Signer.
func NewSignerFromSigner(signer crypto.Signer) (Signer, error)

// ParsePrivateKey parses an SSH private key.
func ParsePrivateKey(pemBytes []byte) (Signer, error)

// ParsePrivateKeyWithPassphrase parses an encrypted SSH private key.
func ParsePrivateKeyWithPassphrase(pemBytes, passphrase []byte) (Signer, error)

// ParsePublicKey parses an SSH public key in authorized_keys format.
func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []string, rest []byte, err error)

// ParseKnownHosts parses a known_hosts file line.
func ParseKnownHosts(in []byte) (marker string, hosts []string, pubKey PublicKey, comment string, rest []byte, err error)

// MarshalAuthorizedKey serializes a key for authorized_keys file.
func MarshalAuthorizedKey(key PublicKey) []byte

// FingerprintSHA256 returns the SHA256 fingerprint of the public key.
func FingerprintSHA256(pubKey PublicKey) string

// FingerprintLegacyMD5 returns the legacy MD5 fingerprint.
func FingerprintLegacyMD5(pubKey PublicKey) string

Certificates

// Certificate represents an OpenSSH certificate.
type Certificate struct {
    Nonce           []byte
    Key             PublicKey
    Serial          uint64
    CertType        uint32
    KeyId           string
    ValidPrincipals []string
    ValidAfter      uint64
    ValidBefore     uint64
    Permissions
    Reserved     []byte
    SignatureKey PublicKey
    Signature    *Signature
}

// SignCert signs the certificate with the given signer.
func (c *Certificate) SignCert(rand io.Reader, authority Signer) error

// Marshal serializes the certificate.
func (c *Certificate) Marshal() []byte

// Type returns the certificate type string.
func (c *Certificate) Type() string

// Verify checks the certificate's signature.
func (c *Certificate) Verify(data []byte, sig *Signature) error

// NewCertSigner returns a Signer that includes a certificate.
func NewCertSigner(cert *Certificate, signer Signer) (Signer, error)

Channel Management

// Channel represents a duplex connection over SSH.
type Channel interface {
    Read(data []byte) (int, error)
    Write(data []byte) (int, error)
    Close() error
    CloseWrite() error
    SendRequest(name string, wantReply bool, payload []byte) (bool, error)
    Stderr() io.ReadWriter
}

// NewChannel represents an incoming channel request.
type NewChannel interface {
    Accept() (Channel, <-chan *Request, error)
    Reject(reason RejectionReason, message string) error
    ChannelType() string
    ExtraData() []byte
}

// RejectionReason is an enumeration for channel rejection reasons.
type RejectionReason uint32

const (
    Prohibited RejectionReason = iota + 1
    ConnectionFailed
    UnknownChannelType
    ResourceShortage
)

// Request represents a channel or connection-level request.
type Request struct {
    Type      string
    WantReply bool
    Payload   []byte
}

// DiscardRequests consumes and rejects all requests from the channel.
func DiscardRequests(in <-chan *Request)

Algorithm Configuration

// Algorithms contains configurable algorithm sets.
type Algorithms struct {
    KeyExchanges   []string
    Ciphers        []string
    MACs           []string
    HostKeys       []string
    PublicKeyAuths []string
}

// SupportedAlgorithms returns the supported secure algorithms.
func SupportedAlgorithms() Algorithms

// InsecureAlgorithms returns deprecated insecure algorithms.
func InsecureAlgorithms() Algorithms

Helper Functions

// Marshal serializes a value to SSH wire format.
func Marshal(msg interface{}) []byte

// Unmarshal parses SSH wire format into a value.
func Unmarshal(data []byte, out interface{}) error

// ParseDSAPrivateKey parses a DSA private key.
func ParseDSAPrivateKey(der []byte) (*dsa.PrivateKey, error)

// ParseRawPrivateKey parses a raw private key.
func ParseRawPrivateKey(pemBytes []byte) (interface{}, error)

// ParseRawPrivateKeyWithPassphrase parses an encrypted raw private key.
func ParseRawPrivateKeyWithPassphrase(pemBytes, passphrase []byte) (interface{}, error)

// MarshalPrivateKey marshals a private key to OpenSSH format.
func MarshalPrivateKey(key crypto.PrivateKey, comment string) (*pem.Block, error)

// MarshalPrivateKeyWithPassphrase marshals an encrypted private key.
func MarshalPrivateKeyWithPassphrase(key crypto.PrivateKey, comment string, passphrase []byte) (*pem.Block, error)

Package: golang.org/x/crypto/ssh/agent

SSH agent protocol implementation for client and server.

Types

// Agent represents capabilities of an ssh-agent.
type Agent interface {
    // List returns the identities known to the agent.
    List() ([]*Key, error)

    // Sign signs data with the given key.
    Sign(key PublicKey, data []byte) (*Signature, error)

    // Add adds a private key to the agent.
    Add(key AddedKey) error

    // Remove removes a key from the agent.
    Remove(key PublicKey) error

    // RemoveAll removes all keys from the agent.
    RemoveAll() error

    // Lock locks the agent with a passphrase.
    Lock(passphrase []byte) error

    // Unlock unlocks the agent.
    Unlock(passphrase []byte) error

    // Signers returns Signers for all known keys.
    Signers() ([]Signer, error)
}

// ExtendedAgent provides additional agent capabilities.
type ExtendedAgent interface {
    Agent

    // SignWithFlags signs data with additional signature algorithm flags.
    SignWithFlags(key PublicKey, data []byte, flags SignatureFlags) (*Signature, error)

    // Extension processes an extension request.
    Extension(extensionType string, contents []byte) ([]byte, error)
}

// AddedKey represents an SSH key being added to an agent.
type AddedKey struct {
    // PrivateKey is the private key to add.
    PrivateKey interface{}

    // Certificate is an optional certificate.
    Certificate *Certificate

    // Comment is a user comment about the key.
    Comment string

    // LifetimeSecs is the time in seconds that the key should be kept.
    LifetimeSecs uint32

    // ConfirmBeforeUse requires user confirmation before each use.
    ConfirmBeforeUse bool

    // ConstraintExtensions are additional constraints.
    ConstraintExtensions []ConstraintExtension
}

// Key represents an SSH public key in the agent.
type Key struct {
    Format  string
    Blob    []byte
    Comment string
}

// Marshal serializes the key.
func (k *Key) Marshal() []byte

// Type returns the key type.
func (k *Key) Type() string

// Verify verifies a signature.
func (k *Key) Verify(data []byte, sig *Signature) error

// String returns a string representation.
func (k *Key) String() string

// ConstraintExtension represents a user-defined constraint.
type ConstraintExtension struct {
    ExtensionName    string
    ExtensionDetails []byte
}

// SignatureFlags provides additional signature flags.
type SignatureFlags uint32

const (
    SignatureFlagReserved SignatureFlags = 1 << iota
    SignatureFlagRsaSha256
    SignatureFlagRsaSha512
)

Functions

// NewClient creates a new agent client.
func NewClient(rw io.ReadWriter) ExtendedAgent

// NewKeyring creates an in-memory keyring.
func NewKeyring() Agent

// ForwardToAgent routes agent requests from a client to an agent.
func ForwardToAgent(client *Client, keyring Agent) error

// ForwardToRemote routes agent requests to a remote agent.
func ForwardToRemote(client *Client, addr string) error

// RequestAgentForwarding sets up agent forwarding for a session.
func RequestAgentForwarding(session *Session) error

// ServeAgent serves the agent protocol on the given connection.
func ServeAgent(agent Agent, c io.ReadWriter) error

Variables

var ErrExtensionUnsupported = errors.New("agent: extension unsupported")

Package: golang.org/x/crypto/ssh/knownhosts

OpenSSH known_hosts file parser.

Functions

// New creates a HostKeyCallback from known_hosts files.
func New(files ...string) (HostKeyCallback, error)

// Normalize normalizes an address for known_hosts format.
func Normalize(address string) string

// Line returns a known_hosts line for the given addresses and key.
func Line(addresses []string, key PublicKey) string

// HashHostname returns a hashed hostname for known_hosts.
func HashHostname(hostname string) string

Types

// KeyError represents a host key mismatch.
type KeyError struct {
    Want []KnownKey
}

func (u *KeyError) Error() string

// KnownKey represents a key from known_hosts.
type KnownKey struct {
    Key      PublicKey
    Filename string
    Line     int
}

func (k *KnownKey) String() string

// RevokedError represents a revoked key.
type RevokedError struct {
    Revoked KnownKey
}

func (r *RevokedError) Error() string

Package: golang.org/x/crypto/ssh/terminal

Terminal handling functions for SSH sessions.

Deprecation Notice: This package is deprecated and has been moved to golang.org/x/term. All types and functions are re-exported from that package.

Variables

var ErrPasteIndicator = term.ErrPasteIndicator

Functions

// GetSize returns the dimensions of the terminal.
func GetSize(fd int) (width, height int, err error)

// GetState returns the current state of a terminal.
func GetState(fd int) (*State, error)

// IsTerminal reports whether fd is a terminal.
func IsTerminal(fd int) bool

// MakeRaw puts the terminal into raw mode.
func MakeRaw(fd int) (*State, error)

// ReadPassword reads a line of input from fd without local echo.
func ReadPassword(fd int) ([]byte, error)

// Restore restores the terminal to a previous state.
func Restore(fd int, oldState *State) error

Types

// EscapeCodes is a type alias for terminal escape code handling.
type EscapeCodes = term.EscapeCodes

// State represents the state of a terminal.
type State = term.State

// Terminal provides line editing and history for interactive terminals.
type Terminal = term.Terminal

// NewTerminal creates a new Terminal.
func NewTerminal(c io.ReadWriter, prompt string) *Terminal

Usage Examples

SSH Client

package main

import (
    "fmt"
    "io"
    "log"
    "golang.org/x/crypto/ssh"
    "golang.org/x/crypto/ssh/knownhosts"
)

func main() {
    // Setup known_hosts checking
    hostKeyCallback, err := knownhosts.New("~/.ssh/known_hosts")
    if err != nil {
        log.Fatal(err)
    }

    // Configure SSH client
    config := &ssh.ClientConfig{
        User: "username",
        Auth: []ssh.AuthMethod{
            ssh.Password("password"),
        },
        HostKeyCallback: hostKeyCallback,
    }

    // Connect to server
    client, err := ssh.Dial("tcp", "example.com:22", config)
    if err != nil {
        log.Fatal(err)
    }
    defer client.Close()

    // Create session
    session, err := client.NewSession()
    if err != nil {
        log.Fatal(err)
    }
    defer session.Close()

    // Run command
    output, err := session.Output("ls -l")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Output:\n%s\n", output)
}

SSH Client with Public Key Authentication

package main

import (
    "io/ioutil"
    "log"
    "golang.org/x/crypto/ssh"
)

func main() {
    // Read private key
    key, err := ioutil.ReadFile("~/.ssh/id_rsa")
    if err != nil {
        log.Fatal(err)
    }

    // Parse private key
    signer, err := ssh.ParsePrivateKey(key)
    if err != nil {
        log.Fatal(err)
    }

    // Configure client
    config := &ssh.ClientConfig{
        User: "username",
        Auth: []ssh.AuthMethod{
            ssh.PublicKeys(signer),
        },
        HostKeyCallback: ssh.InsecureIgnoreHostKey(), // Use knownhosts.New() in production
    }

    // Connect
    client, err := ssh.Dial("tcp", "example.com:22", config)
    if err != nil {
        log.Fatal(err)
    }
    defer client.Close()

    // Use connection
    session, _ := client.NewSession()
    defer session.Close()
    session.Run("echo 'Connected!'")
}

Port Forwarding

package main

import (
    "io"
    "log"
    "net"
    "golang.org/x/crypto/ssh"
)

func main() {
    // Setup SSH client (config omitted for brevity)
    config := &ssh.ClientConfig{ /* ... */ }
    client, _ := ssh.Dial("tcp", "example.com:22", config)
    defer client.Close()

    // Listen on remote server
    listener, err := client.Listen("tcp", "localhost:8080")
    if err != nil {
        log.Fatal(err)
    }
    defer listener.Close()

    // Forward connections
    for {
        remote, err := listener.Accept()
        if err != nil {
            log.Fatal(err)
        }

        go func(remote net.Conn) {
            defer remote.Close()

            // Connect to local service
            local, err := net.Dial("tcp", "localhost:80")
            if err != nil {
                return
            }
            defer local.Close()

            // Forward traffic
            go io.Copy(local, remote)
            io.Copy(remote, local)
        }(remote)
    }
}

SSH Server

package main

import (
    "fmt"
    "io"
    "log"
    "net"
    "golang.org/x/crypto/ssh"
)

func main() {
    // Generate server key
    key, _ := ssh.ParsePrivateKey(serverKeyPEM)

    // Configure server
    config := &ssh.ServerConfig{
        PasswordCallback: func(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) {
            if c.User() == "user" && string(pass) == "password" {
                return nil, nil
            }
            return nil, fmt.Errorf("password rejected for %q", c.User())
        },
    }
    config.AddHostKey(key)

    // Listen for connections
    listener, err := net.Listen("tcp", "0.0.0.0:2022")
    if err != nil {
        log.Fatal(err)
    }

    for {
        conn, err := listener.Accept()
        if err != nil {
            log.Printf("accept error: %v", err)
            continue
        }

        go handleConnection(conn, config)
    }
}

func handleConnection(conn net.Conn, config *ssh.ServerConfig) {
    defer conn.Close()

    serverConn, chans, reqs, err := ssh.NewServerConn(conn, config)
    if err != nil {
        log.Printf("handshake error: %v", err)
        return
    }
    defer serverConn.Close()

    go ssh.DiscardRequests(reqs)

    for newChannel := range chans {
        if newChannel.ChannelType() != "session" {
            newChannel.Reject(ssh.UnknownChannelType, "unknown channel type")
            continue
        }

        channel, requests, err := newChannel.Accept()
        if err != nil {
            continue
        }

        go func(in <-chan *ssh.Request) {
            for req := range in {
                if req.Type == "exec" {
                    // Handle command execution
                    io.WriteString(channel, "Command executed\n")
                    channel.Close()
                }
                if req.WantReply {
                    req.Reply(true, nil)
                }
            }
        }(requests)
    }
}

Using SSH Agent

package main

import (
    "log"
    "net"
    "os"
    "golang.org/x/crypto/ssh"
    "golang.org/x/crypto/ssh/agent"
)

func main() {
    // Connect to SSH agent
    socket := os.Getenv("SSH_AUTH_SOCK")
    conn, err := net.Dial("unix", socket)
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()

    agentClient := agent.NewClient(conn)

    // Get signers from agent
    signers, err := agentClient.Signers()
    if err != nil {
        log.Fatal(err)
    }

    // Use with SSH client
    config := &ssh.ClientConfig{
        User: "username",
        Auth: []ssh.AuthMethod{
            ssh.PublicKeys(signers...),
        },
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    }

    client, _ := ssh.Dial("tcp", "example.com:22", config)
    defer client.Close()

    // Forward agent to remote server
    session, _ := client.NewSession()
    agent.RequestAgentForwarding(session)
    session.Run("ssh another-server")
}

Best Practices

Security

  1. Host Key Verification: Always use knownhosts.New() in production, never InsecureIgnoreHostKey()
  2. Key Types: Prefer Ed25519 or ECDSA keys over RSA
  3. Algorithms: Use modern algorithms (Curve25519, ChaCha20-Poly1305, AES-GCM)
  4. Avoid: DSA keys, SHA-1 key exchange, CBC ciphers

Performance

  1. Connection Reuse: Reuse SSH connections for multiple sessions
  2. KeepAlive: Implement keepalive for long-running connections
  3. Multiplexing: Use SSH connection sharing when possible

Error Handling

  1. Timeouts: Set appropriate timeouts in ClientConfig
  2. Retry Logic: Use RetryableAuthMethod for unreliable networks
  3. Resource Cleanup: Always defer Close() calls

Common Patterns

  1. Interactive Shell: Use RequestPty() for interactive sessions
  2. SFTP: Use github.com/pkg/sftp for file transfers over SSH
  3. Jump Hosts: Chain SSH connections through bastion hosts