Paranoid Penguin - Linux Filesystem Security, Part I
For most of the Paranoid Penguin's illustrious four years with Linux Journal, I've tended to write tools-focused columns. I've described how to secure Sendmail, how to add SSL encryption to things by using Stunnel and how to get any number of other powerful security software tools configured and running.
Over the next couple of columns, however, I am going to address one of the most basic and important, yet often-overlooked aspects of Linux security; filesystem permissions. If used wisely, it will be harder for users and intruders to abuse their system privileges. If you set them carelessly, however, minor vulnerabilities can lead to major system compromises.
These articles should be especially useful to Linux newcomers who wonder what all the drwxr-xr-x gobbledygook in file listings means. But, even if you're an intermediate user—perhaps the kind who doesn't yet understand the precise ramifications of setuid and setgid—these articles, especially Part II, may have something for you too.
Did you know that in UNIX and UNIX-like systems, basically everything is represented by files? Documents, pictures and even executable programs are easy to conceptualize as files on your hard disk. Although we think of a directory as a container of files, a directory actually is a file containing, you guessed it, a list of other files.
Similarly, the CD-ROM drive attached to your system seems tangible enough, but to your Linux kernel, it too is a file—the special device file /dev/cdrom. To send data from it or to write it to the CD-ROM drive, the kernel actually reads to and writes from this special file. Actually, on most systems, /dev/cdrom is a symbolic link to /dev/hdb or some other special file. And wouldn't you know it, a symbolic link is in turn nothing more than a file containing the location of another file.
Other special files, such as named pipes, act as input/output (I/O) conduits, allowing one process or program to pass data to another.
My point here is not to describe each and every type of file that exists in Linux or UNIX. It's to illustrate how nearly everything is represented by a file. Once you understand this, it's much easier to understand why filesystem security is such a big deal and how it works.
Commands and Man Pages
In this article, I focus on filesystem concepts rather than the precise syntax and usage of actual commands. But if you're a beginner, you may be wondering how to execute commands at all and where can you find syntax/usage help.
First, in all of my examples and example scenarios, I'm working in a terminal window. Microsoft Windows users can think of a terminal as like a DOS prompt or command window. A terminal window provides the most direct means of interacting with Linux, that is, by letting you enter all your commands manually rather than by triggering them with mouse clicks.
To start your own shell session from GNOME, click the Main Menu button and select System Tools→Terminal. In KDE, the terminal command is called konsole, and it has its own icon on the taskbar, a clamshell in front of a computer screen. Alternatively, you can start the Run Program dialog and type konsole at the prompt.
For fast help with practically any Linux command from within a terminal/shell session, you can type that command followed by the --help option. For example, if I can't remember all the command-line options for the ls command, which lists files and directories, I enter the command ls --help.
The --help option is quick, but it doesn't work for all commands. Even when it does work, its output can be quite terse. The best way to get command help is by using the man command. Man pages provide complete instructions on how to use most Linux commands and are present on practically all UNIX-like systems. To see the man page for the ls command, for example, type the command man ls. Within the man page listing, press the spacebar to advance forward one page, the B key to go back one page and type /somestring to search the man page for somestring.
But, what if you don't know the name of the command you need? That's what apropos is for. For example, type apropos list to see a variety of commands that list things, and then pull up a man page for whichever of those commands seem to be what you need.
Actually, two things on a Linux system aren't represented by files, user accounts and group accounts, which we call users and groups for short. Various files contain information about a system's users and groups, but none of those files actually represents them. A user account represents someone or something capable of using files. This is to say, both human beings and system processes can use user accounts. For example, a user account named webmaster typically represents a human being who maintains Web sites. But the standard Linux user account lp is used by the line printer dæmon (lpd); the lpd program runs as the user lp. I explain later what it means for a program to run as one user vs. another.
A group account simply is a list of user accounts. Each user account is defined with a main group membership but may in fact belong to as many groups as needed. For example, the user maestro may have a main group membership in conductors and also belong to pianists.
A user's main group membership is specified in the user account's entry in /etc/password. You can add that user to additional groups by editing /etc/group and adding the user name to the end of the entry for each group to which the user should belong. Alternatively, you could use the usermod command; see the usermod(8) man page for more information.
Listing 1 shows maestro's entry in the file /etc/password, and Listing 2 shows part of the corresponding /etc/group file.
Listing 1. An /etc/password Entry for the User maestro
maestro:x:200:100:Maestro Edward Hizzersands:/home/maestro:/bin/bash
Listing 2. Two /etc/group Entries
In Listing 1, we see that the first field contains the name of the user account, maestro. The second field (x) is a placeholder for maestro's password, which actually is stored in /etc/shadow. The third field shows maestro's numeric user ID, or uid; in this case it's 200. The fourth field shows the numeric group ID, or gid—in this case it's 100—of maestro's main group membership. The remaining fields specify a comment, maestro's home directory and maestro's default login shell.
In Listing 2, from /etc/group, each line simply contains a group name, a group password (usually unused—x is a placeholder), numeric group ID (gid) and a comma-delimited list of users with secondary memberships in the group. Thus, we see that the group conductors has a gid of 100, which corresponds to the gid specified as maestro's main group in Listing 1. We also see that the group pianists includes the user maestro, plus another named volodyia, as a secondary member.
The simplest way to modify /etc/password and /etc/group in order to create, modify and delete user accounts is by using the commands useradd, usermod and userdel, respectively. I'd rather concentrate here on concepts than command syntax, so suffice it to say that all three of these commands can be used to set and modify group memberships and all three commands are well documented in their respective man pages. To see a quick usage summary, you also can type the command followed by --help, for example, useradd --help.
Each file has two owners, a user and a group, each with its own set of permissions that specify what the user or group may do with the file—read it, write to it and execute it. A third set of permissions pertains to what others, user accounts that don't own the file or belong to the group that owns it, can do with the file. Listing 3 shows a long file listing for the file /home/maestro/baton_dealers.txt.
Listing 3: File Listing Showing Permissions
-rw-rw-r-- 1 maestro conductors 35414 Mar 25 01:38 baton_dealers.txt
Permissions are listed in the order of user permissions, group permissions and other permissions. For the file shown in Listing 3, its user owner (maestro) can read and write the file (rw-); its group owner (conductors) also can read and write the file (rw-), but other users can only read the file. Permissions are a little more complicated, however. Users classified as other, in terms of permissions on a particular file, can delete any file in a directory to which they have write permissions. In other words, users with read-only permission on a file cannot edit the file but can delete it if they have write permission on the file's directory.
There's a third permission besides read and write: execute, which is denoted by x when set. If maestro writes a shell script named punish_bassoonists.sh and if he sets its permissions to -rwxrw-r--, he then can execute this script by entering the name of the script at the command line. If, however, he forgets to set the execute permission, he is not able to run the script, even though he owns it.
Permissions and root
In practical terms, file permissions simply do not apply to the root user; root can do anything to any file, at any time. This is why it's so important never to log on as root or use the su command to become root, except when absolutely necessary. When you're root, file permissions do not protect you from your own mistakes.
This is not to say that all programs entirely disregard file permissions when you're root. If, for example, root tries to alter a read-only file using the vim editor, root must use the :w! command (force write). The normal ZZ or :w commands return an error in this case. However, many other commands have no such sanity-check feature.
Permissions usually are set with the chmod command, short for change mode. Continuing with our example, suppose maestro has second thoughts about allowing other members of the conductors group to read his list of baton dealers. He could remove the group read/write permissions using the commands shown in Listing 4.
Listing 4. Changing a File's Permissions with chmod
bash-$ ls -l baton_dealers.txt -rw-rw-r-- 1 maestro conductors 35414 Mar 25 01:38 baton_dealers.txt bash-$ chmod go-rw baton_dealers.txt bash-$ ls -l baton_dealers.txt -rw------- 1 maestro conductors 35414 Mar 25 01:38 baton_dealers.txt
In Listing 4's sample chmod command (chmod go-rw), go tells chmod to change the group permissions and other permissions; -rw says to remove read and write permissions for those two categories of permissions, group and other. Thus, a chmod command has three parts: a permission category, some combination of u, g and o or a for all; an operator, - to remove, + to add; and a list of permissions to add or remove, usually r, w or x.
We now know how to change basic permissions on regular files, but what about directories? Directory permissions work slightly differently from permissions on regular files. Read and write are similar; for directories these permissions translate to list the directory's contents and create or delete files within the directory, respectively.
Execute is a little less intuitive on directories, however. Here, execute translates to use anything within or change working directory to this directory. That is, if a user or group has execute permissions on a given directory, the user or group can list that directory's contents, read that directory's files (assuming those individual files' own permissions include this) and change the working directory to that directory with the command cd. If a user or group does not have execute permission on a given directory, the user or group is unable to list or read anything in it, regardless of the permissions set on the things inside. If you lack execute permission on a directory but do have read permission and you try to list its contents with ls, you receive an error message that, in fact, lists the directory's contents. But this doesn't work if you have neither read nor execute permissions on the directory.
Suppose our example system has a user named biff who belongs to the group drummers. Also suppose that his home directory contains a directory called extreme_casseroles that he wishes to share with his fellow percussionists. Listing 5 shows how biff might set that directory's permissions.
Listing 5. A Group-Readable Directory
bash-$ chmod g+rx extreme_casseroles bash-$ ls -l extreme_casseroles drwxr-x--- 8 biff drummers 288 Mar 25 01:38 extreme_casseroles
Per Listing 5, only biff has the ability to create, change or delete files inside extreme_casseroles. Other members of the group drummers can list its contents and cd to it. Everyone else on the system, however, is blocked from listing, reading, cd-ing or doing anything else with the directory.
Mick Bauer, CISSP, is Linux Journal's security editor and an IS security consultant in Minneapolis, Minnesota. He's the author of Building Secure Servers With Linux (O'Reilly & Associates, 2002).