dockerssh

package
v0.9.2 Latest Latest
Warning

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

Go to latest
Published: Nov 6, 2026 License: Apache-2.0 Imports: 23 Imported by: 0

Documentation

Overview

Package dockerssh reads a remote Docker host over an SSH login without running anything on it: SSH is only a transport to the Docker socket, and a client-side allowlist lets nothing but read-only Engine API GETs out.

Index

Constants

View Source
const (
	KindAuth             = "auth_failed"
	KindHostKey          = "host_key_mismatch"
	KindHostKeyRequired  = "host_key_required"
	KindSocketPermission = "socket_permission"
	KindSocketPath       = "socket_path"
	KindSocketForbidden  = "socket_forbidden"
	KindUnreachable      = "unreachable"
	KindBlockedAddress   = "blocked_address"
	KindOther            = "other"
)

Failure kinds the API turns into a typed fix.

View Source
const DefaultSocketPath = "/var/run/docker.sock"

DefaultSocketPath is the Docker socket opened when none is given.

Variables

View Source
var ErrBlockedAddress = errors.New("dockerssh: ssh address is not allowed")

ErrBlockedAddress means the SSH target resolved to an address the network policy forbids.

View Source
var ErrLimit = errors.New("dockerssh: archive passes the configured limit")

ErrLimit is returned when an archive passes a size or file count cap.

View Source
var ErrRequestForbidden = errors.New("dockerssh: request is not on the read-only allowlist")

ErrRequestForbidden is wrapped by every refusal of the read-only transport.

Functions

func KindOf

func KindOf(err error) string

KindOf returns the failure kind of err, KindOther when it has none.

Types

type Config

type Config struct {
	Host string
	Port int
	User string
	// PrivateKey is a PEM private key, Passphrase unlocks it, Password is an
	// alternative or additional login. Wipe zeroes all three.
	PrivateKey []byte
	Passphrase []byte
	Password   []byte
	// Fingerprint is the pinned host key, SHA256:... as ssh-keygen -l prints it.
	Fingerprint string
	// InsecureHostKey skips host key verification, an explicit opt in.
	InsecureHostKey bool
	SocketPath      string
	DialTimeout     time.Duration
	// CheckAddr vets every dialed IP, including after DNS resolution.
	CheckAddr func(netip.Addr) error
}

Config is one SSH login to a Docker host. The secrets are held in memory for the life of the session and are never written anywhere.

func (*Config) Wipe

func (c *Config) Wipe()

Wipe zeroes the credential buffers.

type Error

type Error struct {
	Kind string
	Msg  string
	Err  error
}

Error is a connection failure with a machine-readable kind.

func (*Error) Error

func (e *Error) Error() string

func (*Error) Unwrap

func (e *Error) Unwrap() error

type ExtractStats

type ExtractStats struct {
	Files   int   `json:"files"`
	Dirs    int   `json:"dirs"`
	Bytes   int64 `json:"bytes"`
	Skipped int   `json:"skipped"`
	// Warnings names entries that were left out and why, capped.
	Warnings []string `json:"warnings,omitempty"`
}

ExtractStats reports what an extraction wrote.

func ExtractArchive

func ExtractArchive(r io.Reader, dst string, lim Limits) (ExtractStats, error)

ExtractArchive unpacks a container archive of one directory into dst. The archive's first path component (the directory's own name) is stripped. Names that leave dst, symlinks that could leave it, hard links and device nodes are never created, and no entry is written through a symlink.

type ForbiddenRequestError

type ForbiddenRequestError struct {
	Method string
	Path   string
	Reason string
}

ForbiddenRequestError says which request the allowlist refused and why.

func (*ForbiddenRequestError) Error

func (e *ForbiddenRequestError) Error() string

func (*ForbiddenRequestError) Unwrap

func (e *ForbiddenRequestError) Unwrap() error

type HostKey

type HostKey = sshprovision.HostKey

