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 occurred * "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 delivers 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) 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) UploadSessionRecording(r SessionRecording) error
- func (l *AuditLog) WaitForDelivery(context.Context) error
- type AuditLogClient
- type AuditLogConfig
- type AuditLogEvent
- type AuditLogServer
- type AuditLog_SubmitSessionSliceClient
- type AuditLog_SubmitSessionSliceServer
- type ByTimeAndIndex
- 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) 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) UploadSessionRecording(SessionRecording) error
- func (d *DiscardAuditLog) WaitForDelivery(context.Context) error
- type DiscardRecorder
- type DiskSessionLogger
- type DiskSessionLoggerConfig
- type EventFields
- type FileLog
- func (l *FileLog) Close() error
- func (l *FileLog) EmitAuditEvent(eventType string, fields EventFields) error
- func (l *FileLog) GetSessionChunk(namespace string, sid session.ID, offsetBytes, maxBytes int) ([]byte, error)
- func (l *FileLog) GetSessionEvents(namespace string, sid session.ID, after int, fetchPrintEvents bool) ([]EventFields, error)
- func (l *FileLog) PostSessionSlice(slice SessionSlice) error
- func (l *FileLog) SearchEvents(fromUTC, toUTC time.Time, query string, limit int) ([]EventFields, error)
- func (l *FileLog) SearchSessionEvents(fromUTC, toUTC time.Time, limit int) ([]EventFields, error)
- func (l *FileLog) UploadSessionRecording(SessionRecording) error
- func (l *FileLog) WaitForDelivery(context.Context) error
- type FileLogConfig
- type ForwardRecorder
- type ForwardRecorderConfig
- 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) 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) UploadSessionRecording(r SessionRecording) 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) 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) UploadSessionRecording(SessionRecording) error
- func (d *MockAuditLog) WaitForDelivery(context.Context) error
- type MultiLog
- func (m *MultiLog) Close() error
- func (m *MultiLog) EmitAuditEvent(eventType string, fields EventFields) error
- func (m *MultiLog) GetSessionChunk(namespace string, sid session.ID, offsetBytes, maxBytes int) (data []byte, err error)
- func (m *MultiLog) GetSessionEvents(namespace string, sid session.ID, after int, fetchPrintEvents bool) (events []EventFields, err error)
- func (m *MultiLog) PostSessionSlice(slice SessionSlice) error
- func (m *MultiLog) SearchEvents(fromUTC, toUTC time.Time, query string, limit int) (events []EventFields, err error)
- func (m *MultiLog) SearchSessionEvents(fromUTC, toUTC time.Time, limit int) (events []EventFields, err error)
- func (m *MultiLog) UploadSessionRecording(rec SessionRecording) error
- func (m *MultiLog) WaitForDelivery(ctx 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 SessionRecorder
- type SessionRecording
- 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 ( // EventType is event type/kind EventType = "event" // EventTime is event time EventTime = "time" // EventLogin is OS login EventLogin = "login" // EventUser is teleport user name EventUser = "user" // EventProtocol specifies protocol that was captured EventProtocol = "proto" // EventProtocolsSSH specifies SSH as a type of captured protocol EventProtocolSSH = "ssh" // EventProtocolKube specifies kubernetes as a type of captured protocol EventProtocolKube = "kube" // LocalAddr is a target address on the host LocalAddr = "addr.local" // RemoteAddr is a client (user's) address RemoteAddr = "addr.remote" // EventCursor is an event ID (used as cursor value for enumeration, not stored) EventCursor = "id" // 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" // ClientDisconnectEvent is emitted when client is disconnected // by the server due to inactivity or any other reason ClientDisconnectEvent = "client.disconnect" // Reason is a field that specifies reason for event, e.g. in disconnect // event it explains why server disconnected the client Reason = "reason" // 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" AuthAttemptMessage = "message" // SCPEvent means data transfer that occurred on the server SCPEvent = "scp" SCPPath = "path" SCPLengh = "len" SCPAction = "action" SCPUpload = "upload" SCPDownload = "download" // 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 // V3 is almost like V2, but it assumes // that session recordings are being uploaded // at the end of the session, so it skips writing session event index // on the fly V3 = 3 )
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 ¶
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 ¶
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 ¶
Closes the audit log, which inluces closing all file handles and releasing all session loggers
func (*AuditLog) EmitAuditEvent ¶
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 ¶
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 ¶
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) PostSessionSlice ¶
func (l *AuditLog) PostSessionSlice(slice SessionSlice) error
PostSessionSlice submits slice of session chunks to the audit log server.
func (*AuditLog) SearchEvents ¶
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.
func (*AuditLog) UploadSessionRecording ¶
func (l *AuditLog) UploadSessionRecording(r SessionRecording) error
UploadSessionRecording uploads session recording to the audit server TODO(klizhentas) add protection against overwrites from different nodes
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 // EventC is evnets channel for testing purposes, not used if empty EventsC chan *AuditLogEvent }
AuditLogConfig specifies configuration for AuditLog server
func (*AuditLogConfig) CheckAndSetDefaults ¶
func (a *AuditLogConfig) CheckAndSetDefaults() error
CheckAndSetDefaults checks and sets defaults
type AuditLogEvent ¶
type AuditLogEvent struct { // Type is an event type Type string // Error is an event error Error error }
AuditLogEvent is an internal audit log event
type AuditLogServer ¶
type AuditLogServer interface {
SubmitSessionSlice(AuditLog_SubmitSessionSliceServer) error
}
type AuditLog_SubmitSessionSliceClient ¶
type AuditLog_SubmitSessionSliceClient interface { Send(*SessionSlice) error CloseAndRecv() (*google_protobuf.Empty, error) grpc.ClientStream }
type AuditLog_SubmitSessionSliceServer ¶
type AuditLog_SubmitSessionSliceServer interface { SendAndClose(*google_protobuf.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 DiscardAuditLog ¶
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 ¶
func (d *DiscardAuditLog) EmitAuditEvent(eventType string, fields EventFields) error
func (*DiscardAuditLog) GetSessionChunk ¶
func (*DiscardAuditLog) GetSessionEvents ¶
func (d *DiscardAuditLog) GetSessionEvents(namespace string, sid session.ID, after int, includePrintEvents bool) ([]EventFields, error)
func (*DiscardAuditLog) PostSessionSlice ¶
func (d *DiscardAuditLog) PostSessionSlice(SessionSlice) error
func (*DiscardAuditLog) SearchEvents ¶
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) UploadSessionRecording ¶
func (d *DiscardAuditLog) UploadSessionRecording(SessionRecording) error
func (*DiscardAuditLog) WaitForDelivery ¶
func (d *DiscardAuditLog) WaitForDelivery(context.Context) error
type DiscardRecorder ¶
type DiscardRecorder struct {
DiscardAuditLog
}
DiscardRecorder discards all writes
func (*DiscardRecorder) Close ¶
func (*DiscardRecorder) Close() error
Close does nothing and always succeeds
func (*DiscardRecorder) GetAuditLog ¶
func (d *DiscardRecorder) GetAuditLog() IAuditLog
GetAuditLog returns audit log associated with this recorder
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 ¶
type EventFields map[string]interface{}
EventFields instance is attached to every logged event
func EventFromChunk ¶
func EventFromChunk(sessionID string, chunk *SessionChunk) (EventFields, error)
EventFromChunk returns event converted from session chunk
func (EventFields) AsString ¶
func (f EventFields) AsString() string
String returns a string representation of an event structure
func (EventFields) GetInt ¶
func (f EventFields) GetInt(key string) int
GetString returns an int representation of a logged field
func (EventFields) GetString ¶
func (f EventFields) GetString(key string) string
GetString returns a string representation of a logged field
func (EventFields) GetTime ¶
func (f EventFields) GetTime(key string) time.Time
GetString returns an int representation of a logged field
func (EventFields) GetType ¶
func (f EventFields) GetType() string
GetType returns the type (string) of the event
type FileLog ¶
type FileLog struct { *log.Entry FileLogConfig sync.Mutex // contains filtered or unexported fields }
FileLog is a file local audit events log, logs all events to the local file in json encoded form
func NewFileLog ¶
func NewFileLog(cfg FileLogConfig) (*FileLog, error)
NewFileLog returns a new instance of a file log
func (*FileLog) Close ¶
Close closes the audit log, which inluces closing all file handles and releasing all session loggers
func (*FileLog) EmitAuditEvent ¶
func (l *FileLog) EmitAuditEvent(eventType string, fields EventFields) error
EmitAuditEvent adds a new event to the log. Part of auth.IFileLog interface.
func (*FileLog) GetSessionChunk ¶
func (*FileLog) GetSessionEvents ¶
func (*FileLog) PostSessionSlice ¶
func (l *FileLog) PostSessionSlice(slice SessionSlice) error
func (*FileLog) SearchEvents ¶
func (l *FileLog) 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 (*FileLog) SearchSessionEvents ¶
SearchSessionEvents searches for session related events. Used to find completed sessions.
func (*FileLog) UploadSessionRecording ¶
func (l *FileLog) UploadSessionRecording(SessionRecording) error
type FileLogConfig ¶
type FileLogConfig struct { // RotationPeriod defines how frequently to rotate the log file RotationPeriod time.Duration // Dir is a directory where logger puts the files Dir string // Clock is a clock interface, used in tests Clock clockwork.Clock // SearchDirs is a function that returns // search directories, if not set, only Dir is used SearchDirs func() ([]string, error) }
FileLogConfig is a configuration for file log
func (*FileLogConfig) CheckAndSetDefaults ¶
func (cfg *FileLogConfig) CheckAndSetDefaults() error
CheckAndSetDefaults checks and sets config defaults
type ForwardRecorder ¶
type ForwardRecorder struct { // ForwardRecorderConfig specifies session recorder configuration ForwardRecorderConfig // Entry holds the structured logger *logrus.Entry // AuditLog is the audit log to store session chunks AuditLog IAuditLog }
ForwardRecorder implements io.Writer to be plugged into the multi-writer associated with every session. It forwards session stream to the audit log
func NewForwardRecorder ¶
func NewForwardRecorder(cfg ForwardRecorderConfig) (*ForwardRecorder, error)
NewForwardRecorder returns a new instance of session recorder
func (*ForwardRecorder) Close ¶
func (r *ForwardRecorder) Close() error
Close closes audit log session recorder
func (*ForwardRecorder) GetAuditLog ¶
func (r *ForwardRecorder) GetAuditLog() IAuditLog
GetAuditLog returns audit log associated with this recorder
type ForwardRecorderConfig ¶
type ForwardRecorderConfig struct { // DataDir is a data directory to record DataDir string // SessionID defines the session to record. SessionID session.ID // Namespace is the session namespace. Namespace string // RecordSessions stores info on whether to record sessions RecordSessions bool // Component is a component used for logging Component string // ForwardTo is external audit log where events will be forwarded ForwardTo IAuditLog }
ForwardRecorderConfig specifies config for session recording
func (*ForwardRecorderConfig) CheckAndSetDefaults ¶
func (cfg *ForwardRecorderConfig) CheckAndSetDefaults() error
type Forwarder ¶
type Forwarder struct { ForwarderConfig sync.Mutex // 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) 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.
func (*Forwarder) UploadSessionRecording ¶
func (l *Forwarder) UploadSessionRecording(r SessionRecording) error
UploadSessionRecording uploads session recording to the audit server
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 // Clock is a clock to set for tests Clock clockwork.Clock }
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 ¶
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 // DELETE IN: 2.7.0 // This method is no longer necessary as nodes and proxies >= 2.7.0 // use UploadSessionRecording method. // PostSessionSlice sends chunks of recorded session to the event log PostSessionSlice(SessionSlice) error // UploadSessionRecording uploads session recording to the audit server UploadSessionRecording(r SessionRecording) 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) 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) UploadSessionRecording ¶
func (d *MockAuditLog) UploadSessionRecording(SessionRecording) error
func (*MockAuditLog) WaitForDelivery ¶
func (d *MockAuditLog) WaitForDelivery(context.Context) error
type MultiLog ¶
type MultiLog struct {
// contains filtered or unexported fields
}
MultiLog is a logger that fan outs write operations to all loggers, and performs all read and search operations on the first logger that implements the operation
func NewMultiLog ¶
NewMultiLog returns a new instance of a multi logger
func (*MultiLog) EmitAuditEvent ¶
func (m *MultiLog) EmitAuditEvent(eventType string, fields EventFields) error
EmitAuditEvent emits audit event
func (*MultiLog) GetSessionChunk ¶
func (m *MultiLog) GetSessionChunk(namespace string, sid session.ID, offsetBytes, maxBytes int) (data []byte, err 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 (*MultiLog) GetSessionEvents ¶
func (m *MultiLog) GetSessionEvents(namespace string, sid session.ID, after int, fetchPrintEvents bool) (events []EventFields, err 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 (*MultiLog) PostSessionSlice ¶
func (m *MultiLog) PostSessionSlice(slice SessionSlice) error
DELETE IN: 2.7.0 This method is no longer necessary as nodes and proxies >= 2.7.0 use UploadSessionRecording method. PostSessionSlice sends chunks of recorded session to the event log
func (*MultiLog) SearchEvents ¶
func (m *MultiLog) SearchEvents(fromUTC, toUTC time.Time, query string, limit int) (events []EventFields, err 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)
func (*MultiLog) SearchSessionEvents ¶
func (m *MultiLog) SearchSessionEvents(fromUTC, toUTC time.Time, limit int) (events []EventFields, err error)
SearchSessionEvents returns session related events only. This is used to find completed session.
func (*MultiLog) UploadSessionRecording ¶
func (m *MultiLog) UploadSessionRecording(rec SessionRecording) error
UploadSessionRecording uploads session recording to the audit server
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 ¶
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 SessionRecorder ¶
type SessionRecorder interface { io.Writer io.Closer // GetAuditLog returns audit log associated with this log GetAuditLog() IAuditLog }
SessionRecorder implements io.Writer to be plugged into the multi-writer associated with every session. It forwards session stream to the audit log
type SessionRecording ¶
type SessionRecording struct { // Namespace is a session namespace Namespace string // SessionID is a session ID SessionID session.ID // Recording is a packaged tarball recording Recording io.Reader }
SessionRecording is a recording of a live session
func (*SessionRecording) CheckAndSetDefaults ¶
func (l *SessionRecording) CheckAndSetDefaults() error
CheckAndSetDefaults checks and sets default parameters
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 // 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 // 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