Documentation ¶
Overview ¶
Package events currently implements the audit log using a simple filesystem backend. "Implements" means it implements events.IAuditLog interface (see events/api.go)
The main log files are saved as:
/var/lib/teleport/log/<date>.log
Each session has its own session log stored as two files
/var/lib/teleport/log/<session-id>.session.log /var/lib/teleport/log/<session-id>.session.bytes
Where:
- .session.log (same events as in the main log, but related to the session)
- .session.bytes (recorded session bytes: PTY IO)
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"}
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 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) ([]EventFields, error)
- func (l *AuditLog) LoggerFor(namespace string, sid session.ID) (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) ([]EventFields, error)
- func (l *AuditLog) SearchSessionEvents(fromUTC, toUTC time.Time) ([]EventFields, error)
- func (l *AuditLog) WaitForDelivery(context.Context) error
- type AuditLogClient
- type AuditLogConfig
- type AuditLogServer
- type AuditLog_SubmitSessionSliceClient
- type AuditLog_SubmitSessionSliceServer
- 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) ([]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) ([]EventFields, error)
- func (d *DiscardAuditLog) SearchSessionEvents(fromUTC time.Time, toUTC time.Time) ([]EventFields, error)
- func (d *DiscardAuditLog) WaitForDelivery(context.Context) error
- type DiskSessionLogger
- type DiskSessionLoggerConfig
- type EventFields
- 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) ([]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) ([]EventFields, error)
- func (d *MockAuditLog) SearchSessionEvents(fromUTC, toUTC time.Time) ([]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
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) // 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" 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 ( // 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" // LogfileExt defines the ending of the daily event log file LogfileExt = ".log" // SessionLogPrefix defines the endof of session log files SessionLogPrefix = ".session.log" // SessionStreamPrefix defines the ending of session stream files, // that's where interactive PTY I/O is saved. SessionStreamPrefix = ".session.bytes" )
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 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) ([]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
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
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
SearchEvents finds events. Results show up sorted by date (newest first)
func (*AuditLog) SearchSessionEvents ¶
func (l *AuditLog) SearchSessionEvents(fromUTC, toUTC time.Time) ([]EventFields, error)
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 // 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 }
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 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) ([]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) ([]EventFields, error)
func (*DiscardAuditLog) SearchSessionEvents ¶
func (d *DiscardAuditLog) SearchSessionEvents(fromUTC time.Time, toUTC time.Time) ([]EventFields, error)
func (*DiscardAuditLog) WaitForDelivery ¶
func (d *DiscardAuditLog) WaitForDelivery(context.Context) error
type DiskSessionLogger ¶
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)
LogEvent logs an event associated with this session
func (*DiskSessionLogger) WriteChunk ¶
func (sl *DiskSessionLogger) WriteChunk(chunk *SessionChunk) (written int, err error)
WriteChunk takes a stream of bytes (usually the output from a session terminal) and writes it into a "stream file", for future replay of interactive sessions.
type DiskSessionLoggerConfig ¶
type DiskSessionLoggerConfig struct { // SessionID is the session id of the logger SessionID session.ID // EventsFileName is the events file name EventsFileName string // StreamFileName is the byte stream file name StreamFileName string // Clock is the clock replacement Clock clockwork.Clock // RecordSessions controls if sessions are recorded along with audit events. RecordSessions bool }
DiskSessionLoggerConfig sets up parameters for disk session logger associated with the session ID
type EventFields ¶ added in v1.0.0
type EventFields map[string]interface{}
EventFields instance is attached to every logged event
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 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) ([]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) ([]EventFields, error) // SearchSessionEvents returns session related events only. This is used to // find completed session. SearchSessionEvents(fromUTC time.Time, toUTC time.Time) ([]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) ([]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) ([]EventFields, error)
func (*MockAuditLog) SearchSessionEvents ¶
func (d *MockAuditLog) SearchSessionEvents(fromUTC, toUTC time.Time) ([]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 occurrence of this event Time int64 `protobuf:"varint,2,opt,name=Time,json=time,proto3" json:"Time,omitempty"` // Data is captured data Data []byte `protobuf:"bytes,3,opt,name=Data,json=data,proto3" json:"Data,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) // 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 // WriteChunk takes a stream of bytes (usually the output from a session // terminal) and writes it into a "stream file", for future replay of // interactive sessions. WriteChunk(chunk *SessionChunk) (written int, err error) }
SessionLogger is an interface that all session loggers must implement.
type SessionSlice ¶
type SessionSlice struct { Namespace string `protobuf:"bytes,1,opt,name=Namespace,json=namespace,proto3" json:"Namespace,omitempty"` SessionID string `protobuf:"bytes,2,opt,name=SessionID,json=sessionID,proto3" json:"SessionID,omitempty"` Chunks []*SessionChunk `protobuf:"bytes,3,rep,name=Chunks,json=chunks" json:"Chunks,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