Documentation
¶
Overview ¶
Package sessionrecording contains session recording utils shared amongst Tailscale SSH and Kubernetes API server proxy session recording.
Index ¶
- Constants
- func ConnectToRecorder(ctx context.Context, recs []netip.AddrPort, dial netx.DialFunc) (io.WriteCloser, []*tailcfg.SSHRecordingAttempt, <-chan error, error)
- func SendEvent(ap netip.AddrPort, event io.Reader, dial netx.DialFunc) (retErr error)
- type CastHeader
- type Destination
- type Event
- type EventAPINotSupportedErr
- type Kubernetes
- type KubernetesRequestInfo
- type Request
- type Source
Constants ¶
const (
KubernetesAPIEventType = "kubernetes-api-request"
)
Variables ¶
This section is empty.
Functions ¶
func ConnectToRecorder ¶
func ConnectToRecorder(ctx context.Context, recs []netip.AddrPort, dial netx.DialFunc) (io.WriteCloser, []*tailcfg.SSHRecordingAttempt, <-chan error, error)
ConnectToRecorder connects to the recorder at any of the provided addresses. It returns the first successful response, or a multierr if all attempts fail.
On success, it returns a WriteCloser that can be used to upload the recording, and a channel that will be sent an error (or nil) when the upload fails or completes.
In both cases, a slice of SSHRecordingAttempts is returned which detail the attempted recorder IP and the error message, if the attempt failed. The attempts are in order the recorder(s) was attempted. If successful a successful connection is made, the last attempt in the slice is the attempt for connected recorder.
Types ¶
type CastHeader ¶
type CastHeader struct {
// Version is the asciinema file format version.
Version int `json:"version"`
// Width is the terminal width in characters.
// It is non-zero for Pty sessions.
Width int `json:"width"`
// Height is the terminal height in characters.
// It is non-zero for Pty sessions.
Height int `json:"height"`
// Timestamp is the unix timestamp of when the recording started.
Timestamp int64 `json:"timestamp"`
// Command is the command that was executed.
// Typically empty for shell sessions.
Command string `json:"command,omitempty"`
// SrcNode is the FQDN of the node originating the connection.
// It is also the MagicDNS name for the node.
// It does not have a trailing dot.
// e.g. "host.tail-scale.ts.net"
SrcNode string `json:"srcNode"`
// SrcNodeID is the node ID of the node originating the connection.
SrcNodeID tailcfg.StableNodeID `json:"srcNodeID"`
// Tailscale-specific fields:
// SrcNodeTags is the list of tags on the node originating the connection (if any).
SrcNodeTags []string `json:"srcNodeTags,omitempty"`
// SrcNodeUserID is the user ID of the node originating the connection (if not tagged).
SrcNodeUserID tailcfg.UserID `json:"srcNodeUserID,omitempty"` // if not tagged
// SrcNodeUser is the LoginName of the node originating the connection (if not tagged).
SrcNodeUser string `json:"srcNodeUser,omitempty"`
// Env is the environment variables of the session.
// Only "TERM" is set (2023-03-22).
Env map[string]string `json:"env"`
// SSHUser is the username as presented by the client.
SSHUser string `json:"sshUser"` // as presented by the client
// LocalUser is the effective username on the server.
LocalUser string `json:"localUser"`
// ConnectionID uniquely identifies a connection made to the SSH server.
// It may be shared across multiple sessions over the same connection in
// case of SSH multiplexing.
ConnectionID string `json:"connectionID"`
// Fields that are only set for Kubernetes API server proxy session recordings:
Kubernetes *Kubernetes `json:"kubernetes,omitempty"`
}
CastHeader is the header of an asciinema file.
type Destination ¶ added in v1.90.0
type Destination struct {
// Node is the FQDN of the node receiving the connection.
// It is also the MagicDNS name for the node.
// It does not have a trailing dot.
// e.g. "host.tail-scale.ts.net"
Node string `json:"node"`
// NodeID is the node ID of the node receiving the connection.
NodeID tailcfg.StableNodeID `json:"nodeID"`
}
type Event ¶ added in v1.90.0
type Event struct {
// Type specifies the kind of event being recorded (e.g., "kubernetes-api-request").
Type string `json:"type"`
// ID is a reference of the path that this event is stored at in tsrecorder
ID string `json:"id"`
// Timestamp is the time when the event was recorded represented as a unix timestamp.
Timestamp int64 `json:"timestamp"`
// UserAgent is the UerAgent specified in the request, which helps identify
// the client software that initiated the request.
UserAgent string `json:"userAgent"`
// Request holds details of the HTTP request.
Request Request `json:"request"`
// Kubernetes contains Kubernetes-specific information about the request (if
// the type is `kubernetes-api-request`)
Kubernetes KubernetesRequestInfo `json:"kubernetes"`
// Source provides details about the client that initiated the request.
Source Source `json:"source"`
// Destination provides details about the node receiving the request.
Destination Destination `json:"destination"`
}
Event represents the top-level structure of a tsrecorder event.
type EventAPINotSupportedErr ¶ added in v1.90.0
type EventAPINotSupportedErr struct {
// contains filtered or unexported fields
}
func (EventAPINotSupportedErr) Error ¶ added in v1.90.0
func (e EventAPINotSupportedErr) Error() string
type Kubernetes ¶
type Kubernetes struct {
// PodName is the name of the Pod the session was recorded for.
PodName string
// Namespace is the namespace in which the Pod the session was recorded for exists in.
Namespace string
// Container is the container the session was recorded for.
Container string
// SessionType is the type of session that was executed (e.g., exec, attach)
SessionType string
}
Kubernetes contains 'kubectl exec/attach' session specific information for tsrecorder.
type KubernetesRequestInfo ¶ added in v1.90.0
type KubernetesRequestInfo struct {
// IsResourceRequest indicates whether or not the request is for an API resource or subresource
IsResourceRequest bool
// Path is the URL path of the request
Path string
// Verb is the kube verb associated with the request for API requests, not the http verb. This includes things like list and watch.
// for non-resource requests, this is the lowercase http verb
Verb string
APIPrefix string
APIGroup string
APIVersion string
Namespace string
// Resource is the name of the resource being requested. This is not the kind. For example: pods
Resource string
// Subresource is the name of the subresource being requested. This is a different resource, scoped to the parent resource, but it may have a different kind.
// For instance, /pods has the resource "pods" and the kind "Pod", while /pods/foo/status has the resource "pods", the sub resource "status", and the kind "Pod"
// (because status operates on pods). The binding resource for a pod though may be /pods/foo/binding, which has resource "pods", subresource "binding", and kind "Binding".
Subresource string
// Name is empty for some verbs, but if the request directly indicates a name (not in body content) then this field is filled in.
Name string
// Parts are the path parts for the request, always starting with /{resource}/{name}
Parts []string
// FieldSelector contains the unparsed field selector from a request. It is only present if the apiserver
// honors field selectors for the verb this request is associated with.
FieldSelector string
// LabelSelector contains the unparsed field selector from a request. It is only present if the apiserver
// honors field selectors for the verb this request is associated with.
LabelSelector string
}
copied from https://github.com/kubernetes/kubernetes/blob/11ade2f7dd264c2f52a4a1342458abbbaa3cb2b1/staging/src/k8s.io/apiserver/pkg/endpoints/request/requestinfo.go#L44 KubernetesRequestInfo contains Kubernetes specific information in the request (if the type is `kubernetes-api-request`)
type Request ¶ added in v1.90.0
type Request struct {
Method string `json:"method"`
Path string `json:"path"`
Body []byte `json:"body"`
QueryParameters url.Values `json:"queryParameters"`
}
Request holds information about a request.
type Source ¶ added in v1.90.0
type Source struct {
// Node is the FQDN of the node originating the connection.
// It is also the MagicDNS name for the node.
// It does not have a trailing dot.
// e.g. "host.tail-scale.ts.net"
Node string `json:"node"`
// NodeID is the node ID of the node originating the connection.
NodeID tailcfg.StableNodeID `json:"nodeID"`
// Tailscale-specific fields:
// NodeTags is the list of tags on the node originating the connection (if any).
NodeTags []string `json:"nodeTags,omitempty"`
// NodeUserID is the user ID of the node originating the connection (if not tagged).
NodeUserID tailcfg.UserID `json:"nodeUserID,omitempty"` // if not tagged
// NodeUser is the LoginName of the node originating the connection (if not tagged).
NodeUser string `json:"nodeUser,omitempty"`
}