3

I've been looking for a way to log some more detailed information about the history of commands. My main purpose is to have a rough log of commands that were issued in order to build rough server timelines when debugging issues with our application. It is not for highly detailed auditing purposes. I came across this post which suggested an excellent way to modify PROMPT_COMMAND to augment the history log with additional information about each command. It suggests adding the following to the ~/.bashrc file:

export PROMPT_COMMAND='hpwd=$(history 1); hpwd="${hpwd# *[0-9]*  }"; if [[ ${hpwd%% *} == "cd" ]]; then cwd=$OLDPWD; else cwd=$PWD; fi; hpwd="${hpwd% ### *} ### $cwd"; history -s "$hpwd"'

This works awesome, except that it only happens when the PS1 prompt is issued. Is there a way to enhance this to work with non-interactive shells (I think that's the correct term)?

For example, I would like:

ssh host "ls | grep home"

To create an entry for ls | grep home on host as well, but since this isn't done through a PS1 prompt the linked solution falls short.

I have looked into auditd a little. This is a great utility, but the level of detail was way more than I need. I could have parsed the logs pretty easily, but pipes, redirects, loops become a nightmare to rebuild sanely into something pretty like what history already reports.

Community
  • 1
  • 1
JaredC
  • 4,990
  • 1
  • 18
  • 43

1 Answers1

1

A simple wrapper around ssh would seem like a straightforward way to achieve this.

shout () {
    local host
    host=$1
    shift
    ssh "$host" <<____HERE
        echo "$@" >>\$HOME/.shout-history
        bash -c "$@"
____HERE
}

Or if you want the wrapper to run locally,

shout () {
    local host
    host=$1
    shift
    echo "$@" >>$HOME/.shout-history
    ssh "$host" "$@"
}

I called this shout in opposition to ssh which ought to be, you know, quiet. See also this. Of course, if you are admin, you could simply move /usr/bin/ssh to someplace obscure and force your users to run a /usr/local/bin/ssh with contents similar to the above. It's easy enough to bypass by a knowledgeable user, but if you're really draconian, there are ways to make it harder.

If you are the admin of the remote host, you could force all users to run /usr/local/bin/shout as their shell, for example, and populate it with something more or less similar.

#!/bin/bash
echo "$@" >>/home/root/im.in.ur.sh.reading.ur.seekrit.cmds.lol
exec /bin/bash -c "$@"

Just make sure the transcript file is world writable but not world readable.

Filip J.
  • 575
  • 6
  • 10
tripleee
  • 158,107
  • 27
  • 234
  • 292
  • This requires everyone issuing a command remotely to use `shout` though, right? Is there a host based solution? – JaredC Jan 07 '13 at 22:02
  • You could wrap the login shell with something similar on the remote host. If you are desperate, you might hack the remote `bash` or `sshd` to do logging. – tripleee Jan 07 '13 at 22:04
  • I'm not too familiar with bash... is there some simple guidance for that you could give? – JaredC Jan 07 '13 at 22:05
  • Updated the answer slightly. – tripleee Jan 07 '13 at 22:10
  • I needed to use `exec /bin/bash $@`, and I ended up making a special shell for particular users for this. – JaredC Jan 07 '13 at 22:20
  • Thanks for the update. If you found this answer helpful, please consider marking at as accepted. Thanks! – tripleee Jan 07 '13 at 22:25