HostKey is one host key a server presented.

func ScanHostKeys

func ScanHostKeys(ctx context.Context, cfg Config) ([]HostKey, error)

ScanHostKeys connects and returns every host key the server presents. It never authenticates: each handshake stops inside the host key callback, before a user name or credential is sent.

type Limits

type Limits struct {
	MaxBytes int64
	MaxFiles int
}

Limits bound one extraction. Zero means unlimited.

type Overview

type Overview struct {
	DockerVersion string `json:"docker_version"`
	OS            string `json:"os,omitempty"`
	Swarm         bool   `json:"swarm"`
	Containers    int    `json:"containers"`
	Running       int    `json:"running"`
	Volumes       int    `json:"volumes"`
	Images        int    `json:"images"`
}

Overview is what a connection test reports it can read.

type ReadOnlyTransport

type ReadOnlyTransport struct {
	// contains filtered or unexported fields
}

ReadOnlyTransport is an http.RoundTripper that refuses every request that is not an allowlisted read-only Docker Engine API GET, before it is sent.

func NewReadOnlyTransport

func NewReadOnlyTransport(inner http.RoundTripper) *ReadOnlyTransport

NewReadOnlyTransport wraps inner with the read-only allowlist.

func (*ReadOnlyTransport) Check

func (t *ReadOnlyTransport) Check(req *http.Request) error

Check reports whether the request is allowed. It is pure apart from the mount destinations learned from earlier container inspects.

func (*ReadOnlyTransport) RoundTrip

func (t *ReadOnlyTransport) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip refuses anything off the allowlist and learns mount destinations from allowed container inspects.

type Saver

type Saver struct {
	Cfg Config
}

Saver streams an image from the source host through the socket tunnel, the read-only replacement for running a save command there.

func (Saver) Save

func (s Saver) Save(ctx context.Context, ref string) (io.ReadCloser, error)

Save opens a session, requests the image archive and returns a stream whose Close also ends the SSH connection.

type Session

type Session struct {
	// contains filtered or unexported fields
}

Session is one open SSH connection used only as a transport to the Docker socket. It has no shell, no command execution and no other forwarding.

func Open

func Open(ctx context.Context, cfg Config) (*Session, error)

Open logs in, opens the Docker socket channel and pings the daemon.

func (*Session) Close

func (s *Session) Close()

Close ends the SSH connection.

func (*Session) ContainerArchive

func (s *Session) ContainerArchive(ctx context.Context, containerID, mountPath string) (io.ReadCloser, error)

ContainerArchive streams a tar of one of the container's own mount destinations. The container is inspected first so the allowlist learns which destinations it may ask for.

func (*Session) CopyMount

func (s *Session) CopyMount(ctx context.Context, containerID, mountPath, dstDir string, lim Limits) (ExtractStats, error)

CopyMount streams one of a container's own mount destinations through the tunnel and unpacks it into dstDir with the extraction safeguards applied.

func (*Session) ImageSave

func (s *Session) ImageSave(ctx context.Context, ref string) (io.ReadCloser, error)

ImageSave streams the image as `docker save` would, through the tunnel.

func (*Session) InspectAll

func (s *Session) InspectAll(ctx context.Context) ([]byte, error)

InspectAll returns the inspect JSON of every container as one array, the same shape `docker inspect` prints.

func (*Session) Ping

func (s *Session) Ping(ctx context.Context) error

Ping checks that the daemon answers on the socket.

func (*Session) Probe

func (s *Session) Probe(ctx context.Context) (Overview, error)

Probe reads the version and counts what an import can see.

func (*Session) SwarmServices

func (s *Session) SwarmServices(ctx context.Context) ([]byte, error)

SwarmServices lists swarm services on a manager node, for Swarm sources.

func (*Session) Warnings

func (s *Session) Warnings() []string

Warnings lists caveats of this session, such as a skipped host key check.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL