Documentation ¶
Overview ¶
Package events implements the audit log interface events.IAuditLog using filesystem backend.
Audit logs ----------
Audit logs are events associated with user logins, server access and session log events like session.start.
Example audit log event:
{"addr.local":"172.10.1.20:3022",
"addr.remote":"172.10.1.254:58866", "event":"session.start", "login":"root", "user":"klizhentas@gmail.com" }
Session Logs ------------
Session logs are a series of events and recorded SSH interactive session playback.
Example session log event:
{ "time":"2018-01-04T02:12:40.245Z", "event":"print", "bytes":936, "ms":40962, "offset":16842, "ei":31, "ci":29 }
Print event fields ------------------
Print event specifies session output - PTY io recorded by Teleport node or Proxy based on the configuration.
* "offset" is an offset in bytes from a start of a session * "ms" is a delay in milliseconds from the last event occured * "ci" is a chunk index ordering only print events * "ei" is an event index ordering events from the first one
As in example of print event above, "ei" - is a session event index - 31, while "ci" is a chunk index - meaning that this event is 29th in a row of print events.
Client streaming session logs ------------------------------
Session related logs are delivered in order defined by clients. Every event is ordered and has a session-local index, every next event has index incremented.
Client deliveres session events in batches, where every event in the batch is guaranteed to be in continuous order (e.g. no cases with events delivered in a single batch to have missing event or chunk index).
Disk File format ----------------
On disk file format is designed to be compatible with NFS filesystems and provides guarantee that only one auth server writes to the file at a time.
Main Audit Log Format =====================
The main log files are saved as:
/var/lib/teleport/log/<auth-server-id>/<date>.log
The log file is rotated every 24 hours. The old files must be cleaned up or archived by an external tool.
Log file format: utc_date,action,json_fields
Common JSON fields - user : teleport user - login : server OS login, the user logged in as - addr.local : server address:port - addr.remote: connected client's address:port - sid : session ID (GUID format)
Examples: 2016-04-25 22:37:29 +0000 UTC,session.start,{"addr.local":"127.0.0.1:3022","addr.remote":"127.0.0.1:35732","login":"root","sid":"4a9d97de-0b36-11e6-a0b3-d8cb8ae5080e","user":"vincent"} 2016-04-25 22:54:31 +0000 UTC,exec,{"addr.local":"127.0.0.1:3022","addr.remote":"127.0.0.1:35949","command":"-bash -c ls /","login":"root","user":"vincent"}
Session log file format =======================
Each session has its own session log stored as several files:
Index file contains a list of event files and chunks files associated with a session:
/var/lib/teleport/log/sessions/<auth-server-id>/<session-id>.index
The format of the index file contains of two or more lines with pointers to other files:
{"file_name":"<session-id>-<first-event-in-file-index>.events","type":"events","index":<first-event-in-file-index>} {"file_name":"<session-id>-<first-chunk-in-file-offset>.chunks","type":"chunks","offset":<first-chunk-in-file-offset>}
Files:
/var/lib/teleport/log/<auth-server-id>/<session-id>-<first-event-in-file-index>.events /var/lib/teleport/log/<auth-server-id>/<session-id>-<first-chunk-in-file-offset>.chunks
Where:
- .events (same events as in the main log, but related to the session)
- .chunks (recorded session bytes: PTY IO)
Examples ~~~~~~~~
**Single auth server**
In the simplest case, single auth server a1 log for a single session id s1 will consist of three files:
/var/lib/teleport/a1/s1.index
With contents:
{"file_name":"s1-0.events","type":"events","index":0} {"file_name":"s1-0.chunks","type":"chunks","offset":0}
This means that all session events are located in s1-0.events file starting from the first event with index 0 and all chunks are located in file s1-0.chunks file with the byte offset from the start - 0.
File with session events /var/lib/teleport/a1/s1-0.events will contain:
{"ei":0,"event":"session.start", ...} {"ei":1,"event":"resize",...} {"ei":2,"ci":0, "event":"print","bytes":40,"offset":0} {"ei":3,"event":"session.end", ...}
File with recorded session /var/lib/teleport/a1/s1-0.chunks will contain 40 bytes emitted by print event with chunk index 0
**Multiple Auth Servers**
In high availability mode scenario, multiple auth servers will be
deployed behind a load balancer.
Any auth server can go down during session and clients will retry the delivery to the other auth server.
Both auth servers have mounted /var/lib/teleport/log as a shared NFS folder.
To make sure that only one auth server writes to a file at a time, each auth server writes to it's own file in a sub folder named with host UUID of the server.
Client sends the chunks of events related to the session s1 in order, but load balancer sends first batch of event to the first server a1, and the second batch of event to the second server a2.
Server a1 will produce the following file:
/var/lib/teleport/a1/s1.index
With contents:
{"file_name":"s1-0.events","type":"events","index":0} {"file_name":"s1-0.chunks","type":"chunks","offset":0}
Events file /var/lib/teleport/a1/s1-0.events will contain:
{"ei":0,"event":"session.start", ...} {"ei":1,"event":"resize",...} {"ei":2,"ci":0, "event":"print","bytes":40,"offset":0}
Events file /var/lib/teleport/a1/s1-0.chunks will contain 40 bytes emitted by print event with chunk index.
Server a2 will produce the following file:
/var/lib/teleport/a2/s1.index
With contents:
{"file_name":"s1-3.events","type":"events","index":3} {"file_name":"s1-40.chunks","type":"chunks","offset":40}
Events file /var/lib/teleport/a2/s1-4.events will contain:
{"ei":3,"ci":1, "event":"print","bytes":15,"ms":713,"offset":40} {"ei":4,"event":"session.end", ...}
Events file /var/lib/teleport/a2/s1-40.chunks will contain 15 bytes emitted by print event with chunk index 1 and comes after delay of 713 milliseconds.
Offset 40 indicates that the first chunk stored in the file s1-40.chunks comes at an offset of 40 bytes from the start of the session.
Log Search and Playback -----------------------
Log search and playback is aware of multiple auth servers, merges indexes, event streams stored on multiple auth servers.
Package events is a generated protocol buffer package. It is generated from these files: slice.proto It has these top-level messages: SessionSlice SessionChunk
Index ¶
- Constants
- Variables
- func NewSessionArchive(dataDir, serverID, namespace string, sessionID session.ID) (io.ReadCloser, error)
- func RegisterAuditLogServer(s *grpc.Server, srv AuditLogServer)
- type AuditLog
- func (l *AuditLog) Close() error
- func (l *AuditLog) EmitAuditEvent(eventType string, fields EventFields) error
- func (l *AuditLog) GetSessionChunk(namespace string, sid session.ID, offsetBytes, maxBytes int) ([]byte, error)
- func (l *AuditLog) GetSessionEvents(namespace string, sid session.ID, afterN int, includePrintEvents bool) ([]EventFields, error)
- func (l *AuditLog) LoggerFor(namespace string, sid session.ID, compatibilityMode bool) (SessionLogger, error)
- func (l *AuditLog) PostSessionChunk(namespace string, sid session.ID, reader io.Reader) error
- func (l *AuditLog) PostSessionSlice(slice SessionSlice) error
- func (l *AuditLog) SearchEvents(fromUTC, toUTC time.Time, query string, limit int) ([]EventFields, error)
- func (l *AuditLog) SearchSessionEvents(fromUTC, toUTC time.Time, limit int) ([]EventFields, error)
- func (l *AuditLog) WaitForDelivery(context.Context) error
- type AuditLogClient
- type AuditLogConfig
- type AuditLogServer
- type AuditLog_SubmitSessionSliceClient
- type AuditLog_SubmitSessionSliceServer
- type ByTimeAndIndex
- type CompatSessionLogger
- type CompatSessionLoggerConfig
- type DiscardAuditLog
- func (d *DiscardAuditLog) Close() error
- func (d *DiscardAuditLog) EmitAuditEvent(eventType string, fields EventFields) error
- func (d *DiscardAuditLog) GetSessionChunk(namespace string, sid session.ID, offsetBytes, maxBytes int) ([]byte, error)
- func (d *DiscardAuditLog) GetSessionEvents(namespace string, sid session.ID, after int, includePrintEvents bool) ([]EventFields, error)
- func (d *DiscardAuditLog) PostSessionChunk(namespace string, sid session.ID, reader io.Reader) error
- func (d *DiscardAuditLog) PostSessionSlice(SessionSlice) error
- func (d *DiscardAuditLog) SearchEvents(fromUTC, toUTC time.Time, query string, limit int) ([]EventFields, error)
- func (d *DiscardAuditLog) SearchSessionEvents(fromUTC time.Time, toUTC time.Time, limit int) ([]EventFields, error)
- func (d *DiscardAuditLog) WaitForDelivery(context.Context) error
- type DiskSessionLogger
- type DiskSessionLoggerConfig
- type EventFields
- type Forwarder
- func (l *Forwarder) Close() error
- func (l *Forwarder) EmitAuditEvent(eventType string, fields EventFields) error
- func (l *Forwarder) GetSessionChunk(namespace string, sid session.ID, offsetBytes, maxBytes int) ([]byte, error)
- func (l *Forwarder) GetSessionEvents(namespace string, sid session.ID, after int, includePrintEvents bool) ([]EventFields, error)
- func (l *Forwarder) PostSessionChunk(namespace string, sid session.ID, reader io.Reader) error
- func (l *Forwarder) PostSessionSlice(slice SessionSlice) error
- func (l *Forwarder) SearchEvents(fromUTC, toUTC time.Time, query string, limit int) ([]EventFields, error)
- func (l *Forwarder) SearchSessionEvents(fromUTC time.Time, toUTC time.Time, limit int) ([]EventFields, error)
- func (l *Forwarder) WaitForDelivery(ctx context.Context) error
- type ForwarderConfig
- type IAuditLog
- type MockAuditLog
- func (d *MockAuditLog) Close() error
- func (d *MockAuditLog) EmitAuditEvent(eventType string, fields EventFields) error
- func (d *MockAuditLog) GetError() error
- func (d *MockAuditLog) GetSessionChunk(namespace string, sid session.ID, offsetBytes, maxBytes int) ([]byte, error)
- func (d *MockAuditLog) GetSessionEvents(namespace string, sid session.ID, after int, fetchPrintEvents bool) ([]EventFields, error)
- func (d *MockAuditLog) PostSessionChunk(namespace string, sid session.ID, reader io.Reader) error
- func (d *MockAuditLog) PostSessionSlice(slice SessionSlice) error
- func (d *MockAuditLog) SearchEvents(fromUTC, toUTC time.Time, query string, limit int) ([]EventFields, error)
- func (d *MockAuditLog) SearchSessionEvents(fromUTC, toUTC time.Time, limit int) ([]EventFields, error)
- func (d *MockAuditLog) SetError(e error)
- func (d *MockAuditLog) WaitForDelivery(context.Context) error
- type SessionChunk
- func (*SessionChunk) Descriptor() ([]byte, []int)
- func (m *SessionChunk) Marshal() (data []byte, err error)
- func (m *SessionChunk) MarshalTo(data []byte) (int, error)
- func (*SessionChunk) ProtoMessage()
- func (m *SessionChunk) Reset()
- func (m *SessionChunk) Size() (n int)
- func (m *SessionChunk) String() string
- func (m *SessionChunk) Unmarshal(data []byte) error
- type SessionLogger
- type SessionSlice
- func (*SessionSlice) Descriptor() ([]byte, []int)
- func (m *SessionSlice) GetChunks() []*SessionChunk
- func (m *SessionSlice) Marshal() (data []byte, err error)
- func (m *SessionSlice) MarshalTo(data []byte) (int, error)
- func (*SessionSlice) ProtoMessage()
- func (m *SessionSlice) Reset()
- func (m *SessionSlice) Size() (n int)
- func (m *SessionSlice) String() string
- func (m *SessionSlice) Unmarshal(data []byte) error
- type UploadEvent
- type UploadHandler
- type Uploader
- type UploaderConfig
Constants ¶
const ( // Common event fields: EventType = "event" // event type/kind EventTime = "time" // event time EventLogin = "login" // OS login EventUser = "user" // teleport user LocalAddr = "addr.local" // address on the host RemoteAddr = "addr.remote" // client (user's) address EventCursor = "id" // event ID (used as cursor value for enumeration, not stored) // EventIndex is an event index as received from the logging server EventIndex = "ei" // EventNamespace is a namespace of the session event EventNamespace = "namespace" // SessionPrintEvent event happens every time a write occurs to // temirnal I/O during a session SessionPrintEvent = "print" // SessionPrintEventBytes says how many bytes have been written into the session // during "print" event SessionPrintEventBytes = "bytes" // SessionEventTimestamp is an offset (in milliseconds) since the beginning of the // session when the terminal IO event happened SessionEventTimestamp = "ms" // SessionEvent indicates that session has been initiated // or updated by a joining party on the server SessionStartEvent = "session.start" // SessionEndEvent indicates that a session has ended SessionEndEvent = "session.end" // SessionUploadEvent indicates that session has been uploaded to the external storage SessionUploadEvent = "session.upload" // URL is used for a session upload URL URL = "url" SessionEventID = "sid" SessionServerID = "server_id" // SessionByteOffset is the number of bytes written to session stream since // the beginning SessionByteOffset = "offset" // SessionJoinEvent indicates that someone joined a session SessionJoinEvent = "session.join" // SessionLeaveEvent indicates that someone left a session SessionLeaveEvent = "session.leave" // UserLoginEvent indicates that a user logged into web UI or via tsh UserLoginEvent = "user.login" // LoginMethod is the event field indicating how the login was performed LoginMethod = "method" // LoginMethodLocal represents login with username/password LoginMethodLocal = "local" // LoginMethodOIDC represents login with OIDC LoginMethodOIDC = "oidc" // LoginMethodSAML represents login with SAML LoginMethodSAML = "saml" // LoginMethodGithub represents login with Github LoginMethodGithub = "github" // ExecEvent is an exec command executed by script or user on // the server side ExecEvent = "exec" ExecEventCommand = "command" ExecEventCode = "exitCode" ExecEventError = "exitError" // SubsystemEvent is the result of the execution of a subsystem. SubsystemEvent = "subsystem" SubsystemName = "name" SubsystemError = "exitError" // Port forwarding event PortForwardEvent = "port" PortForwardAddr = "addr" PortForwardSuccess = "success" PortForwardErr = "error" // AuthAttemptEvent is authentication attempt that either // succeeded or failed based on event status AuthAttemptEvent = "auth" AuthAttemptSuccess = "success" AuthAttemptErr = "error" // SCPEvent means data transfer that occurred on the server SCPEvent = "scp" SCPPath = "path" SCPLengh = "len" SCPAction = "action" // ResizeEvent means that some user resized PTY on the client ResizeEvent = "resize" TerminalSize = "size" // expressed as 'W:H' )
const ( // V1 is the V1 version of slice chunks API, // it is 0 because it was not defined before V1 = 0 // V2 is the V2 version of slice chunks API V2 = 2 )
const ( // SessionLogsDir is a subdirectory inside the eventlog data dir // where all session-specific logs and streams are stored, like // in /var/lib/teleport/logs/sessions SessionLogsDir = "sessions" // PlaybacksDir is a directory for playbacks PlaybackDir = "playbacks" // LogfileExt defines the ending of the daily event log file LogfileExt = ".log" )
const ( // MaxChunkBytes defines the maximum size of a session stream chunk that // can be requested via AuditLog.GetSessionChunk(). Set to 5MB MaxChunkBytes = 1024 * 1024 * 5 )
Variables ¶
var ( ErrInvalidLengthSlice = fmt.Errorf("proto: negative length found during unmarshaling") ErrIntOverflowSlice = fmt.Errorf("proto: integer overflow") )
Functions ¶
func NewSessionArchive ¶
func NewSessionArchive(dataDir, serverID, namespace string, sessionID session.ID) (io.ReadCloser, error)
NewSessionArchive returns generated tar archive with all components
func RegisterAuditLogServer ¶
func RegisterAuditLogServer(s *grpc.Server, srv AuditLogServer)
Types ¶
type AuditLog ¶ added in v1.0.0
type AuditLog struct { sync.Mutex *log.Entry AuditLogConfig // contains filtered or unexported fields }
AuditLog is a new combined facility to record Teleport events and sessions. It implements IAuditLog
func NewAuditLog ¶ added in v1.0.0
func NewAuditLog(cfg AuditLogConfig) (*AuditLog, error)
Creates and returns a new Audit Log object whish will store its logfiles in a given directory. Session recording can be disabled by setting recordSessions to false.
func (*AuditLog) Close ¶ added in v1.0.0
Closes the audit log, which inluces closing all file handles and releasing all session loggers
func (*AuditLog) EmitAuditEvent ¶ added in v1.0.0
func (l *AuditLog) EmitAuditEvent(eventType string, fields EventFields) error
EmitAuditEvent adds a new event to the log. Part of auth.IAuditLog interface.
func (*AuditLog) GetSessionChunk ¶ added in v1.0.0
func (l *AuditLog) GetSessionChunk(namespace string, sid session.ID, offsetBytes, maxBytes int) ([]byte, error)
GetSessionChunk returns a reader which console and web clients request to receive a live stream of a given session. The reader allows access to a session stream range from offsetBytes to offsetBytes+maxBytes
func (*AuditLog) GetSessionEvents ¶ added in v1.0.0
func (l *AuditLog) GetSessionEvents(namespace string, sid session.ID, afterN int, includePrintEvents bool) ([]EventFields, error)
Returns all events that happen during a session sorted by time (oldest first).
Can be filtered by 'after' (cursor value to return events newer than)
This function is usually used in conjunction with GetSessionReader to replay recorded session streams.
func (*AuditLog) LoggerFor ¶ added in v1.0.0
func (l *AuditLog) LoggerFor(namespace string, sid session.ID, compatibilityMode bool) (SessionLogger, error)
LoggerFor creates a logger for a specified session. Session loggers allow to group all events into special "session log files" for easier audit
func (*AuditLog) PostSessionChunk ¶ added in v1.0.0
DELETE IN: 2.6.0 This method is no longer used in 2.5.0 PostSessionChunk writes a new chunk of session stream into the audit log
func (*AuditLog) PostSessionSlice ¶
func (l *AuditLog) PostSessionSlice(slice SessionSlice) error
PostSessionSlice submits slice of session chunks to the audit log server.
func (*AuditLog) SearchEvents ¶ added in v1.0.0
func (l *AuditLog) SearchEvents(fromUTC, toUTC time.Time, query string, limit int) ([]EventFields, error)
SearchEvents finds events. Results show up sorted by date (newest first), limit is used when set to value > 0
func (*AuditLog) SearchSessionEvents ¶
SearchSessionEvents searches for session related events. Used to find completed sessions.
type AuditLogClient ¶
type AuditLogClient interface {
SubmitSessionSlice(ctx context.Context, opts ...grpc.CallOption) (AuditLog_SubmitSessionSliceClient, error)
}
func NewAuditLogClient ¶
func NewAuditLogClient(cc *grpc.ClientConn) AuditLogClient
type AuditLogConfig ¶
type AuditLogConfig struct { // DataDir is the directory where audit log stores the data DataDir string // ServerID is the id of the audit log server ServerID string // RecordSessions controls if sessions are recorded along with audit events. RecordSessions bool // RotationPeriod defines how frequently to rotate the log file RotationPeriod time.Duration // SessionIdlePeriod defines the period after which sessions will be considered // idle (and audit log will free up some resources) SessionIdlePeriod time.Duration // Clock is a clock either real one or used in tests Clock clockwork.Clock // GID if provided will be used to set group ownership of the directory // to GID GID *int // UID if provided will be used to set userownership of the directory // to UID UID *int // DirMask if provided will be used to set directory mask access // otherwise set to default value DirMask *os.FileMode // PlaybackRecycleTTL is a time after uncompressed playback files will be // deleted PlaybackRecycleTTL time.Duration // UploadHandler is a pluggable external upload handler, // used to fetch sessions from external sources UploadHandler UploadHandler // ExternalLog is a pluggable external log service ExternalLog IAuditLog }
AuditLogConfig specifies configuration for AuditLog server
func (*AuditLogConfig) CheckAndSetDefaults ¶
func (a *AuditLogConfig) CheckAndSetDefaults() error
CheckAndSetDefaults checks and sets defaults
type AuditLogServer ¶
type AuditLogServer interface {
SubmitSessionSlice(AuditLog_SubmitSessionSliceServer) error
}
type AuditLog_SubmitSessionSliceClient ¶
type AuditLog_SubmitSessionSliceClient interface { Send(*SessionSlice) error CloseAndRecv() (*google_protobuf1.Empty, error) grpc.ClientStream }
type AuditLog_SubmitSessionSliceServer ¶
type AuditLog_SubmitSessionSliceServer interface { SendAndClose(*google_protobuf1.Empty) error Recv() (*SessionSlice, error) grpc.ServerStream }
type ByTimeAndIndex ¶
type ByTimeAndIndex []EventFields
ByTimeAndIndex sorts events by time extracting timestamp from JSON field and if there are several session events with the same session by event index, regardless of the time
func (ByTimeAndIndex) Len ¶
func (f ByTimeAndIndex) Len() int
func (ByTimeAndIndex) Less ¶
func (f ByTimeAndIndex) Less(i, j int) bool
func (ByTimeAndIndex) Swap ¶
func (f ByTimeAndIndex) Swap(i, j int)
type CompatSessionLogger ¶
type CompatSessionLogger struct { CompatSessionLoggerConfig *log.Entry sync.Mutex // contains filtered or unexported fields }
CompatSessionLogger implements a disk based session logger. The imporant property of the disk based logger is that it never fails and can be used as a fallback implementation behind more sophisticated loggers.
func NewCompatSessionLogger ¶
func NewCompatSessionLogger(cfg CompatSessionLoggerConfig) (*CompatSessionLogger, error)
DELETE IN: 2.6.0 CompatSessionLogger is used only during upgrades from 2.4.0 to 2.5.0 Should be deleted in 2.6.0 releases NewCompatSessionLogger creates new disk based session logger
func (*CompatSessionLogger) Close ¶
func (sl *CompatSessionLogger) Close() error
Close is called when clients close on the requested "session writer". We ignore their requests because this writer (file) should be closed only when the session logger is closed
func (*CompatSessionLogger) Finalize ¶
func (sl *CompatSessionLogger) Finalize() error
Finalize is called by the session when it's closing. This is where we're releasing audit resources associated with the session
func (*CompatSessionLogger) LogEvent ¶
func (sl *CompatSessionLogger) LogEvent(fields EventFields) error
LogEvent logs an event associated with this session
func (*CompatSessionLogger) PostSessionSlice ¶
func (sl *CompatSessionLogger) PostSessionSlice(slice SessionSlice) error
PostSessionSlice takes series of events associated with the session and writes them to events files and data file for future replays
type CompatSessionLoggerConfig ¶
type CompatSessionLoggerConfig struct { // SessionID is the session id of the logger SessionID session.ID // DataDir is data directory for session events files DataDir string // Clock is the clock replacement Clock clockwork.Clock // RecordSessions controls if sessions are recorded along with audit events. RecordSessions bool }
DELETE IN: 2.6.0 CompatSessionLogger is used only during upgrades from 2.4.0 to 2.5.0 Should be deleted in 2.6.0 releases CompatSessionLoggerConfig sets up parameters for disk session logger associated with the session ID
type DiscardAuditLog ¶ added in v1.1.0
type DiscardAuditLog struct{}
DiscardAuditLog is do-nothing, discard-everything implementation of IAuditLog interface used for cases when audit is turned off
func NewDiscardAuditLog ¶
func NewDiscardAuditLog() *DiscardAuditLog
NewDiscardAuditLog returns a no-op audit log instance
func (*DiscardAuditLog) Close ¶
func (d *DiscardAuditLog) Close() error
func (*DiscardAuditLog) EmitAuditEvent ¶ added in v1.1.0
func (d *DiscardAuditLog) EmitAuditEvent(eventType string, fields EventFields) error
func (*DiscardAuditLog) GetSessionChunk ¶ added in v1.1.0
func (*DiscardAuditLog) GetSessionEvents ¶ added in v1.1.0
func (d *DiscardAuditLog) GetSessionEvents(namespace string, sid session.ID, after int, includePrintEvents bool) ([]EventFields, error)
func (*DiscardAuditLog) PostSessionChunk ¶ added in v1.1.0
func (*DiscardAuditLog) PostSessionSlice ¶
func (d *DiscardAuditLog) PostSessionSlice(SessionSlice) error
func (*DiscardAuditLog) SearchEvents ¶ added in v1.1.0
func (d *DiscardAuditLog) SearchEvents(fromUTC, toUTC time.Time, query string, limit int) ([]EventFields, error)
func (*DiscardAuditLog) SearchSessionEvents ¶
func (d *DiscardAuditLog) SearchSessionEvents(fromUTC time.Time, toUTC time.Time, limit int) ([]EventFields, error)
func (*DiscardAuditLog) WaitForDelivery ¶
func (d *DiscardAuditLog) WaitForDelivery(context.Context) error
type DiskSessionLogger ¶
type DiskSessionLogger struct { DiskSessionLoggerConfig *log.Entry sync.Mutex // contains filtered or unexported fields }
DiskSessionLogger implements a disk based session logger. The imporant property of the disk based logger is that it never fails and can be used as a fallback implementation behind more sophisticated loggers.
func NewDiskSessionLogger ¶
func NewDiskSessionLogger(cfg DiskSessionLoggerConfig) (*DiskSessionLogger, error)
NewDiskSessionLogger creates new disk based session logger
func (*DiskSessionLogger) Close ¶
func (sl *DiskSessionLogger) Close() error
Close is called when clients close on the requested "session writer". We ignore their requests because this writer (file) should be closed only when the session logger is closed
func (*DiskSessionLogger) Finalize ¶
func (sl *DiskSessionLogger) Finalize() error
Finalize is called by the session when it's closing. This is where we're releasing audit resources associated with the session
func (*DiskSessionLogger) LogEvent ¶
func (sl *DiskSessionLogger) LogEvent(fields EventFields) error
LogEvent logs an event associated with this session
func (*DiskSessionLogger) PostSessionSlice ¶
func (sl *DiskSessionLogger) PostSessionSlice(slice SessionSlice) error
PostSessionSlice takes series of events associated with the session and writes them to events files and data file for future replays
type DiskSessionLoggerConfig ¶
type DiskSessionLoggerConfig struct { // SessionID is the session id of the logger SessionID session.ID // DataDir is data directory for session events files DataDir string // Clock is the clock replacement Clock clockwork.Clock // RecordSessions controls if sessions are recorded along with audit events. RecordSessions bool // Namespace is logger namespace Namespace string // ServerID is a server ID ServerID string }
DiskSessionLoggerConfig sets up parameters for disk session logger associated with the session ID
func (*DiskSessionLoggerConfig) CheckAndSetDefaults ¶
func (cfg *DiskSessionLoggerConfig) CheckAndSetDefaults() error
type EventFields ¶ added in v1.0.0
type EventFields map[string]interface{}
EventFields instance is attached to every logged event
func EventFromChunk ¶
func EventFromChunk(sessionID string, chunk *SessionChunk) (EventFields, error)
EventFromChunk retuns event converted from session chunk
func (EventFields) AsString ¶ added in v1.0.0
func (f EventFields) AsString() string
String returns a string representation of an event structure
func (EventFields) GetInt ¶ added in v1.0.0
func (f EventFields) GetInt(key string) int
GetString returns an int representation of a logged field
func (EventFields) GetString ¶ added in v1.0.0
func (f EventFields) GetString(key string) string
GetString returns a string representation of a logged field
func (EventFields) GetTime ¶ added in v1.0.0
func (f EventFields) GetTime(key string) time.Time
GetString returns an int representation of a logged field
func (EventFields) GetType ¶ added in v1.0.0
func (f EventFields) GetType() string
GetType returns the type (string) of the event
type Forwarder ¶
type Forwarder struct { ForwarderConfig // contains filtered or unexported fields }
ForwarderConfig forwards session log events to the auth server, and writes the session playback to disk
func NewForwarder ¶
func NewForwarder(cfg ForwarderConfig) (*Forwarder, error)
NewForwarder returns a new instance of session forwarder
func (*Forwarder) EmitAuditEvent ¶
func (l *Forwarder) EmitAuditEvent(eventType string, fields EventFields) error
EmitAuditEvent emits audit event
func (*Forwarder) GetSessionChunk ¶
func (l *Forwarder) GetSessionChunk(namespace string, sid session.ID, offsetBytes, maxBytes int) ([]byte, error)
GetSessionChunk returns a reader which can be used to read a byte stream of a recorded session starting from 'offsetBytes' (pass 0 to start from the beginning) up to maxBytes bytes.
If maxBytes > MaxChunkBytes, it gets rounded down to MaxChunkBytes
func (*Forwarder) GetSessionEvents ¶
func (l *Forwarder) GetSessionEvents(namespace string, sid session.ID, after int, includePrintEvents bool) ([]EventFields, error)
Returns all events that happen during a session sorted by time (oldest first).
after tells to use only return events after a specified cursor Id
This function is usually used in conjunction with GetSessionReader to replay recorded session streams.
func (*Forwarder) PostSessionChunk ¶
PostSessionChunk returns a writer which SSH nodes use to submit their live sessions into the session log
func (*Forwarder) PostSessionSlice ¶
func (l *Forwarder) PostSessionSlice(slice SessionSlice) error
PostSessionSlice sends chunks of recorded session to the event log
func (*Forwarder) SearchEvents ¶
func (l *Forwarder) SearchEvents(fromUTC, toUTC time.Time, query string, limit int) ([]EventFields, error)
SearchEvents is a flexible way to find The format of a query string depends on the implementing backend. A recommended format is urlencoded (good enough for Lucene/Solr)
Pagination is also defined via backend-specific query format.
The only mandatory requirement is a date range (UTC). Results must always show up sorted by date (newest first)
func (*Forwarder) SearchSessionEvents ¶
func (l *Forwarder) SearchSessionEvents(fromUTC time.Time, toUTC time.Time, limit int) ([]EventFields, error)
SearchSessionEvents returns session related events only. This is used to find completed session.
type ForwarderConfig ¶
type ForwarderConfig struct { // SessionID is a session id to write SessionID session.ID // ServerID is a serverID data directory ServerID string // DataDir is a data directory DataDir string // RecordSessions is a sessions recording setting RecordSessions bool // Namespace is a namespace of the session Namespace string // ForwardTo is the audit log to forward non-print events to ForwardTo IAuditLog }
ForwarderConfig forwards session log events to the auth server, and writes the session playback to disk
func (*ForwarderConfig) CheckAndSetDefaults ¶
func (s *ForwarderConfig) CheckAndSetDefaults() error
CheckAndSetDefaults checks and sets default values
type IAuditLog ¶ added in v1.0.0
type IAuditLog interface { // Closer releases connection and resources associated with log if any io.Closer // EmitAuditEvent emits audit event EmitAuditEvent(eventType string, fields EventFields) error // PostSessionSlice sends chunks of recorded session to the event log PostSessionSlice(SessionSlice) error // PostSessionChunk returns a writer which SSH nodes use to submit // their live sessions into the session log PostSessionChunk(namespace string, sid session.ID, reader io.Reader) error // GetSessionChunk returns a reader which can be used to read a byte stream // of a recorded session starting from 'offsetBytes' (pass 0 to start from the // beginning) up to maxBytes bytes. // // If maxBytes > MaxChunkBytes, it gets rounded down to MaxChunkBytes GetSessionChunk(namespace string, sid session.ID, offsetBytes, maxBytes int) ([]byte, error) // Returns all events that happen during a session sorted by time // (oldest first). // // after tells to use only return events after a specified cursor Id // // This function is usually used in conjunction with GetSessionReader to // replay recorded session streams. GetSessionEvents(namespace string, sid session.ID, after int, includePrintEvents bool) ([]EventFields, error) // SearchEvents is a flexible way to find events. The format of a query string // depends on the implementing backend. A recommended format is urlencoded // (good enough for Lucene/Solr) // // Pagination is also defined via backend-specific query format. // // The only mandatory requirement is a date range (UTC). Results must always // show up sorted by date (newest first) SearchEvents(fromUTC, toUTC time.Time, query string, limit int) ([]EventFields, error) // SearchSessionEvents returns session related events only. This is used to // find completed session. SearchSessionEvents(fromUTC time.Time, toUTC time.Time, limit int) ([]EventFields, error) // WaitForDelivery waits for resources to be released and outstanding requests to // complete after calling Close method WaitForDelivery(context.Context) error }
IAuditLog is the primary (and the only external-facing) interface for AuditLogger. If you wish to implement a different kind of logger (not filesystem-based), you have to implement this interface
type MockAuditLog ¶
type MockAuditLog struct { sync.Mutex FailedAttemptsC chan *SessionSlice SlicesC chan *SessionSlice // contains filtered or unexported fields }
MockAuditLog is audit log used for tests
func NewMockAuditLog ¶
func NewMockAuditLog(capacity int) *MockAuditLog
func (*MockAuditLog) Close ¶
func (d *MockAuditLog) Close() error
func (*MockAuditLog) EmitAuditEvent ¶
func (d *MockAuditLog) EmitAuditEvent(eventType string, fields EventFields) error
func (*MockAuditLog) GetError ¶
func (d *MockAuditLog) GetError() error
func (*MockAuditLog) GetSessionChunk ¶
func (*MockAuditLog) GetSessionEvents ¶
func (d *MockAuditLog) GetSessionEvents(namespace string, sid session.ID, after int, fetchPrintEvents bool) ([]EventFields, error)
func (*MockAuditLog) PostSessionChunk ¶
func (*MockAuditLog) PostSessionSlice ¶
func (d *MockAuditLog) PostSessionSlice(slice SessionSlice) error
func (*MockAuditLog) SearchEvents ¶
func (d *MockAuditLog) SearchEvents(fromUTC, toUTC time.Time, query string, limit int) ([]EventFields, error)
func (*MockAuditLog) SearchSessionEvents ¶
func (d *MockAuditLog) SearchSessionEvents(fromUTC, toUTC time.Time, limit int) ([]EventFields, error)
func (*MockAuditLog) SetError ¶
func (d *MockAuditLog) SetError(e error)
func (*MockAuditLog) WaitForDelivery ¶
func (d *MockAuditLog) WaitForDelivery(context.Context) error
type SessionChunk ¶
type SessionChunk struct { // Time is the occurence of this event Time int64 `protobuf:"varint,2,opt,name=Time,json=time,proto3" json:"Time,omitempty"` // Data is captured data, contains event fields in case of event, session data otherwise Data []byte `protobuf:"bytes,3,opt,name=Data,json=data,proto3" json:"Data,omitempty"` // EventType is event type EventType string `protobuf:"bytes,4,opt,name=EventType,json=eventType,proto3" json:"EventType,omitempty"` // EventIndex is the event global index EventIndex int64 `protobuf:"varint,5,opt,name=EventIndex,json=eventIndex,proto3" json:"EventIndex,omitempty"` // Index is the autoincremented chunk index ChunkIndex int64 `protobuf:"varint,6,opt,name=ChunkIndex,json=chunkIndex,proto3" json:"ChunkIndex,omitempty"` // Offset is an offset from the previous chunk in bytes Offset int64 `protobuf:"varint,7,opt,name=Offset,json=offset,proto3" json:"Offset,omitempty"` // Delay is a delay from the previous event in milliseconds Delay int64 `protobuf:"varint,8,opt,name=Delay,json=delay,proto3" json:"Delay,omitempty"` }
SessionChunk is a chunk to be posted in the context of the session
func (*SessionChunk) Descriptor ¶
func (*SessionChunk) Descriptor() ([]byte, []int)
func (*SessionChunk) Marshal ¶
func (m *SessionChunk) Marshal() (data []byte, err error)
func (*SessionChunk) ProtoMessage ¶
func (*SessionChunk) ProtoMessage()
func (*SessionChunk) Reset ¶
func (m *SessionChunk) Reset()
func (*SessionChunk) Size ¶
func (m *SessionChunk) Size() (n int)
func (*SessionChunk) String ¶
func (m *SessionChunk) String() string
func (*SessionChunk) Unmarshal ¶
func (m *SessionChunk) Unmarshal(data []byte) error
type SessionLogger ¶ added in v1.0.0
type SessionLogger interface { // LogEvent logs events associated with this session. LogEvent(fields EventFields) error // Close is called when clients close on the requested "session writer". // We ignore their requests because this writer (file) should be closed only // when the session logger is closed. Close() error // Finalize is called by the session when it's closing. This is where we're // releasing audit resources associated with the session Finalize() error // PostSessionSlice posts session slice PostSessionSlice(slice SessionSlice) error }
sessionLogger is an interface that all session loggers must implement.
type SessionSlice ¶
type SessionSlice struct { // Namespace is a session namespace Namespace string `protobuf:"bytes,1,opt,name=Namespace,json=namespace,proto3" json:"Namespace,omitempty"` // SessionID is a session ID associated with this chunk SessionID string `protobuf:"bytes,2,opt,name=SessionID,json=sessionID,proto3" json:"SessionID,omitempty"` // Chunks is a list of submitted session chunks Chunks []*SessionChunk `protobuf:"bytes,3,rep,name=Chunks,json=chunks" json:"Chunks,omitempty"` // Version specifies session slice version Version int64 `protobuf:"varint,4,opt,name=Version,json=version,proto3" json:"Version,omitempty"` }
SessionSlice is a slice of submitted chunks
func (*SessionSlice) Descriptor ¶
func (*SessionSlice) Descriptor() ([]byte, []int)
func (*SessionSlice) GetChunks ¶
func (m *SessionSlice) GetChunks() []*SessionChunk
func (*SessionSlice) Marshal ¶
func (m *SessionSlice) Marshal() (data []byte, err error)
func (*SessionSlice) ProtoMessage ¶
func (*SessionSlice) ProtoMessage()
func (*SessionSlice) Reset ¶
func (m *SessionSlice) Reset()
func (*SessionSlice) Size ¶
func (m *SessionSlice) Size() (n int)
func (*SessionSlice) String ¶
func (m *SessionSlice) String() string
func (*SessionSlice) Unmarshal ¶
func (m *SessionSlice) Unmarshal(data []byte) error
type UploadEvent ¶
type UploadEvent struct { // SessionID is a session ID SessionID string // URL is the upload URL URL string // Error is set in case if event resulted in error Error error }
UploadEvent is emitted by uploader and is used in tests
type UploadHandler ¶
type UploadHandler interface { // Upload uploads session tarball and returns URL with uploaded file // in case of success. Upload(ctx context.Context, sessionID session.ID, readCloser io.Reader) (string, error) // Download downloads session tarball and writes it to writer Download(ctx context.Context, sessionID session.ID, writer io.WriterAt) error }
UploadHandler is a function supplied by the user, it will upload the file
type Uploader ¶
type Uploader struct { UploaderConfig *log.Entry // contains filtered or unexported fields }
Uploader implements a disk based session logger. The imporant property of the disk based logger is that it never fails and can be used as a fallback implementation behind more sophisticated loggers.
func NewUploader ¶
func NewUploader(cfg UploaderConfig) (*Uploader, error)
NewUploader creates new disk based session logger
type UploaderConfig ¶
type UploaderConfig struct { // DataDir is data directory for session events files DataDir string // Clock is the clock replacement Clock clockwork.Clock // Namespace is logger namespace Namespace string // ServerID is a server ID ServerID string // Context is an optional context Context context.Context // ScanPeriod is a uploader dir scan period ScanPeriod time.Duration // ConcurrentUploads sets up how many parallel uploads to schedule ConcurrentUploads int // Handler is upload handler supplied by user Handler UploadHandler // AuditLog is audit log client AuditLog IAuditLog // EventsC is an event channel used to signal events // used in tests EventsC chan *UploadEvent }
UploaderConfig sets up configuration for uploader service
func (*UploaderConfig) CheckAndSetDefaults ¶
func (cfg *UploaderConfig) CheckAndSetDefaults() error
CheckAndSetDefaults checks and sets default values of UploaderConfig