1. Overview

In system administration, it is crucial to maintain a record of every command executed by a user to ensure auditing and security. Keeping track of every command enables system administrators to monitor user activity, identify security threats, and troubleshoot system problems effectively.

In this tutorial, we’ll discuss the steps required to log every command a user executes in Linux using the rsyslog service.

Additionally, we’ll discuss the process of activating command logging in the shell. We’ll also go over setting up the system to capture log messages and viewing the log file.

2. Importance of Logging Every Command

Logging every command a user executes is an essential security practice that provides many benefits for organizations.

Firstly, logging helps to detect and investigate security breaches, identify potentially malicious activity or unauthorized access, and prevent future attacks. By capturing every command a user executes, organizations can easily monitor user activity and identify suspicious or abnormal behavior.

Many industries require logging user activity for compliance with regulations and audit requirements. The financial institutions are required to retain audit logs for seven years. Furthermore, by logging every command a user executes, organizations can demonstrate compliance and ensure that they meet regulatory requirements.

Logging every command executed by a user is useful in forensic analysis. For example, in the event of a security breach or attack, detailed logs of every command executed can provide valuable information for forensic analysis, helping to identify the scope and impact of the breach and enabling the organization to take appropriate action.

3. Enable Command Logging in the Shell

In order to keep track of all user commands, we must alter the shell configuration file to set the PROMPT_COMMAND environment variable. Most importantly, PROMPT_COMMAND is a unique variable that allows command execution before the shell prompt appears.

We can set the PROMPT_COMMAND environment variable to the history command, which appends each executed command to the shell history file. Alternatively, we can also use the logger command to mark the command to the system log. To demonstrate, let’s add PROMPT_COMMAND to the /etc/bashrc file:

# Set PROMPT_COMMAND to log every command to syslog
PROMPT_COMMAND='history -a >(logger -t "[$USER] $SSH_CONNECTION")'

This will enable command logging for all bash shells. Furthermore, within the bash shell, there exists a command known as “history” that presents the user’s command history. Additionally, we can use this variable with the history and logger commands to log every user command. Furthermore, by attaching the command to the shell history file, we can maintain a record of all executed commands. The logger command is a command-line tool that writes messages to the system log. Using the -t option with the logger command allows a personalized tag to be added to the log message, facilitating recorded commands identification. 

The rsyslog handles the command logs, so let’s take a look at the default rsyslog logs:

$ tail -f /var/log/messages
Mar 28 14:21:56 ip-3-168-15-118 systemd[1]: Started Session 38 of user root.
Mar 28 14:21:56 ip-3-168-15-118 systemd[1]: nm-cloud-setup.service: Succeeded.
Mar 28 14:21:56 ip-3-168-15-118 systemd[1]: Started Automatically configure NetworkManager in cloud.

This output shows that normal syslog is logged at the moment, and no command logs are being logged.

4. Configuring the System to Capture Log Messages

The rsyslog service utilizes facilities and severity levels to categorize and prioritize log messages. Facilities indicate the source of the log message, while severity levels indicate the importance of the log message.

4.1. Configure rsyslog

To capture log messages dispatched through the logger command, we need to edit the rsyslog configuration file. The rsyslog service handles and processes log messages from various sources. Let’s add the following lines to the file:

# Log every command executed by a user to a separate file
local6.* /var/log/commands.log

This will capture log messages the logger command sends with the specified tag and write them to the /var/log/commands.log file.

4.2. Restarting the rsyslog Service

To enforce the rsyslog configuration file modifications, it is necessary to reboot the rsyslog service. Furthermore, this can be done by executing the following command:

$ sudo systemctl restart rsyslog

To illustrate, let’s check out the rsyslog service status:

$ systemctl status rsyslog
   rsyslog.service - System Logging Service
   Loaded: loaded (/usr/lib/systemd/system/rsyslog.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2023-03-28 09:38:56 UTC; 4h 45min ago
     Docs: man:rsyslogd(8)
           https://www.rsyslog.com/doc/
 Main PID: 8398 (rsyslogd)
    Tasks: 3 (limit: 48582)
   Memory: 1.1M
   CGroup: /system.slice/rsyslog.service
           └─8398 /usr/sbin/rsyslogd -n
Mar 28 09:38:56 ip-192-168-5-149.us-east-2.compute.internal systemd[1]: Starting System Logging Service...
Mar 28 09:38:56 ip-192-168-5-149.us-east-2.compute.internal rsyslogd[8398]:
  [origin software="rsyslogd" swVersion="8.2102.0-10.el8" x-pid="8398" x-info="https://www.rsyslog.com"] start
Mar 28 09:38:56 ip-192-168-5-149.us-east-2.compute.internal systemd[1]: Started System Logging Service.
Mar 28 09:38:56 ip-192-168-5-149.us-east-2.compute.internal rsyslogd[8398]:
  imjournal: journal files changed, reloading...  [v8.2102.0-10.el8 try https://www.rsyslog.com/e/0 ]

In the above output, we can see that the rsyslog service has started successfully.

4.3. Viewing the Log File

We can use the tail command to view the logged commands. Furthermore, let’s look at the tail command in the log file:

$ tail -f /var/log/commands.log
Mar 28 14:23:56 ip-3-168-15-118 shell[9346]: docker ps
Mar 28 14:23:58 ip-3-168-15-118 shell[9346]: docker ps -a
Mar 28 14:26:01 ip-3-168-15-118 shell[9346]: cat /etc/rsyslog.conf
Mar 28 14:27:02 ip-3-168-15-118 shell[9346]: tail -f /var/log/commands.log
Mar 28 14:27:05 ip-3-168-15-118 shell[9346]: ls -lsh
Mar 28 14:27:07 ip-3-168-15-118 shell[9346]: pwd
Mar 28 14:27:52 ip-3-168-15-118 shell[9346]: tail -f /var/log/commands.log
Mar 28 14:27:56 ip-3-168-15-118 shell[9346]: systemctl restart  rsyslog
Mar 28 14:28:00 ip-3-168-15-118 shell[9346]: systemctl status rsyslog

The above output shows that the system logs all the commands into the /var/log/commands.log file.

5. Drawbacks

Logging every command a user executes can be advantageous, but there are several constraints and potential problems.

  • This approach might not capture commands executed by programs or scripts
  • Logging confidential data (such as passwords) could present a security hazard
  • Increased logging operations could affect system efficiency

Additionally, we should carefully consider command logging and take appropriate measures to secure log files and control access.

6. Conclusion

In this tutorial, we discussed how to log every command executed by a user in Linux using the rsyslog service.

First, we enabled command logging in the rsyslog configuration. After that, we executed the commands to verify the command logging file.

Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.