A few minutes of preparation and planning ahead before putting your systems online can help to protect your system, and the data that is stored on it.
This section discusses some of the methods in which you can use to secure the files on your system, some general guidelines for improving the overall security of the files on your system, and some ideas for preventing problems from occuring in the first place. It also discusses the commands to use to modify the permissions and ownership of files and directories on your system.
Before we discuss some of these methods of improving file system security, it is important to have an understanding of basic Linux file security, ownership, and what each of the fields from a file listing actually mean.
To display the ownership and permissions of a file on your system, use the long-listing option, as well as the display all files option to the ls(1) command. A typical /bin/ls -la command might show the following, with the first line being a field marker:
|----1----|-2--|---3----|----4-----|---5--|-----6------|---7-----|
1. drwxrwxr-x 24 root users 1024 Aug 19 00:05 .
2. drwxr-xr-x 22 root root 1024 Aug 11 22:04 ..
3. drwxr-xr-x 3 root root 1024 Jun 19 03:40 Mail
4. -rw-rw-r-- 1 dave security 43244 Jul 20 14:11 README
5. drwxrwsr-x 17 dave security 1024 Jul 31 01:48 Security
[More not shown]
Each of these fields provide useful information to the security administrator. First, a description of each field (as shown from left to right), then a more in-depth explanation of the most important ones. The numbers down the left side represent the line numbers, which will be referred to later.
- Field One: Permissions for this file or directory. The first nine positions from the right describe the user, group, and other permissions, in groups of three. Within each group of three, the first character denotes read access, the second denotes write access, and the last denotes execute, working from left to right. The tenth position describes the type of file, which can be either a regular file, directory, FIFO, symbolic link, or other type of special file.
- Field Two: Number of hard links to this file or directory. These links can be directories, for example. In this case the current directory (line 1) most likely has 24 directories below it, of which only two are shown here (
Security and Mail)
- Field Three: Owner of the file or directory. This field is as important as the permissions themselves.
- Field Four: The group to which the file belongs. This field, in conjunction with the owner field (field three) are necessary in order to set the permissions correctly.
- Field Five: Size of file
- Field Six: Modification time
- Field Seven: File name
Continuing where we left off in the previous section, we can now discuss some of the fields described above. Particularly, field one and fields three and four are the most exiciting.
Linux separates access control on files and directories according to three characteristics: owner, group, and other. There is always exactly one owner, any number of members of the group, and everyone else.
The files within each of these categories have specific permissions with which they are accessed. File permissions, including regular files, special files (such as FIFOs, sockets, etc), or symbolic links (which dereference the permissions to the file they point to) can have any one, or any, of the following:
Symbol Permission Description
-------------------------------------------------------------------
r Read Can be opened to read the contents
w Write Can be modified, including appending
and deleting
x Execute Can execute the file if it is a
program or shell script
s Special Perm setuid or setgid permission
- Access Denied Cannot be read, written, or executed,
depending on the position of the `-'
The read, write, and execute permissions should be pretty clear as to their meaning. However, the ``s'' symbol may need to explanation. The next two sections address this symbol.
Set User Identification Attribute
When the set user ID access mode is set in the owner permissions, and the file is executable, processes which run it are granted access to system resources based on the owner of the file.
Be extremely careful when setting these permissions. Any user who runs that file assumes the permissions of the owner of the executable file, instead of the user who created the process. This is the cause of many ``buffer overflow'' exploits, typically resulting in superuser privileges.
The setuid permission is shown as an s in the file permissions. For example, the setuid permission on the /usr/bin/passwd command enables normal users to read and write an otherwise inaccessible /etc/passwd file:
user@myhost $ ls -l /etc/shadow /etc/passwd /usr/bin/passwd
-r-------- 1 root root 659 Jul 25 19:40 /etc/shadow
-rw-r--r-- 1 root root 711 Jul 25 19:40 /etc/passwd
-r-sr-xr-x 1 root bin 15613 Apr 27 12:29 /usr/bin/passwd
You will notice that the s takes the place of the execute bit in the example above. This special permission mode really has no meaning unless the file also has execute permission as well.
In the example we see the /etc/shadow file is only readable by root, yet the /usr/bin/passwd file enables us to write our password changes there. When either a normal user, a member of the bin group, or even anyone else executes /usr/bin/passwd, it is really run as root, due to the ``s'' bit set in the owner's permissions field.
Keep in mind that setuid has a different meaning when applied to directories. See the explanation for directories that follows.
It is advisable to keep setuid and setgid binaries on your system to a minimum, in order to reduce the possiblity of their being exploited. You should never execute an suid or sgid binary as a normal user, without knowing what it does. And certainly do not arbitrarily modify an otherwise non-setuid binary to have setuid permissions, simply for convience.
Set Group Identification Attribute
If set in the group permissions, this bit controls the ``set group ID'' status of a file. This behaves the same way as setuid, except the group is affected instead. The file must also be executable for this to have any effect. Upon execution of a file with this bit set, the effective group ID for the process is changed to the group owner of the file and a user is granted access based on the permissions given to that group. The wall(1) program, /usr/bin/wall, is used to ``write all'' users that are logged on to the system at the same time. It must be set group ID in order to have enough permission to write to terminals which do not belong to the user running the program:
user@myhost$ ls -l /usr/bin/wall
-r-xr-sr-x 1 root tty 5492 May 7 14:02 /usr/bin/wall
We see here that everyone has the ability to execute the binary. It is owned by
root, and a member of the
tty group. Having each user on the system a member of the
tty is not practical, and neither is changing the group to which the wall program belongs.
It is advisable to keep setuid and setgid binaries on your system to a minimum, in order to reduce the possiblity of their being exploited. You should never execute an suid or sgid binary as a normal user, without knowing what it does. And certainly do not arbitrarily modify an otherwise non-setuid binary to have setuid permissions, simply for convience.
Keep in mind that setgid has a different meaning when applied to directories. See the explanation for directories that follows.
You can protect the files in a directory, and its subdirectories, by denying access to the entire directory itself. The permissions of a directory typically have a slightly different meaning than the equivilent permissions on a file. Additional permissions are available on directories, including setuid, setgid, and the sticky bit. Directory entries can have any one, or any, of the following:
Symbol Permission Description
---------------------------------------------------------------------
r Read List file contents
w Write Add, modify or remove files in the
directory
x Execute Open or execute files in the directory
- Access Denied Cannot be read, written, or executed,
depending on the position of the `-'
s Special Mode Set group ID bit is active (only in
``group'' section
t Special Mode Save text attribute
It is important to understand the meanings of each of these symbols, and how you can use them to protect your files. Many of these symbols may be clear as to its meaning, but perhaps the other modes deserve a more in-depth explanation.
The read symbol indicates the ability to list the contents within the directory, assuming you also have access to open the directory.
The write symbol indicates the ability to add, remove, or modify files within the directory, also assuming you have access to open the directory. It is important to note that write access on a file within a directory is not required to delete it!
Save Text Attribute (Sticky Bit)
The Save Text (also known as the sticky bit) is an option really only available to directories. If the sticky bit is set on a directory, then a user may only delete files that the user owns or for which he has explicit write permission granted, even when he has write access to the directory. This is designed for directories which are world-writable, but where it may not be desirable to allow any user to delete files at will. The sticky bit is seen as a ``t'' in a long directory listing.
For example, the /tmp directory is typically world-writable, so everyone has a place in which to write temporary files. The /tmp directory looks like this in a long-listing:
user@myhost$ ls -ld /tmp
drwxrwxrwt 3 root root 2048 Aug 23 16:25 /tmp
This shows that everyone can read, write, and access the directory. But the ``
t'' shows us that only the user (and root, of course) that created a file there can delete that file.
The chmod(1) command controls the sticky bit permissions. For example, you can add the sticky bit to a directory using the following:
root@myhost# ls -ld spool
drwxrwxrwx 3 root root 2048 Aug 23 16:25 spool
root@myhost# chmod +t spool
root@myhost# ls -ld spool
drwxrwxrwt 3 root root 2048 Aug 23 16:25 spool
While you can use the sticky bit on files, it does not really serve a purpose on Linux systems, as it did on UNIX systems of yester-year.
Additionally, this option should not be used casually. Instead, create a directory in the user's home directory to which he or she can write temporary files. The TMPDIR environment variable can be set, and programs that use the tempnam(3) system call will look for this variable and use it, instead of /tmp See the section on Writing Secure Code for a further explanation why there are hidden security problems with /tmp
Set Group Identification Attribute
If you set the setgid bit on a directory, files created in that directory will have the same group ownership as the directory itself, rather than the primary group of the user that created the file.
This attribute is useful when multiple users need to access specific files, but still require isolation from other files. Having them work from a common directory with the setgid attribute set means that any files created there will obtain the permissions of that common directory. For example, Joe and Mary might be in different primary groups, but need to collaborate on a common project. In this case, creating a common directory can be used to which both have write access.
You can control the setgid attribute on a directory with the following command:
joe@myhost$ ls -ld common_dir
drwxrwxr-x 2 joe dev 1024 Aug 23 17:03 common_dir
joe@myhost$ chmod g+s common_dir
joe@myhost$ ls -ld common_dir
drwxrwsr-x 2 joe dev 1024 Aug 23 17:03 common_dir
We can see here that the ``
s'' in place of the execute bit in the group permissions indicates all files written to the
common_dir will now belong to group
dev
The chmod(1) command controls the changing of file and directory permissions. Only the owner (or superuser, of course) can change the permissions of a file or directory.
The chmod(1) command has two modes of operation. The first one, called absolute mode, works by explictly specifying the permissions using an octal value, such as 644 or 755. The second mode of operation, called symbolic mode, works by using combinations of letters and symbols to add or remove permissions.
Using the octal values method of changing permissions can be more difficult to use at first, but you'll find it is faster and easier, once you have made the inital time investment, and learned how to do it correctly.
Changing File Permissions Using Octal Values (Absolute Mode)
The octal value for specifying permissions works by specifying a numeric argument for the permissions for which you wish to change. These numbers are used in sets of three to set permissions for owner, group, and other (everyone else). The following table shows what each octal value means:
Value Permissions Description
---------------------------------------------------------------------
0 --- No permission
1 --x Execute only
2 -w- Write only
3 -wx Write and execute (shell scripts need
read permission to be executed)
4 r-- Read only
5 r-x Read and execute
6 rw- Read and write
7 rwx Read, write, and execute (full
control)
Using the table above, you can use chmod(1) to modify file and directory permissions. It helps to disect each of the sections, and explain one at a time. Given the following example:
user@myhost$ ls -l
-rwxrw-r-- 1 dave sysadmin 36012 Aug 21 01:06 run.pl
We see from this example that dave is the owner, and the file belongs to group sysadmin. From the information in the first field, we see this is a normal file, as shown by the - as the left-most character in the left-most field. The owner of this perl script, dave, has permission to read, write, and execute this file. The group, sysadmin has permission to read and write to it (including deleting it). Everyone else can only read this file. Using that information, we can look more closely at the permissions that file has:
Access Class user group other
Symbolic Mode r w x r w - r - -
Binary Mode 1 1 1 1 1 0 1 0 0
Octal Equiv 7 6 4
The octal equivilent of the binary number is generated using powers of two. Each position that is enabled, as shown by a 1 instead of a 0, represents a power of two. Specifically, from right to left, we have 2^0, or 1, then 2^1, or 2, then 2^2, or 4. Adding the enabled values corresponding to the bits that are enabled gives the octal number we use with chmod(1).
One might decide to remove the ability for other to read this file. You can do this using chmod(1) as follows:
user@myhost$ ls -l run.pl
-rwxrw-r-- 1 dave sysadmin 36012 Aug 21 01:06 run.pl
user@myhost$ chmod 760 run.pl
user@myhost$ ls -l run.pl
-rwxrw---- 1 dave sysadmin 36012 Aug 21 01:06 run.pl
We see here that run.pl has now been modified to deny read access (as well as all other types of access) to users other than those in group sysadmin, and the owner (dave in this case)
Changing Directory Permissions Using Octal Values (Absolute Mode)
Using the same format as used to describe file permissions shown above, we will continue, and explain how changing directory permissions using octal values work.
The octal value for specifying permissions works by specifying a numeric argument for the permissions for which you wish to change. These numbers are used in sets of three to set permissions for owner, group, and other (everyone else).
The primary difference between permissions on files and permissions on directories is access control. Permissions on directories typically indicate accessibility. Hint: You cannot execute a directory ;->
The following table shows what each octal value means, as well as what access control is given for the corresponding permissions:
Value Permissions Description
---------------------------------------------------------------------
0 --- No permission
1 --x Access - gives ability to work with programs
and files in the directory that they already
know the name of, but hides all others
2 -w- Write - really has no meaning on its own
3 -wx Write and execute - ability to write to files
you already know the name of
4 r-- Read only - really has no meaning on its own
5 r-x Read and execute - gives ability to enter
directory, and list contents, but cannot write
or delete
6 rw- Read and write - really has no meaning on its
own
7 rwx Read, write, and access - ability to list
contents of directory, as well as read and
write in it
Using the table above, you can use chmod(1) to modify file and directory permissions. It helps to disect each of the sections, and explain one at a time. Given the following example:
user@myhost$ ls -l
drwxr-x--- 1 dave sysadmin 1024 Aug 21 01:06 games
We see from this example that dave is the owner, and the directory belongs to group sysadmin. From the information in the first field, we see this is a directory, as shown by the d as the left-most character in the left-most field. The owner of this directory, dave, has permission to read, write, and access this directory. The group, sysadmin has permission to access the directory, as well as list its contents. Files within this directory with the appropriate read permission would also be able to be read. Other users are not allowed to access this directory at all. Using that information, we can look more closely at the permissions that directory has:
Access Class User Group Other
Symbolic Mode r w x r - x - - -
Binary Mode 1 1 1 1 0 1 0 0 0
Octal Equivilent 7 5 0
The octal equivilent of the binary number is generated using powers of two. Each position that is enabled, as shown by a 1 instead of a 0, represents a power of two. Specifically, from right to left, we have 2^0, or 1, then 2^1, or 2, then 2^2, or 4. Adding the enabled values corresponding to the bits that are enabled gives the octal number we use with chmod(1).
One might decide to give other users the ability for other to access this file, and list the contents within it. You can do this using chmod(1) as follows:
user@myhost$ ls -ld games
drwxr-x--- 1 dave sysadmin 1024 Aug 21 01:06 games
user@myhost$ chmod 755 games
user@myhost$ ls -ld games
drwxr-xr-x 1 dave sysadmin 1024 Aug 21 01:06 games
We see here that games has now been modified to permit access to users other than those in group sysadmin, and the owner (dave in this case)
Changing Permissions Using Symbols (Symbolic Mode)
The symbolic mode is perhaps the easier of the two methods to use to change file permissions. It is probably the one you should work with first if you are just learning this. This section discusses the basic means in which one can change the permissions of a file or directory, using chmod(1)
The symbolic mode of chmod(1) works on the concept of access classes. These classes consist of (u)ser, which is the owner of the file, (g)roup, of which the user is a member, and (o)ther, which is those users not a member of the group, or the owner of the file. The final mode is (a)ll, which consists of all three of the previous modes.
Using these modes, in conjunction with the desired permissions, you can modify the access to a particular file or directory. The permissions are one or more of (r)ead, (w)rite, and e(x)ecute.
Combining the access class and the new permissions desired, with an operator, gives you the ability to change the permissions on a file or directory. The available operators are +, which means to add to the existing permissions, -, which means to subtract from the existing permissions, and =, which means set the new permissions equal to those provided.
For example, ``a+rw'' means to add read and write permission to all three groups of users. Using ``go=r'' means to set the group and other fields to only have read access, regardless of what they had previously.
A more complete example is as follows:
dave@myhost$ ls -l nsmail
drwxr-xr-x 2 dave dave 1024 Aug 7 00:17 nsmail
dave@myhost$ chmod go=rx nsmail
dave@myhost$ ls -l nsmail
drwx------ 2 dave dave 1024 Aug 7 00:17 nsmail
To remove write access for everyone from a file, use the minus sign:
dave@myhost$ chmod a-w myfile
dave@myhost$ ls -l myfile
-r--r--r-- 1 dave dave 424 Aug 23 23:10 myfile
You can control the setuid and setgid on files and directories, as well as the sticky bit, using the symbolic mode with chmod(1). Such an example might be as follows:
1. root@myhost# ls -l
2. drwxr-xr-x 2 root sysadmin 1024 Aug 24 01:18 groupdir
3. -rwxr-x--- 1 root sysadmin 8077 Aug 24 01:19 myprog
4. drwxr-xr-x 2 root root 1024 Aug 24 01:18 spool
5. root@myhost# chmod g+ws groupdir
6. root@myhost# chmod u+s myprog
7. root@myhost# chmod o+t,a+w spool
8. root@myhost# ls -l
9. drwxrwsr-x 2 root sysadmin 1024 Aug 24 01:18 groupdir
10. -rwsr-x--- 1 root sysadmin 8077 Aug 24 01:19 myprog
11. drwxrwxrwt 2 root root 1024 Aug 24 01:18 spool
This is an interesting example which uses many of the features of chmod(1). Lines 1 through 4 show the long-list of the file and two directories before any changes were made. We see here that groupdir and myprog are members of group sysadmin. Another point of interest is that no one but the owner of these files (root in all these cases) is able to write to the file or directories.
Line 5 shows how to add both group write permission, and setgid access to the groupdir directory. This will enable members of group sysadmin to write files there, and retain the sysadmin group.
Line 6 shows how to add the setuid bit to the myprog binary. This means that any user in the sysadmin group that executes this binary is granted access based on the owner of the file, in this case root, rather than the user who executed it.
Line 7 shows how to add the sticky bit to the spool directory, as well as add write permission for all users. This is a publicy-accessible directory, and writable by all. However, only those who actually own the files can delete them.
Lines 8 through 11 show the directories and file after the modifications have been made.
This section discusses the methods in which an administrator can change the owner and group to which a file belongs. Use the chown(1) command to change a files owner (can only be done by root), and chgrp to change the group to which a file or directory belongs.
As with any security-related task, you should use caution when changing the ownership of a file or directory. Most times you can add a user to a group without having to change the ownership. You should also re-evaluate the permissions of the file or directory after you have made the change.
To use the chown(1), supply the new username and the files you wish to change:
root@myhost# ls -l myfile
-r--r--r-- 1 fred sysadmin 424 Aug 23 23:10 myfile
root@myhost# chown root myfile
root@myhost# ls -l myfile
-r--r--r-- 1 root sysadmin 424 Aug 23 23:10 myfile
You can also change ownership of files recursively by using the chown -R option. When you use the -R option, the chown command descends through the directory and any subdirectories below that one, changing the ownership.
If a symbolic link is encountered, the group ownership is changed on the file to which the link points.
This section is very similiar to the previous section. It discusses the methods in which an administrator can change the groups to which a file belongs. Use the chgrp(1) command to change group ownership. In order for a normal user to change a file's group from one to another, the user must be a member of both groups.
To use the chgrp(1), supply the new group name and the files you wish to change:
root@myhost# ls -l myfile
-r--r--r-- 1 fred sysadmin 424 Aug 23 23:10 myfile
root@myhost# chgrp root myfile
root@myhost# ls -l myfile
-r--r--r-- 1 fred root 424 Aug 23 23:10 myfile
You can also change group ownership of files recursively by using the chgrp -R option. When you use the -R option, the chgrp command descends through the directory and any subdirectories below that one, changing the ownership.
You can also use the chown(1) command to change both the owner and group at the same time. Use a colon between the desired new owner and group. For example:
root@myhost# ls -l myfile
-r--r--r-- 1 fred sysadmin 424 Aug 23 23:10 myfile
root@myhost# chown root:root myfile
root@myhost# ls -l myfile
-r--r--r-- 1 root root 424 Aug 23 23:10 myfile
Notice the permissions do not change simply because you have changed the ownership. Use caution here to be sure you are not inadvertantly giving permission to someone that should not have it.
If a symbolic link is encountered, the group ownership is changed on the file to which the link points.
The umask command can be used to determine the default file creation mode on your system. It is the octal complement of the desired file mode. If files are created without any regard to their permissions settings, a user could inadvertently give read or write permission to someone that should not have this permission.
The umask for the creation of new executable files is calculated as follows:
777 Default Permissions
-022 Subtract umask value, for example
-----
755 Allowed Permissions
So in this example we chose 022 as our umask. This shows us that new executables that are created are given mode 755, which means that the owner can read, write, and execute the binary, while members of the group to which the binary belongs, and all others, can only read and execute it.
The umask for the creation of new text files is calculated as follows:
666 Default Permissions
-022 Subtract umask mask, for example
-----
644 Allowed Permissions
This example shows us that given the default umask of 666, and subtracting our sample umask value of 022, new text files are created with mode 644, which states that the owner can read and write the file, while members of the group to which the file belongs, and everyone else can only read the new file.
Typically umask settings include 022, 027, and 077, which is the most restrictive. Normally the umask is set in /etc/profile, so it applies to all users on the system. The file creation mask must be set while keeping in mind the purpose of the account. Permissions that are too restrictive may cause users to start sharing accounts or passwords, or otherwise compromise security. For example, you may have a line that looks like this:
# Set the user's default umask
umask 033
Be sure to make root's umask to at least 022, which will disable write and execute permission for other users, unless explicitly changed using chmod(1).
If you are using Red Hat Linux, and adhered to their user and group ID creation scheme (User Private Groups), it is only necessary to use 002 for a umask with normal users. This is due to the fact that the default configuration is one user per group.
In addition to setting the user's default umask, you should be sure you are aware of the umask value that is set in startup scripts as well. Any files that are created during the boot process may be created with the default umask of 666 if it is not explictly specified.
Additionally, any servers that are started at boot time, such as inetd(8), may inherit the umask at boot time, which in turn will be passed down to the services, and servers, that it controls.
The umask value that the FTP server, spawned by inetd(8) uses, for example, can be easily overlooked, allowing the potential for too lenient permissions on files.
In this specific example, the FTP server has command-line options for controlling umask values. Many do not, however. For this reason, you might consider creating a file that gets run at system boot time, before any others, that simply explictly sets the umask to a known value.
You should regularly monitor your systems for any unauthorized use of the setuid or setgid permissions to gain superuser privileges.
setuid and setgid files on your system are a potential security risk, and should be monitored closely. Because these programs grant special privileges to the user who is executing them, it is necessary to ensure that insecure programs are not installed. A favorite trick of crackers is to exploit ``setuid root'' programs, then leave a setuid program as a back door to get in the next time, even if the original hole is plugged.
Find all setuid and setgid programs on your system, and keep track of what they are, so you are aware of any changes which could indicate a potential intruder. Use the following command to find all setuid and setgid programs on your system:
root@myhost# find / -type f -perm +6000 -ls
You can discriminately remove the setuid or setgid permissions on a suspicious program with chmod(1), then change it back if you absolutely feel it is necessary.
World-writable files, particularly system files, can be a security hole if a cracker gains access to your system and modifies them. Additionally, world-writable directories are dangerous, since they allow a cracker to add or delete files as he wishes. To locate all world-writable files on your system, use the following command:
root@myhost# find / -perm -2 ! -type l -ls
and be sure you know why those files are writable. In the normal course of operation, several files will be writable, including some from
/dev.
Unowned files may also be an indication an intruder has accessed your system. You can locate files on your system that do not have an owner, or belong to a group with the command:
root@myhost# find / -nouser -o -nogroup
The following is a list of general guidelines you should be aware of when configuring the files on your hosts.
Finally, before changing permissions on any system files, make sure you understand what you are doing. Never change permissions on a file because it seems like the easy way to get things working. Always determine why the file has that permission before changing it. And removing permissions from files is typically a good idea, but it is not always practical. Change permissions slowly, and watch carefully for undesired results.