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


10 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