Bash – How to display commands executed via ssh and their user’s IP

bashlinuxnetworkingshellssh

I asked a question before, but I didn't get a satisfying answer in :
How can I display ssh commands executed from another machine?

so I'll ask this time precisely.

How to display commands and their users/IP's, executed in my server via SSH.
I'm looking to something like this :

#tail .bash_history
192.168.1.101 : vi /etc/ssh/sshd_config
192.168.1.102 : ls -l
192.168.1.101 : cd .ssh
192.168.1.101 : systemctl reload sshd.service
192.168.1.102 : service --status-all
etc…

Best Answer

Found the question interesting, so I googled a little, and find this.

More precisely, you need to add this line to your sshd_config.

ForceCommand logger -p user.notice "$SSH_ORIGINAL_COMMAND"

According to the man sshd_config:

ForceCommand
Forces the execution of the command specified by ForceCommand, ignoring any command supplied by the client and ~/.ssh/rc if present. The command is invoked by using the user's login shell with the -c option. This applies to shell, command, or subsystem execution. It is most useful inside a Match block. The command originally supplied by the client is available in the SSH_ORIGINAL_COMMAND environment variable. Specifying a command of internal-sftp will force the use of an in-process SFTP server that requires no support files when used with ChrootDirectory. The default is none.

On my Debian rsyslog installation user.* is written to /var/log/user.log


Please note that the above will execute the logger command in-place of the original command. If you want to log the command and then execute it, you'd have to do something along the lines of (assuming bash is available as /bin/bash):

ForceCommand /bin/bash -rc 'logger -p user.notice "$SSH_ORIGINAL_COMMAND"; $SSH_ORIGINAL_COMMAND'

Or use a wrapper script which is even more restrictive than the restricted shell or - for interactive logins - the sshrc (/etc/ssh/sshrc) file could be another option to implement the logging.

Related Question