Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm running a debian etch server where users will be logging into (hopefully) a chroot jail through ssh. How can I have the commands they execute logged in a way they cannot delete, nor prevent?

share|improve this question
see this question… – hayalci Jul 13 '09 at 20:04
up vote 10 down vote accepted

install snoopy. If you only want to log the one user, do some syslog filtering fu.

share|improve this answer
I want to log every user. – Malfist Jul 13 '09 at 18:20
Then just install it, it'll "just work" (TM) – Cian Jul 13 '09 at 19:01
can I set it to log somewhere besides /var/log/auth.log? – Malfist Jul 13 '09 at 19:48
It goes to syslog, so you can filter it to wherever from there, iirc. I've only ever done anything with syslog-ng, so I've no idea about filters with regular syslog I'm afraid. – Cian Jul 13 '09 at 20:40

I wrote a method to log all 'bash' commands/builtins into a text-file or a 'syslog' server without using a patch or a special executable tool.

It is very easy to deploy, as it is a simple shellscript that need to be called once at the initialization of the 'bash'. (just 'source' it from .bashrc for example) It is based on the idea of using bash DEBUG traps. See also this post on

declare -rx HISTCONTROL=""                                  #does not ignore spaces or duplicates
declare -rx HISTIGNORE=""                                   #does not ignore patterns
declare -rx AUDIT_LOGINUSER="$(who -mu | awk '{print $1}')"
declare -rx AUDIT_LOGINPID="$(who -mu | awk '{print $6}')"
declare -rx AUDIT_USER="$USER"                              #defined by pam during su/sudo
declare -rx AUDIT_PID="$$"
declare -rx AUDIT_TTY="$(who -mu | awk '{print $2}')"
declare -rx AUDIT_SSH="$([ -n "$SSH_CONNECTION" ] && echo "$SSH_CONNECTION" | awk '{print $1":"$2"->"$3":"$4}')"
set +o functrace                                            #disable trap DEBUG inherited in functions, command substitutions or subshells, normally the default setting already
shopt -s extglob                                            #enable extended pattern matching operators
function audit_DEBUG() {
  if [ "$BASH_COMMAND" != "$PROMPT_COMMAND" ]               #avoid logging unexecuted commands after 'ctrl-c or 'empty+enter'
    local AUDIT_CMD="$(history 1)"                          #current history command
    if ! logger -p -t "$AUDIT_STR $PWD" "${AUDIT_CMD##*( )?(+([0-9])[^0-9])*( )}"
      echo error "$AUDIT_STR $PWD" "${AUDIT_CMD##*( )?(+([0-9])[^0-9])*( )}"
function audit_EXIT() {
  local AUDIT_STATUS="$?"
  logger -p -t "$AUDIT_STR" "#=== bash session ended. ==="
  exit "$AUDIT_STATUS"
declare -fr +t audit_DEBUG
declare -fr +t audit_EXIT
logger -p -t "$AUDIT_STR" "#=== New bash session started. ===" #audit the session openning
#when a bash command is executed it launches first the audit_DEBUG(),
#then the trap DEBUG is disabled to avoid a useless rerun of audit_DEBUG() during the execution of pipes-commands;
#at the end, when the prompt is displayed, re-enable the trap DEBUG
declare -rx PROMPT_COMMAND="trap 'audit_DEBUG; trap DEBUG' DEBUG"
declare -rx BASH_COMMAND                                    #current command executed by user or a trap
declare -rx SHELLOPT                                        #shell options, like functrace
trap audit_EXIT EXIT  

see the method explained in details here:

cheers Francois Scheurer

share|improve this answer

You may try ttyrpld. It's more than you want because it will log the whole tty.
I haven't used it myself but the way it's working (in kernel) makes that user can't alter logs.

share|improve this answer
cool, I'll check it out. If it plays nice with everything it'll be what I need. I can change it's log files to append-only just to make sure – Malfist Jul 13 '09 at 17:55
Cian answer using snoopy seems to be more like what you are looking for. – radius Jul 13 '09 at 18:11

You could enable system auditing.

share|improve this answer
and how does one do that? – Rory Jan 22 '10 at 15:11
Start with the man pages for auditd and go from there. It might not be part of the base Debian install, but the audit facility is a Linux kernel component, so the userland tools can be installed and used on any distribution. – Geoff Fritz Jan 22 '10 at 18:24

Use a grsecurity patched kernel. There is a kernel option exactly for this purpose.

share|improve this answer

bash keeps a command history of a specified size. You the admin can set that size, and easily write a script which goes and fetches that history per user via cron.

share|improve this answer
.bash_history is for convenience, not for security. There a number of reasons for this, not the least of which being that it's user-editable (or at least appendable). – Matt Jul 13 '09 at 18:43

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.