diff --git a/web/packages/teleport/src/services/audit/makeEvent.ts b/web/packages/teleport/src/services/audit/makeEvent.ts index 97675560e94af..aee7193e8aab1 100644 --- a/web/packages/teleport/src/services/audit/makeEvent.ts +++ b/web/packages/teleport/src/services/audit/makeEvent.ts @@ -20,7 +20,7 @@ import { formatDistanceStrict } from 'date-fns'; import { pluralize } from 'shared/utils/text'; -import { Event, eventCodes, Formatters, RawEvent, RawEvents } from './types'; +import { Event, eventCodes, Formatters, RawEvent, RawEvents, EventCode } from './types'; const formatElasticsearchEvent: ( json: @@ -65,6 +65,52 @@ const formatElasticsearchEvent: ( return message; }; +const portForwardEventTypes = ['port', 'port.local', 'port.remote', 'port.remote_conn'] as const; +type PortForwardEventType = typeof portForwardEventTypes[number]; +type PortForwardEvent = RawEvents[typeof eventCodes.PORTFORWARD] | RawEvents[typeof eventCodes.PORTFORWARD_STOP] | RawEvents[typeof eventCodes.PORTFORWARD_FAILURE]; + +const getPortForwardEventName = (event: string): string => { + let ev = event as PortForwardEventType; + if (!portForwardEventTypes.includes(ev)) { + ev = 'port'; // default to generic 'port' if the event type is unknown + } + + switch (event) { + case 'port': + return 'Port Forwarding'; + case 'port.local': + return 'Local Port Forwarding' + case 'port.remote': + return 'Remote Port Forwarding'; + case 'port.remote_conn': + return 'Remote Port Forwarded Connection'; + } +} + +const formatPortForwardEvent = ({ user, code, event }: PortForwardEvent): string => { + const eventName = getPortForwardEventName(event).toLowerCase(); + + switch (code) { + case eventCodes.PORTFORWARD: + return `User [${user}] started ${eventName}`; + case eventCodes.PORTFORWARD_STOP: + return `User [${user}] stopped ${eventName}`; + case eventCodes.PORTFORWARD_FAILURE: + return `User [${user}] failed ${eventName}`; + } +} + +const getPortForwardDesc = ({ code, event }: PortForwardEvent) => { + switch (code) { + case eventCodes.PORTFORWARD: + return `${getPortForwardEventName(event)} Start`; + case eventCodes.PORTFORWARD_STOP: + return `${getPortForwardEventName(event)} Stop`; + case eventCodes.PORTFORWARD_FAILURE: + return `${getPortForwardEventName(event)} Failure`; + } +} + export const formatters: Formatters = { [eventCodes.ACCESS_REQUEST_CREATED]: { type: 'access_request.create', @@ -172,17 +218,15 @@ export const formatters: Formatters = { return `User [${user}] executed a command on Kubernetes cluster [${kubernetes_cluster}]`; } - return `User [${user}] executed a command on node ${ - event['server_hostname'] || event['addr.local'] - }`; + return `User [${user}] executed a command on node ${event['server_hostname'] || event['addr.local'] + }`; }, }, [eventCodes.EXEC_FAILURE]: { type: 'exec', desc: 'Command Execution Failed', format: ({ user, exitError, ...rest }) => - `User [${user}] command execution on node ${ - rest['server_hostname'] || rest['addr.local'] + `User [${user}] command execution on node ${rest['server_hostname'] || rest['addr.local'] } failed [${exitError}]`, }, [eventCodes.GITHUB_CONNECTOR_CREATED]: { @@ -223,19 +267,18 @@ export const formatters: Formatters = { }, [eventCodes.PORTFORWARD]: { type: 'port', - desc: 'Port Forwarding Started', - format: ({ user }) => `User [${user}] started port forwarding`, + desc: getPortForwardDesc, + format: formatPortForwardEvent, }, [eventCodes.PORTFORWARD_FAILURE]: { type: 'port', - desc: 'Port Forwarding Failed', - format: ({ user, error }) => - `User [${user}] port forwarding request failed: ${error}`, + desc: getPortForwardDesc, + format: formatPortForwardEvent, }, [eventCodes.PORTFORWARD_STOP]: { type: 'port', - desc: 'Port Forwarding Stopped', - format: ({ user }) => `User [${user}] stopped port forwarding`, + desc: getPortForwardDesc, + format: formatPortForwardEvent, }, [eventCodes.SAML_CONNECTOR_CREATED]: { type: 'saml.created', @@ -259,208 +302,182 @@ export const formatters: Formatters = { type: 'scp', desc: 'SCP Download', format: ({ user, path, ...rest }) => - `User [${user}] downloaded a file [${path}] from node [${ - rest['server_hostname'] || rest['addr.local'] + `User [${user}] downloaded a file [${path}] from node [${rest['server_hostname'] || rest['addr.local'] }]`, }, [eventCodes.SCP_DOWNLOAD_FAILURE]: { type: 'scp', desc: 'SCP Download Failed', format: ({ exitError, ...rest }) => - `File download from node [${ - rest['server_hostname'] || rest['addr.local'] + `File download from node [${rest['server_hostname'] || rest['addr.local'] }] failed [${exitError}]`, }, [eventCodes.SCP_UPLOAD]: { type: 'scp', desc: 'SCP Upload', format: ({ user, path, ...rest }) => - `User [${user}] uploaded a file to [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] + `User [${user}] uploaded a file to [${path}] on node [${rest['server_hostname'] || rest['addr.local'] }]`, }, [eventCodes.SCP_UPLOAD_FAILURE]: { type: 'scp', desc: 'SCP Upload Failed', format: ({ exitError, ...rest }) => - `File upload to node [${ - rest['server_hostname'] || rest['addr.local'] + `File upload to node [${rest['server_hostname'] || rest['addr.local'] }] failed [${exitError}]`, }, [eventCodes.SCP_DISALLOWED]: { type: 'scp', desc: 'SCP Disallowed', format: ({ user, ...rest }) => - `User [${user}] SCP file transfer on node [${ - rest['server_hostname'] || rest['addr.local'] + `User [${user}] SCP file transfer on node [${rest['server_hostname'] || rest['addr.local'] }] blocked`, }, [eventCodes.SFTP_OPEN]: { type: 'sftp', desc: 'SFTP Open', format: ({ user, path, ...rest }) => - `User [${user}] opened file [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] + `User [${user}] opened file [${path}] on node [${rest['server_hostname'] || rest['addr.local'] }]`, }, [eventCodes.SFTP_OPEN_FAILURE]: { type: 'sftp', desc: 'SFTP Open Failed', format: ({ user, path, error, ...rest }) => - `User [${user}] failed to open file [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] + `User [${user}] failed to open file [${path}] on node [${rest['server_hostname'] || rest['addr.local'] }]: [${error}]`, }, [eventCodes.SFTP_SETSTAT]: { type: 'sftp', desc: 'SFTP Setstat', format: ({ user, path, ...rest }) => - `User [${user}] changed attributes of file [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] + `User [${user}] changed attributes of file [${path}] on node [${rest['server_hostname'] || rest['addr.local'] }]`, }, [eventCodes.SFTP_SETSTAT_FAILURE]: { type: 'sftp', desc: 'SFTP Setstat Failed', format: ({ user, path, error, ...rest }) => - `User [${user}] failed to change attributes of file [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] + `User [${user}] failed to change attributes of file [${path}] on node [${rest['server_hostname'] || rest['addr.local'] }]: [${error}]`, }, [eventCodes.SFTP_OPENDIR]: { type: 'sftp', desc: 'SFTP Opendir', format: ({ user, path, ...rest }) => - `User [${user}] opened directory [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] + `User [${user}] opened directory [${path}] on node [${rest['server_hostname'] || rest['addr.local'] }]`, }, [eventCodes.SFTP_OPENDIR_FAILURE]: { type: 'sftp', desc: 'SFTP Opendir Failed', format: ({ user, path, error, ...rest }) => - `User [${user}] failed to open directory [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] + `User [${user}] failed to open directory [${path}] on node [${rest['server_hostname'] || rest['addr.local'] }]: [${error}]`, }, [eventCodes.SFTP_READDIR]: { type: 'sftp', desc: 'SFTP Readdir', format: ({ user, path, ...rest }) => - `User [${user}] read directory [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] + `User [${user}] read directory [${path}] on node [${rest['server_hostname'] || rest['addr.local'] }]`, }, [eventCodes.SFTP_READDIR_FAILURE]: { type: 'sftp', desc: 'SFTP Readdir Failed', format: ({ user, path, error, ...rest }) => - `User [${user}] failed to read directory [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] + `User [${user}] failed to read directory [${path}] on node [${rest['server_hostname'] || rest['addr.local'] }]: [${error}]`, }, [eventCodes.SFTP_REMOVE]: { type: 'sftp', desc: 'SFTP Remove', format: ({ user, path, ...rest }) => - `User [${user}] removed file [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] + `User [${user}] removed file [${path}] on node [${rest['server_hostname'] || rest['addr.local'] }]`, }, [eventCodes.SFTP_REMOVE_FAILURE]: { type: 'sftp', desc: 'SFTP Remove Failed', format: ({ user, path, error, ...rest }) => - `User [${user}] failed to remove file [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] + `User [${user}] failed to remove file [${path}] on node [${rest['server_hostname'] || rest['addr.local'] }]: [${error}]`, }, [eventCodes.SFTP_MKDIR]: { type: 'sftp', desc: 'SFTP Mkdir', format: ({ user, path, ...rest }) => - `User [${user}] created directory [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] + `User [${user}] created directory [${path}] on node [${rest['server_hostname'] || rest['addr.local'] }]`, }, [eventCodes.SFTP_MKDIR_FAILURE]: { type: 'sftp', desc: 'SFTP Mkdir Failed', format: ({ user, path, error, ...rest }) => - `User [${user}] failed to create directory [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] + `User [${user}] failed to create directory [${path}] on node [${rest['server_hostname'] || rest['addr.local'] }]: [${error}]`, }, [eventCodes.SFTP_RMDIR]: { type: 'sftp', desc: 'SFTP Rmdir', format: ({ user, path, ...rest }) => - `User [${user}] removed directory [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] + `User [${user}] removed directory [${path}] on node [${rest['server_hostname'] || rest['addr.local'] }]`, }, [eventCodes.SFTP_RMDIR_FAILURE]: { type: 'sftp', desc: 'SFTP Rmdir Failed', format: ({ user, path, error, ...rest }) => - `User [${user}] failed to remove directory [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] + `User [${user}] failed to remove directory [${path}] on node [${rest['server_hostname'] || rest['addr.local'] }]: [${error}]`, }, [eventCodes.SFTP_RENAME]: { type: 'sftp', desc: 'SFTP Rename', format: ({ user, path, ...rest }) => - `User [${user}] renamed file [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] + `User [${user}] renamed file [${path}] on node [${rest['server_hostname'] || rest['addr.local'] }]`, }, [eventCodes.SFTP_RENAME_FAILURE]: { type: 'sftp', desc: 'SFTP Rename Failed', format: ({ user, path, error, ...rest }) => - `User [${user}] failed to rename file [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] + `User [${user}] failed to rename file [${path}] on node [${rest['server_hostname'] || rest['addr.local'] }]: [${error}]`, }, [eventCodes.SFTP_SYMLINK]: { type: 'sftp', desc: 'SFTP Symlink', format: ({ user, path, ...rest }) => - `User [${user}] created symbolic link [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] + `User [${user}] created symbolic link [${path}] on node [${rest['server_hostname'] || rest['addr.local'] }]`, }, [eventCodes.SFTP_SYMLINK_FAILURE]: { type: 'sftp', desc: 'SFTP Symlink Failed', format: ({ user, path, error, ...rest }) => - `User [${user}] failed to create symbolic link [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] + `User [${user}] failed to create symbolic link [${path}] on node [${rest['server_hostname'] || rest['addr.local'] }]: [${error}]`, }, [eventCodes.SFTP_LINK]: { type: 'sftp', desc: 'SFTP Link', format: ({ user, path, ...rest }) => - `User [${user}] created hard link [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] + `User [${user}] created hard link [${path}] on node [${rest['server_hostname'] || rest['addr.local'] }]`, }, [eventCodes.SFTP_LINK_FAILURE]: { type: 'sftp', desc: 'SFTP Link Failed', format: ({ user, path, error, ...rest }) => - `User [${user}] failed to create hard link [${path}] on node [${ - rest['server_hostname'] || rest['addr.local'] + `User [${user}] failed to create hard link [${path}] on node [${rest['server_hostname'] || rest['addr.local'] }]: [${error}]`, }, [eventCodes.SFTP_DISALLOWED]: { type: 'sftp', desc: 'SFTP Disallowed', format: ({ user, ...rest }) => - `User [${user}] was blocked from creating an SFTP session on node [${ - rest['server_hostname'] || rest['addr.local'] + `User [${user}] was blocked from creating an SFTP session on node [${rest['server_hostname'] || rest['addr.local'] }]`, }, [eventCodes.SESSION_JOIN]: { @@ -735,10 +752,8 @@ export const formatters: Formatters = { type: 'db.session.start', desc: 'Database Session Started', format: ({ user, db_service, db_name, db_user, db_roles }) => - `User [${user}] has connected ${ - db_name ? `to database [${db_name}] ` : '' - }as [${db_user}] ${ - db_roles ? `with roles [${db_roles}] ` : '' + `User [${user}] has connected ${db_name ? `to database [${db_name}] ` : '' + }as [${db_user}] ${db_roles ? `with roles [${db_roles}] ` : '' }on [${db_service}]`, }, [eventCodes.DATABASE_SESSION_STARTED_FAILURE]: { @@ -751,8 +766,7 @@ export const formatters: Formatters = { type: 'db.session.end', desc: 'Database Session Ended', format: ({ user, db_service, db_name }) => - `User [${user}] has disconnected ${ - db_name ? `from database [${db_name}] ` : '' + `User [${user}] has disconnected ${db_name ? `from database [${db_name}] ` : '' }on [${db_service}]`, }, [eventCodes.DATABASE_SESSION_QUERY]: { @@ -1965,9 +1979,9 @@ const unknownFormatter = { export default function makeEvent(json: any): Event { // lookup event formatter by code - const formatter = formatters[json.code] || unknownFormatter; + const formatter = formatters[json.code as EventCode] || unknownFormatter; return { - codeDesc: formatter.desc, + codeDesc: typeof formatter.desc === 'function' ? formatter.desc(json) : formatter.desc, message: formatter.format(json as any), id: getId(json), code: json.code, diff --git a/web/packages/teleport/src/services/audit/types.ts b/web/packages/teleport/src/services/audit/types.ts index 26c94f54e0b51..cbcb7b8015482 100644 --- a/web/packages/teleport/src/services/audit/types.ts +++ b/web/packages/teleport/src/services/audit/types.ts @@ -1991,7 +1991,7 @@ type RawSpannerRPCEvent = RawEvent< export type Formatters = { [key in EventCode]: { type: string; - desc: string; + desc: string | ((json: RawEvents[key]) => string); format: (json: RawEvents[key]) => string; }; };