Giter VIP home page Giter VIP logo

tlog's Introduction

Tlog

Build Status Coverage Status

Tlog is a terminal I/O recording and playback package suitable for implementing centralized user session recording.

Whereas most other similar packages write the recorded data to a file in their own format, or upload it to a custom server, tlog sends it to a logging service. Both the standard syslog and the journald interfaces are supported. The recorded data is encoded in JSON in a way which keeps it human-readable and searchable as much as possible.

The primary purpose of logging in JSON format is to eventually deliver the recorded data to a storage service such as Elasticsearch, where it can be searched and queried, and from where it can be played back.

Tlog contains three tools: tlog-rec for recording terminal I/O of programs or shells in general, tlog-rec-session for recording I/O of whole terminal sessions, with protection from recorded users, and tlog-play for playing back the recordings. You can run tlog-rec for testing or recording specific commands or shell sessions for yourself, or you can integrate it into another solution. Tlog-rec-session is intended to be a user's login shell. It puts itself between the actual user's shell and the terminal upon user login, logging everything that passes through. Lastly, tlog-play can playback recordings from Elasticsearch or from a file, made with either tlog-rec or tlog-rec-session. There is no difference in log format between tlog-rec and tlog-rec-session.

Building

Build dependencies are systemd, cURL, json-c, and libutempter, which development packages are systemd-devel, json-c-devel, libcurl-devel, and libutempter-devel on RPM-based distros, and pkg-config, libjson-c-dev, libsystemd-journal-dev/libsystemd-dev, libcurl-*-dev, and libutempter-dev on Debian-based distros.

To build from Git you'll need autoconf, automake and libtool packages. For creating RPM package rpm-build is also required.

If Systemd Journal support is not required, it can be disabled with configure's --disable-journal option, removing the systemd dependency as well.

Updating the system utmp and wtmp files can be enabled with the --enable-utempter configure option, utilizing the libutempter library.

If you'd like to build tlog from the Git source tree, you need to first generate the build system files:

autoreconf -i -f

After that, or if you're building a release source tarball, you need to follow the usual configure & make approach:

./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var && make

To generate a source tarball:

./configure --prefix=/usr --sysconfdir=/etc && make dist

From a source tarball you can build an SRPM package:

rpmbuild -ts <tarball>

Or an RPM package:

rpmbuild -tb <tarball>

Installing

You can use one of the release binary RPM packages and install them with your favorite tool. The RPM package does all the necessary setup for you.

Otherwise, if you built tlog from source, you can install it with the usual make install:

sudo make install

If you are recording other user sessions, and don't want them to be able to affect the recording process, make sure you use tlog-rec-session and its executable is SUID/SGID to separate and dedicated user and group. It doesn't require running as root and will be safer with a regular, dedicated user.

You will also need to create the session lock directory /var/run/tlog and make it writable (only) for the user(s) tlog-rec-session runs as. On systems where (/var)/run is a tmpfs you will also need to make sure the session lock directory is recreated on the next boot. In that case, on systems with systemd you'll need to create a tmpfiles.d configuration file, and on init.d systems - a startup script, creating the directory for you.

Testing

You can test if session recording and playback work in general with a freshly installed tlog, by recording a session into a file with tlog-rec and then playing it back with tlog-play.

Usage

Recording to a file

To record into a file, execute tlog-rec on the command line as such:

tlog-rec --writer=file --file-path=tlog.log

Playing back from a file

Both during, and after the recording you can play the session back with tlog-play:

tlog-play --reader=file --file-path=tlog.log

Recording to Systemd Journal

To record into the Systemd Journal, execute tlog-rec as such:

tlog-rec --writer=journal

Along with the regular JSON log messages, when recording to Journal, tlog copies a few JSON fields to Journal fields (unless explicitly disabled) to aid searching and extracting (parts of) particular recordings:

  • TLOG_USER - the user the recording was started as (user in JSON),
  • TLOG_SESSION - the audit session ID of the recording process (session in JSON),
  • TLOG_REC - host-unique recording ID (rec in JSON),
  • TLOG_ID - log message ID within the recording (id in JSON).

Playing back from Systemd Journal

In general, selecting Journal log entries for playback is done using Journal matches and timestamp limits, with -M/--journal-match, -S/--journal-since, and -U/--journal-until options.

