Practical Guide to Software Quality Management (Artech House Computing Library)
< Day Day Up > |
Granting users and administrators rights on the system is a deceptively easy task, and one of the most basic facing the system administrator. Controlling system access, begins with basic Unix accounts, group membership, and file permissions. Recent additions such as ACLs and mandatory access controls in FreeBSD can make managing access quite complicated. Take a little time to think about the design of your access control systems to ensure you have granted the access needed, without sacrificing security. 4.1.1. Controlling User Access
Users fall into several categories, depending on the system involved. Generally, only administrators have accounts on infrastructure systems and in higher security environments, only administrators responsible for the service that system provides. Add developers to the list of allowed users and you have a workgroup system. Traditionally, local user accounts represent two classes of users: those who have shell accounts on the system, and service users. Service users don't usually need a valid shell (they do not log in) but do have an associated group. The user and group named on an OpenBSD system (BIND in FreeBSD), for example, allows the DNS server to run as someone other than root. In this case there is no human being associated with the user and it should stay this way. Do not set a password and shell for system users or use the account as an administrative one. It is permissible, however, to add DNS administrators to the named group for the purposes of administering nameserver configuration files without needing privileged access.
Infrastructure systems should provide shell access only to administrators; therefore these systems require few user accounts and groups beyond the system defaults. Workgroup systems, however, benefit from careful user and group planning before the creation of the first user account. Most Unix users are familiar with the user/group/other permissions model found in most Unix operating systems. OpenBSD and FreeBSD continue to provide this basic access control functionality by user and group membership. Granting access by group is fairly flexible in that you are able to control access by moving users into and out of groups instead of changing the permissions of files and directories. Thus group permissions are often used more than user permissions for controlling access to data. As such, how you allocate users to primary groups is a very important decision. There are three typical approaches: using a catch-all primary group, using project-based primary groups, and using per-user groups. We favor the last approach, as you'll see. 4.1.1.1 Using a catchall primary group
One way to organize users into groups involves creating one group for all users (e.g. users) and placing all users into this group. Create additional groups on a per-project or role basis and assign users to these secondary groups for finer grain access control. This paradigm suffers one conceptual drawback: the users group is almost equivalent to world permissions because this group contains all users. In addition, files created by users will be group-owned by the users group and, depending on the user's umask, may be group readable by default. The key difference between world permissions and a catchall users group is that system users like nobody, sshd, and so on will not be in the users group you create. This is a good thing. User accounts used by system daemons should be granted minimal access to files and directories on the system. 4.1.1.2 Project-based or role-based primary groups
Project-based or role-based groups as primary groups also allow for effective access control. This method, like the method described above, fails to cover one scenario. There is no way to add users without automatically giving them access to some subset of data already present on the system. In environments where contractors or guest users are periodically given user accounts, this can pose a problem. 4.1.1.3 Per-user groups
Per-user groups are one way around this drawback, and this solution fits in well with the least-privilege paradigm. In this scenario, you create a new group every time you create a new user; thus there is a one-to-one mapping of users to groups. Following this strategy, users do not automatically have access to any data when they first log in. Only if they are subsequently added to another group will they have any group-based access. This effectively nullifies group permissions by default for all users, allows for more granular access control, and may therefore be your ideal choice for managing users and groups. The only drawback to this approach is the small administrative inconvenience of creating new groups when you create new users. 4.1.1.4 Login classes
With a system to manage users and groups in place, you can turn your attention to putting in place resource limits, environment variables, and session accounting on a per-user or per-group basis. Login classes provide an effective means of doing this. As you create groups for the users of your systems, reevaluate the preexisting limits imposed in /etc/login.conf and see if additional restrictions may be appropriate for the group you are creating. 4.1.1.5 umasks
The user file-creation mask (umask) is of fundamental importance in any discussion about access control. Setting a umask affects the default permissions on all newly created files. Most administrators and users expect files they create to be readable for everyone (user, group, and other) but only writable for themselves. Likewise when directories are created, they expect that anyone should be able to change into the directory and list contents (user, group, and other read/execute), but only the creator should be able to write files. FreeBSD and OpenBSD set a default umask of 022 for users. It is this setting that creates the behavior described above. For users, this may be acceptable. For the root user, a more restrictive umask is preferable. A more appropriate umask would enforce full user rights but no group or world permission upon file, a umask of 077. You may adjust the default umask on your system by modifying /etc/login.conf appropriately. Be advised that users can freely overwrite the default umask by using the shell-builtin command umask either on the command line or in their shell startup configuration file (.[t]cshrc for [t]csh, .profile for [ba]sh, etc.). 4.1.1.6 The danger of ACLs (FreeBSD only)
User and group permissions used to be all there was to worry about on BSD systems. Now, however, FreeBSD 5.x offers support for filesystem access control lists (ACLs). With these discretionary access controls, it is now possible to grant much more fine-grained permissions based on arbitrary collections of users instead of granting permission by preexisting groups. With this increased flexibility comes the need for more careful administration. Arbitrary and haphazard assignment of permissions can make it extremely difficult to determine who has access to what and manage permissions in general. In some cases, it may be preferable to administer your system using standard Unix permissions. On the other hand, it can be frustrating to see carefully crafted group-based permissions changed by users to a world-readable or, heaven forbid, a world-writable state. In many cases, users see this as a convenience and prefer it over tracking down the administrator with a change request. Whichever paradigm you choose, understand the risks involved in either approach and make a conscious decision instead of "going with the flow." If you decide discretionary access controls are not appropriate in your environment, perhaps mandatory access controls are for you. The mandatory access control (MAC) framework was introduced with FreeBSD 5.x and allows the administrator to assign security-relevant labels to data. This type of access control imposes limits based on data classification and user rights, both of which are controlled by the administrator.
Neither ACLs nor MAC is supported in OpenBSD. 4.1.2. Controlling Administrator Access
Perhaps even more important than controlling the access users have on your systems is limiting and auditing administrator access. On systems with multiple administrators or service operators who need certain administrative rights, don't provide access by passing around the root password during lunch. Infrastructure systems generally provide one or two major services and you may be able to grant rights by making key files group-writable. On some systems, the only privilege certain administrative users may need is the ability to restart key service. Allowing some non-root users to do this is easy using sudo. Even on systems where multiple administrators operate at the same system-wide level, it is important to carefully audit what administrators do to enforce accountability. The rest of this section outlines some of the approaches you should take to grant administrator access while limiting and auditing the use of escalated privileges. 4.1.2.1 Disable and avoid clear-text access
The first place to look for ways to mitigate the risks administrators pose is in their access method. telnet(1), rsh(1), rlogin(1), etc. are clear-text protocols. Your username, password, and every bit of data displayed or typed into a session is easily readable by anyone else on the local network. Administrators should never use clear-text protocols. This should be a done deal, as the default on both FreeBSD and OpenBSD systems is to have these clear-text protocols disabled. 4.1.2.2 Connect using SSH
Both OpenBSD and FreeBSD provide secure shell (ssh(1)) services as part of the base installation. Leave telnet disabled and use ssh. Configure sshd(8) to accept remote connections based on public/private key cryptography instead of the weaker password-based authentication. Ensure all administrators accessing your servers are generating ssh keys using the ssh-keygen(1) utility. The public half of their keys may then be placed in their ~/.ssh/authorized_keys file on every system to which they require access. See the Section 3.6 section of Chapter 3 or the sshd_config(5) manpage to learn how to disable password authentication altogether.
When the number of systems involved reaches hundreds, thousands, or tens of thousands, managing ssh keys scattered across machines can become a nightmare: both for distribution and removal. In this case, ssh using public key authentication might not be an option, so consider deploying a Kerberos infrastructure which provides for secure, centralized authentication and kerberized ssh. Kerberos eliminates the need for distributing ssh keys while still providing encrypted access. Without additional software, however, Kerberos reduces the authentication from two-factor back to one. 4.1.2.3 Privileged access using ssh
Administrators gain root-level access to a system in one of three ways:
The first option requires that you allow root logins via ssh and no human being can be directly tied to login events. This is far from ideal. The second option allows you to disable root logins, but after the administrator gains a root shell, she is unlikely to relinquish it and subsequent commands are not audited. The third option provides accountability, enables auditing for every action, and is generally considered the most secure way to gain privileged access. 4.1.3. General sudo Configuration
Once administrators are using an encrypted means of access to the system, and not logging in as root, you may turn your attention to the execution of privileged commands. This is, after all, what sets the administrator apart from the user. sudo is available with the base operating system in OpenBSD and may be installed out of FreeBSD's ports from ports/security/sudo or during the install process. It allows the users of the system (or other administrators) to execute commands as other, often more privileged, users. It also allows for the dissemination of granular administrative rights with comprehensive auditing (by logging every command run through sudo) instead of "keys to the kingdom" without any accountability. In a nutshell, sudo operates by accepting entire commands as arguments to itself, consulting the sudoers(5) configuration file to authorize the user attempting to run the command, and then executing the command in an alternate user context. Creating a customized sudoers file is one of the first steps the security-minded system administrator takes on a newly installed system. Like it's counterpart vipw(8) for the passwd files, visudo locks the sudoers file and provides some syntax checking after editing. Since the sudoers file defines how users can execute privileged commands, errors in the file can be very dangerous. Always use visudo. sudo configuration is fairly straightforward. You define aliases for commands, hosts (useful if you distribute a single sudoers file to multiple hosts), users who should be allowed to run privileged commands, and user accounts under whose context certain commands should be executed (sudo can run commands as non-root users with -u). Aliases, found at the bottom of the sudoers file, specify which users are allowed to execute what commands, where (which host), and potentially, as whom. We do not go into any more detail about general sudo configuration, as configuration is extremely well documented in the sudoers(5) manpage. Instead we turn our attention to secure configuration guidelines and pitfalls. 4.1.3.1 Avoid dangerous commands
Be extraordinarily careful about the binaries to which you grant access. Be aware that many binaries (like vi(1)) let you spawn a shell. When vi is executed with super-user privileges, any commands it runs (such as a shell, or grep, or awk) will be too! Likewise, less(1) (which is the opposite of more(1)) on FreeBSD and OpenBSD can invoke the editor defined by the VISUAL or EDITOR environment variable when you press v while paging through a file if this variable is set to vi, a root shell is just a few keystrokes away. To allow users to view certain sensitive files, allow privileged execution of the cat(1) binary; more can run in the user's context. In Example 4-1, the first command runs more as root, the second runs more in the user context and cat as root. Example 4-1. Viewing files with sudo
% sudo more /root/private_file % sudo cat /root/private_file | more
There are innumerable commands that can gain unrestricted elevated privileges when provided certain keyboard input, file input, or environment variables. Some examples include find(1), chown(8), chgrp(1), chmod(1), rm(1), mv(1), cp(1), crontab(1), tar(1), gzip(1), and gunzip(1). As it turns out, configuring sudo without "giving away the barn" is no easy task! Remember that liberal sudo rights should only be assigned to administrators who would otherwise have root. Otherwise, allow only very specific privileged commands by following the guidelines in the rest of this section. 4.1.3.2 Use explicit paths
Explicitly providing a path ensures that identically named binaries elsewhere in the path are never executed with elevated privileges. While there are ways to control how the PATH is used in sudo, including the ignore_dot and env_reset flags, the safest and most foolproof way is to always use explicit paths to binaries.
4.1.3.3 Be very specific
As mentioned previously, several system commands can be used to gain elevated privileges when combined with sudo. To combat this, be very specific about not only allowed commands but also the allowed arguments, as shown in Example 4-2. Example 4-2. Commands with arguments
Cmnd_Alias WEB = /usr/local/sbin/apachectl, \ /usr/bin/chgrp [-R] www-devel /web/*
In this case, the alias WEB is created as a set of commands for the administrators of the web server. They have unrestricted use to the Apache control script apachectl(1), and may change group ownership of any files in /web/ to www-devel, while optionally providing the recursive argument to chgrp. 4.1.3.4 Use NOPASSWD sparingly
A useful feature of sudo is the ability to allow certain users to run commands without having to provide a password. If users ask for this functionality, you should feel comfortably within your rights as an administrator to deny their request. Forcing a password prompt sends a message (both literally and figuratively) to users that they are about to run a command in root's context and they should be careful and responsible. In some cases, service accounts need to run privileged commands, and there may not be a human being around to enter a password at the time. In these cases, it becomes acceptable to use the NOPASSWD option as shown in Example 4-3. Example 4-3. Service account using NOPASSWD
nagios localhost = NOPASSWD : /usr/local/etc/rc.d/nagios.sh restart
In this case, the nagios service account under which some daemon or script runs is able to run the nagios.sh startup script with the restart argument. Since this daemon is running without user intervention, should the need arise to restart nagios, it will be able to do so without needing to provide a password. 4.1.3.5 Be realistic
Finally, avoid being too draconian. Service operators are likely to get angry and spend time trying to find ways to gain unrestricted escalated privileges if you provide too few means for them to do their jobs. This wastes time and, if they succeed, will defeat your auditing strategy. 4.1.4. Comparing sudo and su
The BSD operating systems favor sudo over su. We take a moment here to outline some of the advantages and disadvantages of both approaches. We have tried to capture the salient differences in Table 4-1.
Bear in mind that the satisfaction of the named characteristics may be affected by the number of administrators on the system in question.
Even when you have configured sudo to grant fine-grained permissions, the root account, of course, still exists. This account represents "keys to the kingdom" and is a goal of many attackers. This account must have a strong password that is known by few, and protected well, or it should be locked. When administrators are supposed to have full-fledged root access but choose, or are required by policy, to use sudo, the root account may be safely locked. In this case, administrators invoke a shell through sudo to gain root-level access. Remember, however, that whenever shell access is provided, every administrator's password is as important as the root password would be since it effectively grants the same privileges. 4.1.5. Safeguard the Root Password
Root passwords should be stored in a secure location available to a non-administrator in the event of an emergency. This is most often accomplished in at least two ways for redundancy. The most common and straightforward way to be able to securely recover root passwords is very nontechnical. Write the passwords down on paper and store the sheet offsite with other system configuration documentation. Be sure to clearly define who has access to these documents.
The root password may also be encrypted by a combined key such that multiple people are required for decryption. For instance, if none of the administrators to whom the file has been encrypted are able to perform root functions (e.g., due to vacation, illness, or death), passwords should be recoverable only by the combined efforts of some collection of relevant supervisors, IT managers, and/or executives. Protecting the root password in these ways is more important when no other individuals are able to gain physical access to the system. Where physical access exists, someone should be able to boot the system from removable media and change root's password from the console. Nevertheless, an alternate means of root password access should be possible to save time in the event of an emergency.
|
< Day Day Up > |