SSH can help secure a truly staggering variety of administrative tasks. I'd be remiss, however, not to mention two other tools useful for this purpose. These tools, su and sudo, can help minimize the time you spend logged on as or operating with root privileges.
Many new Linux users, possibly because they often run single-user systems, fall into the habit of frequently logging in as root. But it's bad practice to log in as root in any context other than direct console access (and even then it's a bad habit to get into, since it will be harder to resist in other contexts). There are several reasons why this is so:
Although the whole point of SSH is to make eavesdropping unfeasible, if not impossible, there have been a couple of nearly feasible man-in-the-middle attacks over the years. Never assume you're invincible: if some day someone finds some subtle flaw in the SSH protocol or software you're using and successfully reconstructs one of your sessions, you'll feel pretty stupid if in that session you logged in as root and unknowingly exposing your superuser password, simply in order to do something trivial like browsing apache logs.
In the hyperabbreviated world of Unix, typing errors can be deadly. The less time you spend logged in as root, the less likely you'll accidentally erase an entire volume by typing one too many forward slashes in an rm command.
This book is about bastion hosts, which tend to not have very many local user accounts. Still, if a system cracker compromises an unprivileged account, they will probably use it as a foothold to try to compromise root too, which may be harder for them to do if you seldom log in as root.
You're probably familiar with su, which lets you escalate your privileges to root when needed and demote yourself back down to a normal user when you're done with administrative tasks. This is a simple and excellent way to avoid logging in as root, and you probably do it already.
Many people, however, aren't aware that it's possible to use su to execute single commands rather than entire shell sessions. This is achieved with the -c flag. For example, suppose I'm logged in as mick but want to check the status of the local Ethernet interface (which normally only root can do). See Example 4-10 for this scenario.
[mick@kolach mick]$ su -c "ifconfig eth0" - Password: (superuser password entered here) eth0 Link encap:Ethernet HWaddr 00:10:C3:FE:99:08 inet addr:192.168.201.201 Bcast:192.168.201.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:989074 errors:0 dropped:0 overruns:0 frame:129 TX packets:574922 errors:0 dropped:0 overruns:0 carrier:0 [mick@kolach mick]$
If logging in as an unprivileged user via SSH and only occasionally su-ing to root is admirable paranoia, then doing that but using su for single commands is doubly so.
su is part of every flavor of Linux ? indeed, every flavor of Unix, period. But it's a little limited: to run a shell or command as another user, su requires you to enter that user's password and essentially become that user (albeit temporarily). But there's an even better command you can use, one that probably isn't part of your distribution's core installation but probably is somewhere on its CDROM: sudo, the "superuser do." (If for some reason your Linux of choice doesn't have its own sudo package, sudo's latest source-code package is available at http://www.courtesan.com/sudo/.)
sudo lets you run a specific privileged command without actually becoming root, even temporarily. Unlike with su -c, authority can thus be delegated without having to share the root password. Let's transpose Example 4-11 into a sudo scenario.
[mick@kolach mick]$ sudo ifconfig eth0 We trust you have received the usual lecture from the local System Administrator. It usually boils down to these two things: #1) Respect the privacy of others. #2) Think before you type. Password: (mick's password entered here) eth0 Link encap:Ethernet HWaddr 00:10:C3:FE:99:08 inet addr:192.168.201.201 Bcast:192.168.201.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:989074 errors:0 dropped:0 overruns:0 frame:129 TX packets:574922 errors:0 dropped:0 overruns:0 carrier:0 collisions:34 txqueuelen:100 Interrupt:3 Base address:0x290 Memory:d0000-d4000 [mick@kolach mick]$
Just like with su -c, we started out as mick and ended up as mick again. Unlike with su -c, we didn't have to be root while running ifconfig. This is very cool, and it's the way true paranoiacs prefer to operate.
Less cool, however, is the fact that sudo requires some manpage look-ups to configure properly (in most people's cases, many manpage look-ups). This is due to sudo's flexibility. (Remember what I said about flexibility bringing complexity?)
I'll save you the first couple of manpage look-ups by showing and dissecting the two-line configuration file needed to achieve Example 4-11 ? i.e., setting up a single user to run a single command as root. The file in question is /etc/sudoers, but you don't really need to remember this, since you aren't supposed to edit it directly anyhow: you need to run the command visudo. visudo looks and behaves (and basically is) vi, but before allowing you to save your work, it checks the new sudoers file for syntax errors (see Example 4-12).
# sudoers file. # # This file MUST be edited with the 'visudo' command as root. # See the sudoers manpage for the details on how to write a sudoers file. # # Host, User, and Cmnd alias specifications not used in this example, # but if you use sudo for more than one command for one user you'll want # some aliases defined [mdb] # User privilege specification root ALL=(root) ALL mick ALL=(root) /sbin/ifconfig
The last two lines in Example 4-12 are the ones that matter. The first translates to "root may, on all systems, run as root any command." The second line is the one we'll dissect.
Each sudoers line begins with the user to whom you wish to grant temporary privileges ? in this case, mick. Next comes the name of the system(s) on which the user will have these privileges ? in this example, ALL (you can use a single sudoers file across multiple systems). Following an = sign is the name, in parentheses, of the account under whose authority the user may act, root. Finally comes the command the user may execute, /sbin/ifconfig.
It's extremely important that the command's full path be given; in fact, visudo won't let you specify a command without its full path. Otherwise, it would be possible for a mischievous user to copy a forbidden command to their home directory, change its name to that of a command sudo lets them execute, and thus run rampant on your system.
Note also that in Example 4-12, no flags follow the command, so mick may execute /sbin/ifconfig with whichever flags mick desires, which is of course fine with me, since mick and root are one and the same person. If/when you use sudo to delegate authority in addition to minimizing your own use of root privileges, you'll probably want to specify command flags.
For example, if I were root but not jeeves, (e.g., root=me, jeeves=one of my minions), I might want this much-less-trustworthy jeeves to view but not change network-interface settings. In that case, the last line of Example 4-12 would look like this:
jeeves ALL=(root) /sbin/ifconfig -a
This sort of granular delegation is highly recommended if you use sudo for privilege delegation: the more unnecessary privilege you grant nonroot accounts, the less sudo is actually doing for you.
That's as far as we're going to go here in exploring sudo, though, since my main angle is remote administration and the intelligent execution thereof. In summary: be sneaky when administering Linux servers, and, whenever possible, don't be root while you're doing it.