Enhance and secure your Bash shells

Information Is Power

The knockout shell that is Bash can also quietly assist by providing a little extra security for your servers. I would probably to call it user auditing or accounting (logging, essentially) rather than security, but I hope you'll find it useful.

It's easy to lose track of when you last logged into a system, or indeed, when other users have. Thankfully, Bash offers a useful way of improving user auditing. You can log when users logged in (and from which IP address), as well as what commands they ran.

What if you want to look for users who log in to a server and then elevated their privileges to a more powerful user that isn't the superuser? (The system might already have a means for tracking superuser access through messages written to /var/log/messages, /var/log/auth.log, /var/log/syslog or other files.) The ever-friendly Bash allows you to insert a simple command to enhance your auditing of all users.

In conjunction with the last | less command, it's perfectly possible to trace back who has been logging in to your system when and which commands were run. Or, maybe you spent a morning trying to get something working and found that you had indeed fixed it at a certain time from timestamp information held in another log file, and decided that you want to cross-reference the two files?

Enter the history command in Bash, which lists the history of past Bash commands. history is hardly a well-kept secret, but many users aren't aware that you can add timestamp information to the history command. Add the following line to your hungry .bashrc file:

export HISTTIMEFORMAT="%h/%d - %H:%M:%S "

Next, you could simply reload or refresh your shell with the command mentioned earlier from within your home directory:

# . .bashrc

Now if you type history, you'll see an output of times and dates, something like the following:


Don't be alarmed if you see some initial timestamps that are all the same (they'll show today's date and time), because the timestamp information for previous commands isn't retrospectively stored when you restart Bash. Try entering a few new commands to see if the command is working.

Displaying the time along with the command will make it much easier to look up when a command that caused a particular server symptom happened so you can correlate the event with later symptoms that turn up in other logs.

The shopping list format history displays is actually written to the .bash_history file in the good old Unix epoch timestamp format (1608004274 as I write) and then automagically converted into human-readable format by the history command.

Less Is More

When running the last and history commands, I usually prefer to pipe the output into less so I can easily move from the top to the bottom of the output and also search proficiently. The less command displays the output one page at a time. You can quit with a lowercase q (the entered commands sit bottom left), or search with a question mark followed by a search term.

You can also move to the top or the bottom of text by using the angular brackets < and >, respectively.

The last command has been around for several years, and it also provides a number of other details separate to just timestamps, such as the originating IP address of the login, the type of terminal, and whether the user is still logged in.

Those eagle-eyed among us might also spot the fact that the last command offers some interesting uptime information – it can tell you when the last reboot or shutdown was. From what I remember, different versions, possibly on differing operating systems, provide slightly different outputs, so your mileage may vary.

In addition to the highly efficacious HISTORY timestamp config option (which you can configure to provide a number of different options), you'll find a few other useful enhancements within Bash that you might not have stumbled across on your travels.

For example, you can set the size of the .bash_history file:

export HISTSIZE=1000
export HISTFILESIZE=1000

Also, you might have noticed that the output of the history command includes a number to the left of each command. If you run the history command and take note of the number for a command you wish to repeat, you can re-run that command by prepending an exclamation mark, such as:

# !321

Although this trick is undoubtedly useful, especially for long commands, be warned that it's very easy to get the numbers wrong, and running the wrong command, especially as root, can sometimes be devastating.

Serious Stuff

Now a slightly more serious note. This note might apply more to sys admins looking after very busy servers with thousands of login users, or possibly those looking after servers in what might be considered a relatively hostile environment, such as shared public hosting.

The Bash history command is quite useful, but clearly it is far from ideal that a user can delete or alter the .bash_history file after trying to compromise a local/remote server or partake in some other illegal activity.

Veterans describe a simple fix, which ostensibly looks pretty solid, but admittedly, I haven't put it through its paces on many production servers so use this with care. The fix is the chattr command. On my Debian server, chatrr is described as being used to "change file attributes on a Linux file system."

You can use the mighty chattr command to change the attributes to only allow the user to append to the .bash_history file, as opposed to deleting or editing it.

You need to elevate your privileges to root, and rather than globally adding this command to every user's .bash_history files, you might want to test it on one user first with something like:

# chattr +a ~chrisbinnie/.bash_history

If you're feeling brave, this command might save you time – again, use it with care especially as root; it changes every user's .bash_history file attributes:

# find / -maxdepth 5 | grep -i .bash_history | \
  while read user; do chattr +a "$user"; done

For safety, you can always print which files you're going to change first before running the command:

# find / -maxdepth 5 | grep -i .bash_history | \
  while read user; do echo "$user"; done

If you decide you don't like limiting the ability for users to edit that file, you can simply remove the "append only" attribute using a minus instead of a plus sign before the a (as root):

# chattr -a ~chrisbinnie/.bash_history

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus