Logging Shell Commands


In response to my previous post about logging in directly as root [1] it was suggested that using sudo is the only way to log the commands that are entered as root. One reason for doing this is if you don’t trust the people who are granted root access and you want to log all commands to a remote server that is run by different people. I wonder whether it is really possible to run systems with untrusted sysadmins, if someone can apply patches etc then they can surely install a trojan and then wait a while before activating it to make things more difficult for anyone who is analysing the logs.

One of the many issues is that even the restricted version of vim permits the :r and :w commands, so one could start vim from sudo with an innocuous file as the target of the edit operation and then read and write some critical file such as /etc/shadow. I expect that someone has written an editor which has a restricted mode that doesn’t allow reading/writing files other than the one specified on the command-line, and if not it surely wouldn’t be difficult to patch vim (or your favorite editor) to have such a mode of operation. But there are always other programs that can access files other than the ones specified on their command-line. It seems that using the auditctl interface to log access to certain critical files (EG read access to /etc/shadow and write access to everything under /etc, /bin, /sbin, and /usr) would be a necessary part of an effective auditing strategy and that sudo would only comprise a small part of a useful configuration.

There are other viable ways of logging everything that is done as root which offer benefits over sudo.

Ways of Logging Shell Commands

The Korn shell supports doing all the logging you might desire as part of a shell function [2].

Bash can have a similar shell function to do the logging, but when a command is entered the previous command is logged [3], this means that any single bash command that unsets this will never be logged. It might be possible to solve this if you know more about Bash than I do. I wonder if the Korn shell function has the same issue. This is still probably useful for some situations when you want to track what honorable sysadmins do, but of little benefit for tracking hostile sysadmins – (tracking hostile sysadmins is actually possible).

You can put code in a file such as /etc/bash.bash_logout to log the commands elsewhere, but even trivial things such as “kill -9 $$” can defeat that so it’s only useful when the sysadmin is trusted.

The Sudoshell project exists to log all data that is entered in a shell [3]. One deficiency of this for the people who don’t trust the root user is that it logs the data to files on disk, but it shouldn’t be difficult to rewrite sudoscriptd to write directly to another machine over the network. Also one benefit of this for auditing is that it captures all the output of the commands as well (which can be a little inconvenient to decipher when curses programs are run. The web site also describes some of the problems with trying to use sudo directly for everything (such as pipelines).

If you compile Bash version 4.1 with the SYSLOG_HISTORY macro enabled (which can be done by editing the file config-top.h) then it will log all commands to syslog. RootShell.be has a short post about this which mentions the security issues, some commands take passwords as parameters and these passwords could be exposed to the network [5]. Of course the best option is to just avoid such commands. Thanks to Chris Samuel for pointing out the Bash logging feature.


If you use sudo for auditing root access then you lose some shell functionality. Sudo also only logs the commands that are executed – you don’t get logging of output. It seems that depending on the exact needs either a modified version of Sudoshell or the logging that can be compiled in to Bash would be the way to go depending on the exact requirements. The main benefit of using sudo for logging would be that some distributions of Linux are configured that way by default – but it seems unlikely that someone would go to the effort of running a separate logging server that the regular sysadmin team can’t touch and then configure their servers in a default manner.


4 thoughts on “Logging Shell Commands”

  1. Glen Turner says:

    The only worthwhile case is when the sysadmin is trusted. If the sysadmin isn’t trusted then logging from the shell can be logging from the wrong place as the sysadmin can always exec() what they want and hide that exec() through clever naming (eg, compile a ~/bin/ls) or programmable utilities (emacs, Firefox, etc).

    In the untrusted sysadmin case you need keystroke capture, For example, by using a modified sshd or by using covert hardware at the keyboard.

    Like all interception, keystroke capture leads to an attractive target at the interception collection point and thus a significant risk of network-wide compromise via one subverted machine.

    Part of the attraction of MAC schemes like SELinux is that it digs us out of this issue. The MAC is concerned about the activity, not the command, so the complexity of discovering all the ways a command can be run goes away. Keeping an audit log doesn’t carry as high a risk as a keystroke log.

  2. poisonbit says:

    Before bash4, snoopy (http://sourceforge.net/projects/snoopylogger/) adding a remote syslog to store commands, avoids some (shell workarounds) problems on logging plain users…
    For $UID 0, I think that always “something” can be done to avoid anything (i.e. with snoopy that is not $SHELL based… simply need to stop/kill syslog).

  3. It always makes me wonder when people speak about sudo and that using editors is an issue to be aware of but on the other hand always fail to mention that there is the pseudo command “sudoedit” for exactly this reason. It copies the file in a save manner and starts the editor as the calling user instead of as root, and starting to edit such a file would be with “sudo -e $file”.

    Also, claiming that sudo is a good way to log the commands that people run is quite iritating, given that it seems to be common habit to run “sudo -s” and start hacking from there. What gets logged from there on is to the user shell’s history and not syslog, and depending on shell a “kill -9 $$” can even avoid that in the end. It’s an even worse false sense of safety/traceability than the ignored sudoedit feature.

  4. etbe says:

    Gerfried: Thanks for the information about sudoedit, I don’t know how I missed it when I read the man page in the past. I guess I was just concentrating on what I wanted to do rather than exploring what was possible. I trusted the descriptions of limitations in sudo because they matched my prior experience.

    Presumably if one wanted to strictly log everything then one could prohibit sudo -s (maybe be hacking the source to make it impossible) and then configure sudo to not allow running editors or shells. But it’s a lot more effort than just recompiling bash with one macro definition!

Comments are closed.