Reputation: 5310
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.
Upvotes: 4
Views: 1334
Reputation: 385
Check out SSHLog -- this seems to do what you're looking for: https://github.com/sshlog/agent/
I'm a code contributor on this project.
It monitors SSH sessions and reports each session and all the commands they run. The exit code and command output is also available.
By default it will write to a log file, but it is configurable and has plug-ins for remote syslog, slack alerts, e-mail, etc.
Upvotes: 1
Reputation: 189628
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.
Upvotes: 1