In practice however, playback from Journal is usually done with a single match against the TLOG_REC Journal field. The TLOG_REC field contains a copy of the rec field from the logged JSON data, which is a host-unique ID of the recording. For example, to playback a recording which contains this message (output with journalctl -o verbose and abbreviated):

Mon 2018-01-22 10:51:48.463904 EET [s=87ea0a3f655a48cd80d7f49053860806;...
    _AUDIT_LOGINUID=1000
    _UID=1000
    _GID=1000
    _AUDIT_SESSION=2
    _BOOT_ID=12ca5b356065453fb50adfe57007658a
    _MACHINE_ID=2d8d017e2b1144cbbdd049a8a997911b
    _HOSTNAME=bard
    PRIORITY=6
    _TRANSPORT=journal
    _SYSTEMD_OWNER_UID=1000
    TLOG_REC=12ca5b356065453fb50adfe57007658a-306a-26f2910
    TLOG_USER=nkondras
    TLOG_SESSION=2
    TLOG_ID=1
    MESSAGE={"ver":"2.3","host":"bard","rec":"12ca5b356065453fb50adfe57007658a-306a-26f2910",...
    SYSLOG_IDENTIFIER=tlog-rec
    _PID=12394
    _COMM=tlog-rec
    _SOURCE_REALTIME_TIMESTAMP=1516611108463904

you can take the ID either from the TLOG_REC field value directly, or from the MESSAGE field (from the JSON rec field). You can then playback the whole recording like this:

tlog-play -r journal -M TLOG_REC=12ca5b356065453fb50adfe57007658a-306a-26f2910

When compiled with Systemd >= 245 it is possible to read log entries from a specific Journal namespace using parameters -N/--journal-namespace.

Playing back ongoing recordings

By default, once tlog-play reaches the last message a recording has so far, it exits. However, it can be made to poll for new messages appearing with the -f/--follow option, which is useful for playing back ongoing recordings.

Playback controls

Tlog-play accepts several command-line options affecting playback, including -s/--speed for setting playback speed multiplier, -g/--goto for specifying the location the playback should be fast-forwarded to, and -p/--paused for starting playback in paused state.

Several control keys are also recognized during playback:

  • SPACE or p for pause/resume,
  • { and } for halving and doubling the playback speed,
  • . for stepping through the recording (on pause or during playback)
  • G for fast-forwarding to the end of the recording (useful with --follow), or to the specified timestamp (see tlog-play(8) for details),
  • and q for quitting playback.

Rate-limiting recording

Both tlog-rec and tlog-rec-session can be setup to limit the rate at which recording's messages are logged. Tlog-rec accepts three options: --limit-rate=NUMBER, --limit-burst=NUMBER, and --limit-action=STRING, which specify rate limit in bytes per second, burst limit in bytes, and the limit action (pass/delay/drop), respectively. The same parameters can be changed using limit.rate, limit.burst, and limit.action configuration parameters for both tlog-rec and tlog-rec-session.

The default pass limit action lets all the messages through unhindered, effectively disabling rate-limiting. You can throttle logging, and slow down the user's terminal I/O using the delay limit action. Finally, you can simply drop the captured I/O, going above the rate and burst limits, using the drop action. See tlog-rec(8), tlog-rec.conf(5), and tlog-rec-session.conf(5) for details.

Playing back partial recordings

By default tlog-play will terminate playback, if it notices out-of-order or missing log messages. However, it is possible to make it ignore missing messages with the --lax option for when you need to playback a partial or a corrupted recording.

Recording sessions of a user

Change the shell of the user to be recorded to tlog-rec-session:

sudo usermod -s /usr/bin/tlog-rec-session <user>

Login as the user on a text terminal. By default the recorded terminal data will be delivered to Journal (if tlog was built with Journal support) or to syslog with facility "authpriv". In both cases default priority will be "info". It will appear in Journal, if you use journald, or in /var/log/auth.log on Debian-based systems, and in /var/log/secure on Fedora and derived systems.

Customize tlog-rec-session configuration in /etc/tlog/tlog-rec-session.conf as necessary (see tlog-rec-session.conf(5) for details).

Locale configuration issue on Fedora and RHEL

Fedora and RHEL (and some other distros) use an approach for configuring system locale, where the login shell is responsible for reading the locale configuration from a file (/etc/locale.conf) itself, instead of receiving it through the environment variables as most programs do. Since su clears environment when asked for imitation of a login shell (su -, or su -l), the shell can only retrieve locale configuration from that file, in that case, on these distros.

Because tlog-rec-session is not an actual shell and cannot read /etc/locale.conf file itself, it will use libc routines to read the environment, which will fall back to ANSI_X3.4-1968 (ASCII) in these cases. Since nowadays pure ASCII is rarely used, tlog-rec-session assumes that locale environment was lost, assumes the actual encoding is UTF-8, and prints a warning.

To work that around, you can implement the approach Debian and derived distros use. I.e. use PAM's pam_env.so module to read and set the locale environment variables before shell or tlog-rec-session starts. To accomplish that on Fedora or RHEL, put this into the /etc/pam.d/system-auth file, along with all other session lines:

session     required      pam_env.so readenv=1 envfile=/etc/locale.conf

However, tlog only supports UTF-8 so far, so the above workaround only serves to silent the fallback warning.

Configuring shell per-user using symlinks

You can create a symlink to tlog-rec-sessions containing the shell it should start, in its name. E.g. if you create a symlink like this:

sudo ln -s tlog-rec-session /usr/bin/tlog-rec-session-shell-bin-zsh

and execute tlog-rec-session-shell-bin-zsh, then tlog-rec-session will start and execute /bin/zsh as the shell to record. See tlog-rec-session(8) for details.

Such symlinks can then be assigned as login shells to certain users to have a specific shell started for them, under recording.

Configuring recording in SSSD

SSSD starting with v1.16.0 allows configuring which users and/or groups should be recorded (have tlog-rec-session started when they login), while also preserving the original user shell. See sssd-session-recording(5).

Recording sessions to Elasticsearch

Rsyslog can be set up to deliver tlog messages to Elasticsearch. First of all, increase the maximum message size to be 1k more than the tlog-rec-session payload. The default payload is 2kB, so the rsyslog maximum message size needs to be "3k" if the defaults are used:

$MaxMessageSize 3k

The line above needs to be above any network setup in rsyslog.conf (put it at the top to be safe).

Then the Elasticsearch output module needs to be loaded:

$ModLoad omelasticsearch

Massaging JSON

Before sending tlog messages to Elasticsearch they need to be reformatted and real time timestamp needs to be added, which can be done with this rsyslog template:

template(name="tlog" type="list") {
    constant(value="{")
    property(name="timegenerated"
             outname="timestamp"
             format="jsonf"
             dateFormat="rfc3339")
    constant(value=",")
    property(name="msg"
             regex.expression="{\\(.*\\)"
             regex.submatch="1")
    constant(value="\n")
}

Filtering out tlog messages

Then, a rule routing messages originating from tlog to Elasticsearch needs to be added. If you installed v4 or later tlog RPM package, or set up tlog-rec-session as SUID/SGID to a dedicated user yourself, then the rule can use that user ID to filter genuine tlog messages securely.

If your rsyslog receives messages from journald, with the imjournal module, then the rule condition should be:

if $!_UID == "<TLOG_UID>" then {
    # ... actions ...
}

Note that the above would only work with rsyslog v8.17.0 and later, due to an issue preventing it from parsing variable names starting with underscore.

If your rsyslog receives messages via syslog(1) socket by itself, with the imuxsock module, you need to enable the module's Annotate and ParseTrusted options. E.g. like this:

module(load="imuxsock" SysSock.Annotate="on" SysSock.ParseTrusted="on")

And then the rule condition should be:

if $!uid == "<TLOG_UID>" then {
    # ... actions ...
}

The <TLOG_UID> above should be replaced with the UID your tlog-rec-session runs as.

Otherwise you'll need to filter by something else. For example the program name (ident argument to syslog(3)), which tlog specifies as tlog. In that case the condition could be:

if $programname == "tlog-rec-session" then {
    # ... actions ...
}

However, note that any program is able to log with that program name and thus spoof tlog messages.

Sending the messages

Once your rule condition is established, you can add the actual action sending the messages to Elasticsearch:

action(name="tlog-elasticsearch"
       type="omelasticsearch"
       server="localhost"
       searchIndex="tlog-rsyslog"
       searchType="tlog"
       bulkmode="on"
       template="tlog")

The action above would send messages formatted with the tlog template, described above, to an Elasticsearch server running on localhost and default port, and would put them into index tlog-rsyslog with type tlog, using the bulk interface.

Add the following action if you want to also send tlog messages to a dedicated file for debugging:

action(name="tlog-file"
       type="omfile"
       file="/var/log/tlog.log"
       fileCreateMode="0600"
       template="tlog")

Further, if you don't want tlog messages delivered anywhere else you can add the discard action (~) after both of those:

~

If you'd like to exclude tlog messages from any other logs remember to put its rule before any other rules in rsyslog.conf.

Here is a complete example of a rule matching messages arriving from tlog-rec-session running as user with UID 123, delivered from journald. It sends them to Elasticsearch running on localhost with default port, puts them into tlog-rsyslog index with type tlog, using bulk interface, stores them in /var/log/tlog.log file, and then stops processing, not letting them get anywhere else.

if $!_UID == "123" then {
	action(name="tlog-elasticsearch"
		   type="omelasticsearch"
		   server="localhost"
		   searchIndex="tlog-rsyslog"
		   searchType="tlog"
		   bulkmode="on"
		   template="tlog")
	action(name="tlog-file"
		   type="omfile"
		   file="/var/log/tlog.log"
		   fileCreateMode="0600"
		   template="tlog")
	~
}

Playing back from Elasticsearch

Once you got tlog messages to Elasticsearch, you can play them back using the still rudimentary tlog-play command-line tool. You will need to tell it to use the Elasticsearch reader (es), supply it with the Elasticsearch base URL, and the query string, which would match the messages for your session.

The base URL should point to the _search endpoint for your type and index. E.g. a base URL for index tlog-rsyslog and type tlog on localhost would be:

http://localhost:9200/tlog-rsyslog/tlog/_search

The query string should follow the Elasticsearch query string syntax. E.g. to look for session #17 which happened in the last week on host server, you can use this query string:

host:server AND timestamp:>=now-7d AND session:17

Use --reader (or just -r), --es-baseurl and --es-query options to specify the reader, base URL, and the query string respectively. The full command for the above parameters could look like this:

tlog-play -r es \
          --es-baseurl=http://localhost:9200/tlog-rsyslog/tlog/_search \
          --es-query='host:server AND timestamp:>=now-7d AND session:17'

If you're playing back an ongoing session, adding the --follow or -f option will make tlog-play wait for more messages after it plays back all that were logged so far. Just like tail -f will wait for more lines to be added to a file it's outputting.

Interrupt tlog-play (e.g. press Ctrl-C) to stop the playback at any moment.

Instead of specifying the reader and the base URL on the command line every time, you can put them in /etc/tlog/tlog-play.conf configuration file.

Limitations

Currently tlog-play functionality is limited. It doesn't provide a way to rewind playback, only to fast-forward. It polls files, Journal and Elasticsearch for new messages, instead of asking to be updated when they appear, which impairs performance. Even though the messages contain recorded terminal window (re)sizes, it doesn't resize its own terminal to fit the output better. Further development will be addressing these.

Contributing

Please read the Contributing Guidelines for more details on the process for submitting pull requests.

tlog's People

Contributors

ajf8 avatar alexole avatar casantos avatar conan-kudo avatar dmjacobsen avatar frasertweedale avatar jhrozek avatar justin-stephenson avatar sabbaka avatar sanjaymsh avatar spbnick avatar spoore1 avatar theblazehen avatar trevor-vaughan avatar tvdw avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tlog's Issues

Implement privilege separation in tlog-rec

Make tlog-rec executable SUID/SGID to a dedicated user/group. Drop back to the
original user/group before exec'ing the shell in the fork. This will keep
tlog-rec safe from the modification by the recorded user and would also allow
authenticated filtering of the log messages.

Upon RPM installation, a special user and group both named tlog should be
created, and tlog-rec should be owned by them and marked SUID and SGID.

After forking the shell process, tlog-rec should drop to the real UID/GID with
setuid(getuid()) and setgid(getgid()).

For additional security, consider retreiving the effective user/group IDs and
setting them to the real IDs with seteuid/setegid right after starting,
passing them around (say as euid/egid) and only setting them back with
seteuid/setegid when necessary. I.e. when reading the configuration and
when opening the logging socket/file.

Also consider calling setreuid(euid, euid)/setregid(egid, egid) in the
parent process after forking the shell, so the parent (recording) process
would not be able to regain the user's real IDs. However, ignore EPERM,
perhaps producing a warning, as POSIX says that might not be permitted, even
though it works on Linux and some BSDs.

To verify:

  • Check that all user/group IDs in /proc/PID/status of the user shell are
    the user's IDs.
  • If setreuid/setregid use is implemented, check that all user/group IDs in
    /proc/PID/status of the parent recording process are the tlog's IDs.
    Otherwise, check that real IDs are user's IDs and others are tlog IDs.
  • Check that log file is created with tlog UID/GID, when using the file
    writer.
  • Check that journald and rsyslog record tlog UID/GID as the logger's
    credentials, and rsyslog can filter by them, when using the syslog writer.

Add integration tests

To test tlog end-to-end add integration tests. Possible tests follow.

General Recording

  • For several payload limit setting values (minimum, default, large) check
    that tlog-rec produces payloads within the limit, for both input and output,
    for the following crossing the limit:
    • single-byte UTF-8 characters,
    • multi-byte UTF-8 characters,
    • input byte sequences producing escape sequences on the output,
    • invalid input byte sequences diverted into binary fields on the output,
    • window resize records.
  • For several latency settings (minimum, default, long) check that tlog-rec
    writes a record on time when there was any I/O or window resizes, and
    doesn't when there wasn't any.
  • For each --log-* option check that turning it on or off reflects in tlog-rec
    output. That is input/output/window resizes are (not) recorded as
    configured.
  • Check that various rate-limiting settings affect tlog-rec log as documented.
    That is:
    • average rate is within 5% of configured over 10 seconds of recording,
    • configured amount of burst I/O is allowed through,
    • configured action (pass/delay/drop) is observed.
  • Check that tlog-rec can record to a file correctly, and responds
    appropriately for various conditions preventing it from writing one.
    Including:
    • Filesystem permissions
    • SElinux violation (assuming the session is somehow confined)
    • Insufficient space on device
  • Check that tlog-rec can record to syslog correctly, and observes facility
    and priority settings
  • Check that tlog-rec can record to journal correctly, observes the priority
    setting, and adds the documented extra Journal fields correctly
  • Check that both terminal input and output recorded by tlog-rec and played
    back by tlog-play are preserved, including:
    • Valid 1-, 2-, 3-, and 4-byte UTF-8 byte sequences
    • Invalid UTF-8 byte sequences
    • Characters that must be escaped in JSON
    • Window resizes
  • Check that terminal input, output, and window resize timing is preserved
    when recorded by tlog-rec and played back by tlog-play.
  • Check that tlog-rec records and tlog-play faithfully reproduces, without
    crashing/memory corruption, any input and output produced by a fuzzer.
  • Check that tlog-play can process any input produced by a fuzzer without
    crashing or memory corruption.

Tlog-rec

  • Check that tlog-rec observes settings stored in its system-wide
    configuration file.
  • Check that tlog-rec overrides settings from its system-wide configuration
    file by ones found in file specified with TLOG_REC_CONF_FILE environment
    variable.
  • Check that tlog-rec overrides settings from the file specified with
    TLOG_REC_CONF_FILE environment variable by settings specified in
    TLOG_REC_CONF_TEXT environment variable value.
  • Check that tlog-rec observes SHELL environment variable value, when no
    command to record was specified.
  • Check that tlog-rec doesn't interpret options passed to the recorded program
    as its own.

Tlog-rec-session

  • Check that tlog-rec-session doesn't interpret arguments passed to the shell
    as its own, when started with -c option.
  • Check that tlog-rec-session doesn't interpret arguments passed to the shell
    script to execute as its own, when started with arguments, but without the
    -c option.
  • Check that tlog-rec-session starts a login shell when invoked with argv[0]
    starting with dash -.
  • Check that tlog-rec-session starts a login shell when invoked with -l
    option.
  • Check that tlog-rec-session observes settings stored in its system-wide
    configuration file.
  • Check that tlog-rec-session observes the shell specified in its system-wide
    configuration file.
  • Check that tlog-rec-session observes the notice text setting specified in
    its system-wide configuration file.
  • Check that tlog-rec-session overrides settings from its system-wide
    configuration file by ones found in file specified with
    TLOG_REC_SESSION_CONF_FILE environment variable.
  • Check that tlog-rec-session overrides settings from the file specified with
    TLOG_REC_SESSION_CONF_FILE environment variable by settings specified in
    TLOG_REC_SESSION_CONF_TEXT environment variable value.
  • Check that tlog-rec-session observes TLOG_REC_SESSION_SHELL environment
    variable value, overriding the shell specified in TLOG_REC_SESSION_CONF_TEXT
    environment variable.

Tlog-play

  • Check that tlog-play can playback recordings stored in files.
  • Check that tlog-play can playback recordings stored in journal.
  • Check that tlog-play can playback recordings stored in ElasticSearch.
  • Check that tlog-play would tolerate missing log messages with lax option
    enabled, and would not with it disabled.
  • Check that tlog-play observes -s/--speed option correctly.
  • Check that tlog-play observes -p/--paused option correctly.
  • Check that tlog-play observes all possible value types of -g/--goto option
    correctly. Including negative and ones beyond the end of the recording.
  • Check that tlog-play observes -f/--follow option correctly with any log
    reader.
  • Check that tlog-play observes -S/--journal-since, -U/--journal-until,
    and -M/--journal-match options correctly.
  • Check that tlog-play reacts to control keys correctly during playback.
  • Check that tlog-play doesn't react to escape sequences in recording, which
    would normally invoke a response from the terminal including characters that
    are used to control tlog-play. See #147.

Most, if not all, integration tests should run within make check.

Add Doxygen documentation generation to the build

To ship Doxygen documentation with the devel package and to make sure the doxygen documentation is always valid add the documentation generation to the build system, either to the "all" target, or to a special target.

Figure out the origin timestamp JSON sink should use

At the moment the JSON sink uses the timestamp of the first written packet as the origin of all the messages. However the first packet's timestamp might get shifted if the packet was an incomplete character terminated later, resulting in the first message having non-zero "pos".

Consider renaming "timing" to "meta"

The "timing" message field stores information on stream runs and window sizes, plus delays between them. Even though it is actually timing, it is also metadata for all the streams and forks involved, and might be better named as such from the perspective of the considerable code chunk that implements them. Check if "timing" might actually be better named "meta" both in messages and in the code.

Check if tlog-rec can be used with sudo

See if tlog-rec can be used with sudo to any benefit. Check if there's anything tlog needs to do for that. E.g. tlog-rec might be assigned as the shell for a dedicated privileged user, which is not root, but would still need to start some specific shell.

Split JSON encoding streams into forks

Split JSON encoding streams into two forks each: one for text and another for binary, each having the same interface and working with the dispatcher. This would also require changing the timing string format to have symmetric operations for reading/skipping and would actually make it simpler. This can also make stream implementations simpler and more self-contained, even though the actual code size would increase.

Implement a GUI playback app/backend

Implement a (GNOME?) GUI playback app or a backend to tlog-play which would observe window sizes and terminal types through using a terminal widget such as VteTerminal, and resizing the window and/or font automatically, as recorded. Consider using XEmbed to embed an actual terminal and resizing it accordingly as a simpler approach.

Implement charset conversion on recording

As users can use ono of the multitude of character encodings and JSON only supports UTF-8, tlog-rec needs to convert the received data accordingly.

An invocation of "locale charmap" can return the used encoding name, but might be too burdensome and a lighter way may need to be found.

We can use iconv for conversion, but we need a way to detect and extract invalid characters for separate, binary storage. Iconv seems to be able to stop at the first invalid byte, which can be used to implement that. We can use two iconv descriptors: one normal and another discarding invalid characters (with "//IGNORE" encoding suffix) to somehow extract invalid bytes. However we need to check how far back all the required functionality goes and if it's available in RHEL6.

Handle running under an X session in tlog-rec

Tlog-rec shouldn't record when running under an X session - other software should be used to record the whole graphical session instead, not just terminals. Add a way to detect such invocations and simply exec the shell after dropping back to the original user.

Ensure session recordings are not duplicated

Implement limiting recording to one per session.

Perhaps have a tlog-only-writable directory (tlog-rec will be SUID when #5 is fixed) with files named after session IDs, containing tlog-rec PIDs. Session IDs uniquely identify logins within a single system boot. Tlog-rec also uses them in its JSON messages.

So, if tlog-rec is started and finds that this session already has a file in
that directory, and the process with the stored PID is alive, it just drops the
privileges and execs the user shell.

Consider implementing playback correlated with audit

Consider implementing a playback interface which would allow correlating terminal I/O with at least audit messages, all fetched from ElasticSearch. Perhaps we can simply fetch any specified indexes, join them by absolute timestamp and allow scrolling them side-by-side. Say, a bunch of options to tlog-play.

Make sure tlog can be used in a jump-server setup

As tlog-rec cannot be used safely and reliably to record superuser sessions another approach needs to be employed. One of those is using a "jump-server", where the user would first login to a special "jump" server where tlog-rec would be running, and from there (automatically?) login to the target server.

In this case some of the logged data might need to be altered, such as hostname, or the user name. Consider the whole setup, how it would work, and implement the extra flexibility, if necessary.

Make configuration validation function return error message

Make tlog-rec and the future tlog-play configuration validation function return validation error string instead of printing it, so the function could be used in assertions.

Add assertions using it all over configuration loading and using routines.

Merge separate messages when reading

When reading a packet from a JSON source, merge similar timing runs across messages. This can reduce the number of terminal write syscalls on playback, e.g. when a lot of output is produced and message size is not that big.

Fix error handling in tlog-rec.c

Tlog-rec.c has a number of error-handling issues, where grc wouldn't be initialized properly or not assigned error codes, at least in the "run" function. We need to fix those.

Implement recording throttling

It should be possible to limit tlog recording throughput so that neither local nor remote systems are overwhelmed with too many log messages and don't run out of space. The best way would be to have the logging server implement per-process rate limiting with flow control, i.e. without dropping the log messages. However, as the existing logging servers don't seem to do that, we'll need to implement that in tlog. The limit might be expressed in encoded bytes per second and observed at the writer level.

Check if FQDN retrieval is reliable/necessary

As Jakub suggested, the standard FQDN retrieval approach used by tlog-rec might be unreliable. Consider using a different method, having a fallback, and/or relying on a configured value.

Record terminal type as well

Add a field to every message specifying the type of the terminal it was recorded on. Check if the TERM environment variable can be used reliably or other approach is necessary.

Support running tlog-rec without a terminal

Tlog-rec needs to support running without a terminal connected to either or both of STDIN/STDOUT, but to e.g. a file or a pipe. This is particularly necessary for ssh sessions with command to execute. E.g. 'ssh host command arg' invocations.

Add proper command-line interface to tlog-play

Add a standard command-line interface to tlog-play, including options, online help and manpage. Consider using the same approach as for tlog-rec, schema and everything. Consider the necessity of a configuration file.

Implement pluggable memory allocation

As per suggestion from Jakub, implement pluggable memory allocation in tlog if the library grows bigger and there is a potential for outside users.

Add a real time timestamp to each message

As tlog-rec always caches the recorded data for at least one second, the timestamp the log server adds lags behind and doesn't represent the exact time the input was done, which might make correlating with other log messages more difficult.

Implement adding a real time timestamp to each message signifying the real and absolute time the first timing entry has arrived.

Limit timestamps passed to sinks

Add checks for timestamps passed to sinks to not exceed the maximum pos recognized by source, supposedly for delta to be within TLOG_DELAY_MAX.

Implement passing the shell name to tlog-rec via argv[0]

The simplest way to specify the shell to tlog-rec might be specifying a special shell for the user - one for each possible invoked shell. Such shell might start with "tlog-rec-shell-" and end with the shell name. E.g. "tlog-rec-shell-bash". The actual executable would be just a symlink to tlog-rec and tlog-rec would extract the shell to be invoked from argv[0]. This would make standalone setups easier to implement and wouldn't require using pam_env or pam_sss to pass the shell to tlog-rec via environment variables.

Abort tlog-rec and tlog-play if terminal uses non-UTF-8 charset

As tlog-rec doesn't support character encoding conversion yet, implement character encoding detection and abort tlog-rec if the terminal uses non-UTF-8 charset. Same goes for tlog-play.

An invocation of "locale charmap" can return the used charset name, but might be too burdensome and a lighter way may need to be found.

Limit the whole message size in JSON sink

Provide an option to limiting the whole logged JSON message size in JSON sink, including all the fields and formatting. This can be done by formatting a dummy message with empty in/out_txt/bin fields, as soon as the "pos" field is known, and getting its length.

Check if conf schema can do without "default" flag

At the moment the configuration schema file has "default" flag for each parameter. However, it is only making sense for the "file" origin as only there can be a defaults file. Consider removing this flag and replacing it with something else. Perhaps have origin "none" or some such, which goes before "file" and means parameters without defaults.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.