How to Audit and Log All User Commands in Linux (Including Vim Shell Commands)


2 views

When administering Linux systems, comprehensive command logging is crucial for security audits, troubleshooting, and compliance. The standard acct package (process accounting) often falls short because:

1. Truncates long commands
2. Doesn't capture shell escapes from editors
3. Misses commands executed through complex pipelines

Method 1: Bash History Enhancement

Modify /etc/profile or user's .bashrc:

# Log all commands to syslog
PROMPT_COMMAND='history -a >(tee -a ~/.bash_history | logger -t "USER_COMMAND[$USER]")'

# Unlimited history size
HISTSIZE=
HISTFILESIZE=
HISTTIMEFORMAT="%F %T "

# Important: Record multi-line commands
shopt -s cmdhist
shopt -s lithist

# Log commands immediately
PROMPT_COMMAND="history -a; $PROMPT_COMMAND"

Method 2: Auditd System Configuration

Configure /etc/audit/audit.rules:

# Monitor execve system calls
-a always,exit -F arch=b64 -S execve -k EXECVE
-a always,exit -F arch=b32 -S execve -k EXECVE

# Watch specific users (replace with actual usernames)
-w /home/user1/.bash_history -p wa -k USER_CMDS
-w /home/user2/.bash_history -p wa -k USER_CMDS

View logs with: ausearch -k EXECVE | aureport -x

Method 3: Snoopy Logger

Install this preload library for system-wide capture:

# Debian/Ubuntu
sudo apt-get install snoopy

# RHEL/CentOS
sudo yum install snoopy

# Verify installation
ldd $(which ls) | grep snoopy

Vim's :! commands bypass normal logging. Add this to /etc/vim/vimrc:

" Log shell commands to syslog
function! LogCommand(cmd)
    silent execute '!echo "[vim] ' . a:cmd . '" | logger -t "VIM_COMMAND[' . $USER . ']"'
    execute a:cmd
endfunction

" Override :! command
command! -nargs=+ -complete=shellcmd Shell call LogCommand()

For multiple servers, configure rsyslog (/etc/rsyslog.conf):

# For command logs
:programname, isequal, "USER_COMMAND" /var/log/user_commands.log
& stop

# For VIM commands
:programname, isequal, "VIM_COMMAND" /var/log/vim_commands.log
& stop

Test your setup with various scenarios:

# Regular shell command
ls -la /etc

# Vim shell escape
:vim:!cat /etc/passwd

# Complex pipeline
find /var/log -type f -name "*.log" | xargs wc -l | sort -n

Check all log locations:

tail -f /var/log/user_commands.log
tail -f /var/log/vim_commands.log
journalctl -t USER_COMMAND

When administering Linux systems, comprehensive command monitoring is crucial for security auditing and troubleshooting. Standard tools like acct often fall short because they don't capture:

  • Commands executed from within editors (vim, nano)
  • Subshell commands
  • Complex piped commands

1. Bash History Enhancement

First, ensure your .bashrc contains these critical settings:

export HISTTIMEFORMAT="%F %T "
export HISTCONTROL=ignoredups
export HISTSIZE=100000
export HISTFILESIZE=100000
shopt -s histappend
PROMPT_COMMAND='history -a'

2. Advanced System-wide Monitoring with auditd

The Linux audit subsystem provides the most comprehensive solution:

# Install auditd
sudo apt install auditd  # Debian/Ubuntu
sudo yum install audit   # RHEL/CentOS

# Configure to monitor execve syscalls
sudo nano /etc/audit/rules.d/audit.rules

Add these rules:

-a always,exit -F arch=b64 -S execve -k exec_cmds
-a always,exit -F arch=b32 -S execve -k exec_cmds

Restart the service:

sudo service auditd restart

3. Real-time Monitoring with Snoopy Logger

For lightweight alternative:

# Install
sudo apt-get install snoopy

# Configuration
sudo nano /etc/snoopy.ini

# Enable logging to syslog
enable_syslog = yes

To capture commands executed from within vim:

# Create wrapper script
sudo nano /usr/local/bin/vim

Script content:

#!/bin/bash
logger -t USER_COMMAND "vim command: $USER executed: $@"
/usr/bin/vim "$@"

Make it executable:

sudo chmod +x /usr/local/bin/vim

For enterprise environments, consider:

  • ELK Stack (Elasticsearch, Logstash, Kibana)
  • Splunk forwarder
  • Graylog

Example rsyslog configuration:

# /etc/rsyslog.d/command-logging.conf
:programname, isequal, "USER_COMMAND" /var/log/user-commands.log

After implementation, verify with:

sudo ausearch -k exec_cmds | less
tail -f /var/log/user-commands.log