How to log ssh client connection/command?

I would like to know how i could log SSH command lines a user is using on a server. For exemple, if the user Alex on my server is doing the following set of commands :

$ cd /tmp
$ touch myfile
$ ssh [email protected]
$ ssh [email protected]
$ vim anotherfile
$ ssh [email protected]

I would like to log the ssh commands used on the server in a file which looks like :

[2014-07-25 10:10:10] Alex : ssh [email protected]
[2014-07-25 10:18:20] Alex : ssh [email protected]
[2014-07-25 11:15:10] Alex : ssh [email protected]

I don't care what he did during his ssh session, i just want to know WHEN and TO WHERE he made a connection to another server.

The user is not using bash and i would like to avoid manipulating .bash_history anyway as the user can modify it.

Any clue on this ?

Thank you :)

edit : to be more specific :

a user connects to a server A and then connects from the server A to server B. I want to track down to which server he connects through ssh from server A.


Solution 1:

You could do it in three different ways as i see it - There are most likely many other ways to do it as well! The best method would be to attach a audit tool to the kernels sysexec calls so it would be untraceable by the user etc. The two other ways would simply be to modify the shell environment to log it.

Instead of me (grabbing the code/answers from google) showing you how to do it. I will give you links to sites that have explained this detailed already. I hope it's exactly what you need.

Btw, the easiest way is by far just to include something in your main bashrc/profile to affect all users.

Anyway's, here are links to bashrc solutions.

1) Bashrc solution: How to log commands executed by all the users in Linux? 2) Bashrc/trap solution: Bash: History to Syslog

The other way (kernel level) would be to look into to tools audit or acct. There are many sites out there who tell you how to setup logging of commands via kernel sysexec calls.

Solution 2:

Here's a script that you can use to capture the userid and other info to put in a logfile before kicking off the ssh. I tested it with several very complicated multiline ssh commands.

#!/bin/bash

# Title......: ssh (wrapper)
# Description: this script replaces the ssh binary and runs the real binary after logging the connection attempt

# variables
#----------------------------------
REALBINARY=/usr/bin/sshu
THISHOST=$(uname -n)
LOGFILE=/var/log/sshclient.log
CALLINGPROC=$(ps -o comm= $PPID)

log() {  # creates a basic log entry; $LOGFILE must be defined
 echo "$(date '+%Y-%m%d %H:%M:%S %Z') $$  $*">>$LOGFILE
}

SSHTARGETOPTS=$(echo "$@" | head -1)
while getopts :l: OPT 2> /dev/null
do
 case "$OPT" in
  l) TARGETUSER="$OPTARG" ;;
 esac
done

#after parsing with getopts, OPTIND will be the positional parameter number of the first argument after the options
FIRSTARG=$(echo $SSHTARGETOPTS | awk "{print \$$OPTIND}")
#if there is an '@' symbol in the FIRSTARG, parse out the LOGIN and TARGETSERVER, if not, TARGETSERVER is FIRSTARG
if [[ "$FIRSTARG" =~ '@' ]] ; then
 TARGETUSER="${FIRSTARG%@*}"
 TARGETSERVER=${FIRSTARG##*@}
else
 TARGETSERVER="$FIRSTARG"
fi
TARGETUSER="${TARGETUSER:-$LOGNAME}"

if [[ "$SUDO_USER" ]] ; then
 log "$THISHOST CallingProc='$CALLINGPROC' SUDO_USER='$SUDO_USER' became LOGNAME='$LOGNAME' ssh to TARGETSERVER='$TARGETSERVER' as TARGETUSER='$TARGETUSER' with command '$0 $SSHTARGETOPTS'"
else
 log "$THISHOST CallingProc='$CALLINGPROC' LOGNAME='$LOGNAME' ssh to TARGETSERVER='$TARGETSERVER' as TARGETUSER='$TARGETUSER' with command '$0 $SSHTARGETOPTS'"
fi

exec $REALBINARY "$@"