How to log every linux command to a logserver
Solution 1:
This is not how you approach the problem. Once you give shell access to a user, you are entrusting that user to do anything he/she has the proper permissions to. Forget command logging, there are way too many ways to execute a command in any Unix system.
For example, the user may start a mail client (the only command logged is pine
, for example), in there he selects "Compose" which starts VI, and from VI he launches any command he wants through :!cmd
. This command isn't logged anywhere, and from the point-of-view of the system, it is like any helper application called by VI, like grep or sort. The only command logged by the shell was pine
.
It seems that what you actually want is called auditing. Enable the auditing subsystem and use the auditctl
command and the auditd
daemon from the audit package to control what is logged. More information is in the auditctl(8) manual page.
Note that logging every process instantiation it may also not be optimal. For example, the simple ./configure
for a software package (created using autotools) is notable for creating thousands of process instantiations. This will flood the auditing log with so much noise that it becomes very hard to analyze it later.
Solution 2:
Install the acct
package (package name varies by distro, also known as process accounting) and use lastcomm <username>
:
[mithrandir]-[/home/sernin]-[1951] % lastcomm sernin
tr sernin pts/2 0.00 secs Fri Nov 12 12:02
zsh F sernin pts/2 0.00 secs Fri Nov 12 12:02
tr sernin pts/2 0.02 secs Fri Nov 12 12:02
zsh F sernin pts/2 0.00 secs Fri Nov 12 12:02
fortune sernin pts/2 0.00 secs Fri Nov 12 12:02
xmodmap sernin pts/2 0.00 secs Fri Nov 12 12:02
xrdb sernin pts/2 0.00 secs Fri Nov 12 12:02
sh sernin pts/2 0.00 secs Fri Nov 12 12:02
cpp sernin pts/2 0.00 secs Fri Nov 12 12:02
You can also search by tty or command name. As usual,man lastcomm
for more info.
Solution 3:
If you're willing to do a little C programming, you can do this by writing a library that wraps execve, logs to syslog, then dlopen's the library containing the real execve syscall. Then in /etc/environment, set LD_PRELOAD to the path for the library you've made.
You will want to be careful about entering a loop here, so you may want to either only log the exec's of certain binaries, or exclude others (like syslog) from being logged.