8.2 Build Time: Installing ApacheA secure web service starts with a secure web server, which in turn, starts with good code — no buffer overflows, race conditions, or other problems that could be exploited to gain root privileges. It should be immune to remote root exploits by the swarming script kiddies. By any criteria, Apache is pretty good. No serious exploit has been reported since January 1997; security patches have addressed minor vulnerabilities. Apache's main competition among web servers, Microsoft's Internet Information Server (IIS), has had many critical and ongoing security problems. A Microsoft Security Bulletin issued in April 2002 describes ten critical problems in IIS 4 and 5. These include vulnerabilities to buffer overruns, denial of service, and cross-site scripting; a number of these provide full-system privileges to the attacker. In practice, most Apache security problems are caused by configuration errors, and I'll talk about how to avoid these shortly. Still, there are always bug fixes, new features, and performance enhancements, along with the occasional security fix, so it's best to start from the most recent stable release. As this was written, Apache 2.0 was released for general availability after years of development and testing. It will take a while for this to settle down and percolate into Linux distributions and existing systems, so the 1.3 family is still maintained. I'll cover 1.3 configuration here, with mentions of 2.x where it differs. See http://www.apacheweek.com/security/ for Apache security news. 8.2.1 Starting InstallationAttacks are so frequent on today's Internet that you don't want to leave a window for attack, even for the few minutes it takes to set up a secure server. This section covers setting up your environment and obtaining the right version of Apache. 8.2.1.1 Setting up Your firewallA public web server is commonly located with email and name servers in a DMZ, between outer and inner firewalls. If you're doing your own hosting, you need at least one layer of protection between your public web server and your internal network. Web servers normally listen on TCP ports 80 (http:) and 443 (secure HTTP, https:). While you're installing Apache and the pieces are lying all around, block external access to these ports at your firewall (with iptables or other open source or commercial tools). If you're installing remotely, open only port 22 and use ssh. After you've configured Apache, tightened your CGI scripts (as described in this chapter), and tested the server locally, you should then reopen access to the world. 8.2.1.2 Checking Your Apache versionIf you have Linux, you almost certainly already have Apache somewhere. Check your version with the following command: httpd -v Check the Apache mirrors (http://www.apache.org/mirrors/) or your favorite Linux distribution site for the most recent stable release of Apache, and keep up with security updates as they're released. Red Hat publishes overall security updates at http://www.redhat.com/apps/support/errata/. If you're running an older version of Apache, you can build a new version and test it with another port, then install it when ready. If you plan to replace any older version, first see if another copy of Apache (or another web server) is running: service httpd status or: ps -ef | grep httpd If Apache is running, halt it by entering the following: apachectl stop or (Red Hat only): service httpd stop or: /etc/init.d/apache stop Make sure there aren't any other web servers running on port 80: netstat -an | grep ':80' If you see one, kill -9 its process ID, and check that it's really most sincerely dead. You can also prevent it from starting at the next reboot with this command: chkconfig httpd off 8.2.2 Installation MethodsShould you get a binary installation or source? A binary installation is usually quicker, while a source installation is more flexible and current. I'll look at both, but emphasize source, since security updates usually should not wait. 8.2.2.1 RPM installationOf the many Linux package managers, RPM may be the most familiar, so I'll use it for this example. Grab the most current stable version of Apache from http://www.apache.org, your favorite Linux distribution, or any RPM site. Here's an example of obtaining and installing an older Apache RPM from Red Hat's site: # wget ftp://ftp.redhat.com/pub/redhat/linux/updates/7.0/en/\
os/i386/apache-1.3.22-1.7.1.i386.rpm
# rpm -Uvh apache-1.3.22-1.7.1.i386.rpm
Depending on whose RPM package you use, Apache's files and directories will be installed in different places. This command prints where the package's files will be installed: rpm -qpil apache-1.3.22-1.7.1.i386.rpm We'll soon see how to make Apache's file hierarchy more secure, no matter what it looks like. 8.2.2.2 Source installationGet the latest stable tarball: # wget http://www.apache.org/dist/httpd/apache_1.3.24.tar.gz # tar xvzf apache_1.3.24.tar.gz # cd apache_1.3.24 If the file has an MD5 or GPG signature, check it (with md5sum or gpgv) to ensure you don't have a bogus distribution or a corrupted download file. Then, run the GNU configure script. A bare: # ./configure will install everything in directories under /usr/local/apache (Apache 2 uses /usr/local/apache2). To use another directory, use --prefix: # ./configure --prefix=/usr/other/apache Apache includes some standard layouts (directory hierarchies). To see these and other script options, enter the following: # ./configure --help Next, run good old make: # make This will print pages of results, eventually creating a copy of Apache called httpd in the src subdirectory. We'll look at what's actually there in the next section. When you're ready to install Apache to the target directory, enter the following: # make install 8.2.2.3 Linking methodsDoes the preceding method produce a statically linked or dynamically linked executable? What modules are included? By including fewer modules, you use less memory and have fewer potential problems. "Simplify, simplify," say Thoreau, the least privilege principle, and the Web Server Diet Council. Dynamic linking provides more flexibility and a smaller memory footprint. Your copy of Apache is dynamically linked if you see something like this: # httpd -l Compiled-in modules: http_core.c mod_so.c Dynamically linked versions of Apache are easy to extend with some configuration options and an Apache restart. Recompilation is not needed. I prefer this method, especially when using the Perl or PHP modules. See http://httpd.apache.org/docs/dso.html for details on these Dynamic Shared Objects (DSOs). A statically linked Apache puts the modules into one binary file, and it looks something like this: # httpd -l Compiled-in modules: http_core.c mod_env.c mod_log_config.c mod_mime.c mod_negotiation.c mod_status.c mod_include.c mod_autoindex.c mod_dir.c mod_cgi.c mod_asis.c mod_imap.c mod_actions.c mod_userdir.c mod_alias.c mod_access.c mod_auth.c mod_setenvif.c suexec: disabled; invalid wrapper /usr/local/apache/bin/suexec Specify --activate-module and --add-module to modify the module list. Changing any of the modules requires recompilation and relinking. 8.2.3 Securing Apache's File HierarchyWherever your installation scattered Apache's files, it's time to make sure they're secure at runtime. Loose ownership and permission settings are a common cause of security problems. We want the following:
Least privilege suggests we create an Apache user ID with as little power as possible. You will often see use of user ID nobody and group ID nobody. However, these IDs are also used by NFS, so it's better to use dedicated IDs. Red Hat uses user ID apache and group ID apache. The apache user has no shell and few permissions — just the kind of guy we want, and the one we'll use here. There are different philosophies on how to assign permissions for web user IDs. Here are some solutions for content files (HTML and such):
Table 8-2 lists the main types of files in an Apache distribution, where they end up in a default RPM installation or a source installation, and recommended ownership and permissions.
|