Securing Linux, Part 3: Hardening the system
时间:2007-03-11 来源:ooike
Securing Linux, Part 3: Hardening the system |
|
||
Mario Eberlein ([email protected]), IT Architect, IBM Global Services In this series of articles, learn how to plan, design, install, configure, and maintain systems running Linux in a secure way. In addition to a theoretical overview of security concepts, installation issues, and potential threats and their exploits, you'll also get practical advice on how to secure and harden a Linux-based system. We will discuss minimal installation, hardening a Linux installation, authorization/authentication, local and network security, attacks and how to protect against them, as well as data security, virus, and malware programs. Part 1 of this series started you on your way with a general explanation of security concepts and potential threats. Part 2 took you to the next stage by listing the concerns you need to keep in mind when planning a secure installation, including making a detailed security action plan. In this part, we'll cover the steps involving in hardening Linux.
About hardening
After completing the preliminary planning and preparation and performing the minimal installation (see Part 2), you need to consider several configuration steps. These steps are generally referred to as hardening Linux:
Securing the boot process For LILO, replace the parameter prompt with password in the lilo.conf configuration file (usually in /etc). For Grub, the relevant parameters are hiddenmenu, default 0, and password in the Grub configuration file (usually in /boot/grub/grub/conf). Ensure that the run-level configuration requires the root password when switching to single user mode by adding sp:S:respawn:/sbin/sulogin to /etc/inittab. Prevent users from invoking a reboot using Ctrl-Alt-Del: disable the ctrlaltdel entry in /etc/inittab by commenting out the line with the ctrlaltdel. By adding a hash (#) sign similar to this -- #ca::ctrlaltdel:/sbin/shutdown -t5 -rf now -- you can prevent that key combination from ever triggering a reboot.
Securing services and daemons To uncover all enabled services, check several locations. Also, disable insecure services and replace their functionality with more secure options. For instance, telnet is not encrypted, so use the encrypted ssh service instead of telnet (see Part 2). Consider these elements when securing services:
/etc/inittab The init process distinguishes several states, so-called run levels, identified by a single character. When a run level is entered or certain events (such as power failure) occur, the entries are evaluated and the appropriate commands are executed. The format of an entry in /etc/inittab is a label for the entry, followed by the run levels in which the entry is processed, followed by an action keyword and the command to be executed including command-line parameters. All these fields are separated by colons and a typical entry would look like this: my_service:35:once:/usr/local/bin/my_service someparameter (Find a complete list of action keywords in the man-pages of inittab.) In this example, the entry's label is my_service. It will run the program /usr/local/bin/my_service with the parameter someparameter when run levels 3 or 5 are entered. Once the program terminates, it is not restarted (action keyword "once"). For a secure Linux system, you need to understand the functions of all entries in /etc/inittab and disable potentially unwanted services by deleting the entry or commenting it out using the hash sign at the beginning of the line. Two types of entries are common in all Linux systems. The first is used to launch a program called /sbin/getty (or similar), which is used to allow logins on the Linux virtual consoles or serial lines. The second type launches a script usually named rc in the /etc/rc.d directory with the current run level as the parameter. This script controls the starting and stopping of services (and that's described next).
Boot scripts in /etc/init.d If the link name starts with an "S" the script is executed when entering the run level to start the corresponding service; if it starts with "K" the script is executed when exiting the run level to stop the service. Most of the time the name of the boot script reveals which service it controls. To prevent a service from being started in a specific run level, delete the links from the run-level subdirectory to the corresponding boot script or replace the original boot script in /etc/init.d by a dummy script doing nothing.
The inetd/xinetd daemons The inetd daemon is configured in /etc/inetd.conf, which contains entries for each service to be offered by the super daemon. An entry configuring an FTP server could look like this -- ftp stream tcp nowait root /usr/bin/ftpd in.ftpd -el -- and you can disable it by commenting it out using a hash sign. For security reasons, the use of xinetd is recommended. In contrast to inetd, xinetd is able to start rpc-based services and provides access control. xinetd can limit the rate of incoming connections, number of incoming connections from specific hosts, or total number of connections for a service. xinetd is configured by distinct configuration files for each subordinate daemon. These files are located in /etc/xinetd.d/. The example configuration file for the FTP server above would be called /etc/xinetd.d/ftp and would look like this: Listing 1. Configuration file, /etc/xinetd.d/ftp
To disable the service, the parameter disable is set to yes as in the previous example. For a more fine-grained control of access, xinetd supports these three additional parameters:
To restrict the access but not completely disable the ftp daemon, you could modify the config file /etc/xinetd.d/ftp as follows: Listing 2. Configuration file, /etc/xinetd.d/ftp, modified to restrict access
only-from and no_access accept numeric IP addresses (right-most zeros are treated as wild cards), IP addresses/netmask ranges, hostnames, and network names from /etc/networks. If a combination of only-from and no_access is used, xinetd finds the closest match for each host connecting. For the previous code example, this means hosts with an IP address 172.16.x.x can connect except to hosts with addresses in 172.16.1.x, 172.16.2.x, 172.16.3.x, and 172.16.10.x. As you can see, there is no need to specify all four components of an address when you use the factorized notation as shown for no_access. The factorized part must be the right-most element of the address. See the Resources section below for an article on xinetd and its configuration.
TCP wrappers Using TCP wrappers delivers two main advantages over using plain inetd:
For a detailed documentation of TCP wrapper configuration files, see the Red Hat Linux Reference Guide listed in Resources.
Firewalls The installation and configuration of a firewall is quite a complex topic and is beyond the scope of this article series.
Securing local filesystems Take special care with respect to inappropriate permissions regarding world-writable files and system directories and so-called setuid or setgid commands. These commands are executed with higher user privileges than the user running the command actually has. This might be necessary to access files that only root has access to (such as /bin/passwd needs to access /etc/passwd). For each of these commands, make sure that it really needs the setuid/setgid bits set. If this is not the case, disable it. When all files on a partition definitely do not need the setuid/setgid bits, the nosuid option in /etc/fstab disables it for each file on the corresponding filesystem (/dev/hdc1 in the following example):
Furthermore, for very sensitive data, it might make sense to encrypt that data and protect it with a passphrase. GnuPG provides a suitable package to accomplish this.
Enforcing quotas and limits Groupnames must be preceded by the @ to distinguish them from usernames. The type must be either soft or hard. Soft-limits can be exceeded and are usually warning marks, whereas hard-limits cannot be exceeded. A resource can be one of these keywords:
In the following code example, all users are limited to 10 MB per session and are allowed a total of four simultaneous logins. The third line disables core dumps for everybody. The fourth line removes all limits for user bin. ftp is allowed to have 10 simultaneous sessions (which is especially useful for anonymous ftp accounts); members of the group managers are limited to 40 processes. developers have a memlock limit of 64 MB and all members of wwwusers cannot create files that are larger than 50 MB. Listing 3. Setting quotas and limits
To activate these limits, you need to add the following line to the bottom of /etc/pam.d/login: session required /lib/security/pam_limits.so. Quotas allow you to restrict the number of inodes and the consumable space for users and groups. Note that a quota is defined per mount point, so if users have write access on several partitions, make sure to define quotas for each of them. Quotas are an administrator's way of minimizing the risk of DoS attacks that rely on filling up all the available space of a hard drive (which prevents other processes from creating temporary files and thus makes them fail). Depending on which distribution you are using, you can install the shipped quota tools or you can download, compile, and install them yourself (see Resources). Quotas must be enabled in the kernel. Most distributions today come with quota support. If your distribution doesn't have quotas enabled, see the mini-howto in Resources for instructions on enabling them. To enable quotas for a filesystem, you must add an option to the corresponding line in /etc/fstab. Use usrquota and grpquota to enable user quotas and group quotas as Listing 4 shows: Listing 4. Enabling user quotas and group quotas
Next, remount the corresponding filesystems to activate the newly added options with mount -a -o remount; then create a binary quota file using the command quotacheck -cugvm, which contains the quota configuration in a machine-readable format. This is what the quota subsystem operates on. Assigning quotas is done using the tool edquota. To define the limits for user alice, invoke it with edquota -u alice. The editor defined in the environment variable EDITOR (default is vi) opens with similar content:
The "in use" values are for your information only and cannot be changed -- soft and hard limits are the only values you can modify. After saving and exiting the editor, edquota reads the temporary file you just edited and transfers the values into the binary quota file to reflect your changes. Editing group quotas works the same except that the option -g instead of -u has to be used. Soft limits are a warning level that can be exceeded, whereas hard limits are strictly enforced. Soft limits have a grace period (sometimes also called soft time limits); this is the time span a user is allowed to exceed the soft limit until it is enforced by the system. You can set the grace period with edquota -t. The available units are seconds, minutes, hours, days, weeks, and months. Other useful tools for managing quotas are repquota (summarizes quotas for a filesystem), quotaon, and quotaoff (switches quotas on and off).
Enabling Mandatory Access Control That way, in a properly configured system with MAC, a service that has been hijacked or hacked into cannot take over the system. Even though the user or group ID under which the service processes run (worst case scenario: root) may match the file permissions of critical system files such as /etc/passwd, the policy in place disallows access to them. The effectiveness of SELinux is illustrated by test systems on the Internet that allow anyone to log in; the control mechanisms prevent anything malicious from being done, even though users can log in as root!
There are some problems with SELinux, however. First, the configuration is fairly intrusive if the distribution is not MAC-enabled by the vendor. It may require patching and recompiling the kernel and replacing certain system-management tools (all of which may violate the distribution vendor's support policy). Second, it is a quite complex task to define a proper policy. If there is no policy definition available for your application of choice, you may have a hard time getting it to run in a MAC environment. This makes it difficult for use cases such as desktop workstations in which a wide variety of software packages are to be supported.
Updating and adding security patches When a new update becomes available, you should check to see if it applies to your system and your security requirements. Installing an update can itself be the cause of security issues. Also consider that each update may introduce new vulnerabilities, or if the update fails, your system may be left in an unusable state. When you have to apply an update to a large range of systems, you often cannot update them all at the same time -- this may cause your systems to be mutually incompatible during the update phase. As you can see, there are a lot of risks involved with updating a system. Here are some recommendations to mitigate these risks:
Putting your security plan into action This section shows you how to find and disable those unnecessary (and potentially dangerous) processes and prepare for a regular audit of the system.
Finding and disabling unnecessary processes
Now let's look at those processes that open network connections; they hold the largest potential for attacks. To get a list of all TCP or UDP connections, issue the command netstat -atu (with name resolution, easier to read) or netstat -atun (without name resolution, quicker). Within this list, pay special attention to TCP connections with status LISTEN and to all UDP connections because these are servers that accept incoming connections. If the server listens to 127.0.0.1/localhost, it can only be reached by the system itself (loopback interface). It is therefore much less exposed than a server listening to an externally reachable interface or even 0.0.0.0 (= * with name-resolution turned on), which can be reached through any network interface. If you have used netstat -atun, you need to translate the port numbers yourself. You can look them up in /etc/services. Use the additional parameter -p to display the corresponding process as shown in Listing 5. In this example, you could conclude that the portmapper and the graphical user interface (X) is not needed for a particular server. Portmapper provides a standard endpoint for various RPC-based services such as NFS; the system does not provide NFS shares. An X window display is useful when the system is used as workstation, but has limited use on a server. Identify how these processes were started (via /etc/inittab, via boot scripts, etc.) and disable them as described earlier. This task can become a bit more challenging if the program was launched by another program: The X server was most likely launched by a display manager such as xdm, kdm, or gdm, and does not turn up in the inittab or boot scripts directory itself. Connections listed by netstat do not automatically have to be available to all computers on the net: A firewall based on Linux's built-in capabilities may further regulate the access before any packet reaches the open connection.
Audit preparation
Next in the series |