There are several parameters associated with security on the Apache Web server. The security of the server is enforced in part by firewalls and SELinux. Internal Apache security measures are associated with the main Apache httpd.conf configuration file.
Now that you've glanced at the configuration file, it's time to analyze it, and its associated directories, with a view toward security.
You can modify the httpd.conf configuration file to secure the entire server or manage security on a directory-by-directory basis. Directory controls secure access by the server, as well as users who connect to the Web sites on the server. To explore the basics of Apache security, start with the first default active line in httpd.conf:
This line looks deceptively simple; it limits what readers see about your Web server when you browse to a nonexistent page. If you don't use this command, outsiders can see whether you've loaded modules such as Perl, Python, and PHP. Sharing this knowledge can make your system more vulnerable. You can restrict access to the root directory on your Web server as shown here:
<Directory /> Options FollowSymLinks AllowOverride None </Directory>
This configures a very restrictive set of permissions. The Options FollowSymLinks line supports the use of symbolic links for Web pages. The AllowOverride None line disables any .htaccess files. Otherwise, .htaccess can allow others to administer your server, starting from the DocumentRoot directory. If .htaccess is in a subdirectory, such as /var/www/html/data/, the additional directives, if permitted by AllowOverride, would apply only to that directory.
You can improve this by limiting access to all but explicitly allowed users, such as those within your company, by adding the following commands to the <Directory> container:
Order deny,allow Deny from all
The next excerpt limits access to /var/www/html, which corresponds to the default DocumentRoot directive (while these directives are divided by numerous comments, they are all in the same stanza):
<Directory /var/www/html> Options Indexes FollowSymLinks AllowOverride None Order allow,deny Allow from all </Directory>
You'll note that the Options directive has changed; the Indexes setting allows readers to see a list of files on your Web server if no index.html file is present in the directory as defined by DocumentRoot. The Order and Allow lines allow all users to access the Web pages on this server.
Finally, the Listen directive defines the IP address and TCP/IP port for this server. For example, the default shown next means that this server will work with every computer that requests a Web page from any of the IP addresses for your computer on the standard TCP/IP port, 80:
If you have more than one IP address on your computer, you can use this directive to limit this Web server to one specific IP address. For example, if you've set up an intranet on this Web server, you could use the IP address that connects to your private network here.
If you're also setting up secure Web services, there's a second Listen directive in the ssl.conf file in the /etc/httpd/conf.d directory. The data from this file is automatically incorporated into your Apache configuration. It includes the following directive, which points to the default secure HTTP (HTTPS) port for TCP/IP, 443:
The Red Hat Exam Prep guide suggests that you need to be ready to configure a regular HTTP and a secure HTTPS Web site.
If you have an iptables firewall on your computer, you'll need to disable it at least for TCP/IP port 80. If you're configuring a secure Web site, you'll also need to disable iptables for port 443. If you've enabled SELinux, you'll need to change the Access Control List (ACL) security contexts of key directories. Chapter 15 describes these processes in detail. For now, just take the following two steps:
Run system-config-securitylevel, allow incoming WWW (HTTP) and Secure WWW (HTTPS) connections as "Trusted Services," and exit normally.
Run the ls -Z /var/www command. Note the ACL settings. If you configure other directories for Web services, you'll need to change their ACL settings. For example, if you create and then use the /www directory, run the following commands:
# chcon -R -u system_u /www/ # chcon -R -t httpd_sys_content_t /www/
You can add the Order, allow, and deny directives to regulate access based on host names or IP addresses. This basic command allows access by default. It reads the deny directive first:
If you set Order allow,deny, access is denied by default. Only those host names or IP addresses associated with the allow directive are allowed access.
You can deny or allow from various forms of host names or IP addresses. For example, the following directive denies access from all computers in the osborne .com domain:
Deny from osborne.com
It's preferable to use IP addresses, so communication with a DNS server does not slow down your Web server. The following example directives use a single IP address; alternatively, you can set up the 192.168.30.0 subnet in partial, netmask, or CIDR (Classless InterDomain Routing) notation, as shown here:
Deny from 192.168.30.66 Allow from 192.168.30 Deny from 192.168.30.0/255.255.255.0 Allow from 192.168.30.0/24
You can limit access to your Web sites to authorized users with passwords. As describe shortly, these passwords can be different from the regular password database on your Linux computer.
If you want to configure user-based security for the virtual Web site described earlier, you'll need to set up a <Directory> container for the selected directory, in this case, it's /var/www/html/test. You'll want several commands in the <Directory> container:
To set up basic authentication, you'll need an AuthType Basic directive.
To describe the site to requesting users, you can include an AuthName "some comment" directive.
To refer to a Web server password database named /etc/httpd/testpass, you'll need a AuthUserFile /etc/httpd/testpass directive.
To limit the site to a single user named engineer1, you could add a Require user engineer1 directive.
Alternatively, to limit the site to a group as defined in /etc/httpd/webgroups, you'd add the AuthGroupFile /etc/httpd/webgroups directive. You would also need a directive such as Require group Design, where Design is the name of the group specified in webgroups.
Here's an example of code that I've added after the <Virtual Host> container:
<Directory "/var/www/html/test"> AuthType Basic AuthName "Password Protected Test" AuthUserFile /etc/httpd/testpass Require user engineer1 </Directory>
When properly configured, the next time you try accessing the http://enterprise5a.example.net/test Web site directory in the Firefox browser, you're prompted for a username and password, as shown in Figure 9-3.
Figure 9-3: A password-protected Web site
To configure passwords for a Web site on your server, you need to create a separate database of usernames and passwords. As the useradd and passwd commands are used for regular users, the htpasswd command is used to set up usernames and passwords for your Web server.
For example, if you want to create a database file named webpass in the /etc/httpd directory, you'd start with the following command:
# htpasswd -c /etc/httpd/webpass engineer1
The -c switch creates the specified file, and the first user is engineer1. You're prompted to enter a password for engineer1. Users in the webpass database do not need to have a regular account on your Linux computer. Note how I set up the file in the ServerRoot directory when I configure virtual hosts later in this chapter. The permissions limit access to specific users and override any settings that use the default DocumentRoot /var/www/html directory.
Once you've created the database file, you can add to it without the -c switch; for example, the following command prompts you for a password for drafter1 before adding it to your testpass database:
# htpasswd /etc/httpd/testpass drafter1
To set up access for more than one user, you'll also need a group file. For the example described earlier in the "User-Based Security" section, you can set up the webgroups file in the same directory with the following line of users:
Design: engineer1 drafter1 lead1
One useful option through Apache is access to a user's home directory. If you change the following directive from UserDir disable to
anyone will have access to Web pages that a user puts in his or her ~/public_html directory. For example, a user named michael can create a /home/michael/public_html directory and add the Web pages of his choice.
However, this requires a bit of a security compromise; you need to make michael's home directory executable for all users. This is also known as 701 permissions, which you can configure with the following command:
# chmod 701 /home/michael
You'll also need to make the public_html subdirectory readable and executable by all users, also known as 705 permissions:
# chmod 705 /home/michael/public_html
As this is a Web server, you will need to add at least an index.html file to this directory. It can be a text file for test purposes. The commented stanza that follows is one excellent way to help keep home directories so shared a bit more secure. For more information, see the Apache documents available from http://httpd.apache.org, or those you may have copied to the /var/www/html/sharing directory as described in Exercise 9-2. In that case, they'll be available locally as http://localhost/sharing, as long as you haven't activated "Virtual Hosts" as described later in the section of the same name.
Exercise 9-2: Creating a List of Files
In this exercise, you'll be setting up a list of files to share with others who access your Web server. The process is fairly simple; you'll configure an appropriate firewall, create a subdirectory of DocumentRoot, fill it with the files of your choice, set up appropriate security contexts, and activate Apache. This assumes you've installed the ELinks RPM as described in Exercise 9-1.
Make sure the firewall does not block access to port 80. One way to do so is with the Red Hat Security Configuration tool, which you can start with the system-config-securitylevel command. If you're required to activate a firewall (on your exam), make sure to allow incoming WWW (HTTP) connections (and any others required on your exam).
Create a subdirectory of DocumentRoot. In the default /etc/httpd/conf/httpd .conf file, it's /var/www/html. For this exercise, I've created the /var/www/html/ sharing/ directory.
Add the files of your choice to this directory; I've copied the files from the /etc/httpd/conf.d directory:
# cp -ar /var/www/manual/* /var/www/html/sharing/
Activate the Apache service with the following command:
# apachectl start
Make sure Apache starts the next time you boot:
# chkconfig httpd on
Use the ls -Z /var/www/html and ls -Z /var/www/html/sharing commands to review the security contexts for the /var/www/html/sharing directory and copied files. If it doesn't already correspond to the contexts shown here, set them up with the following commands:
# chcon -R -u system_u /var/www/html/sharing/ # chcon -R -t httpd_sys_content_t /var/www/html/sharing/
Try starting the elinks browser on the local server, pointing to the sharing subdirectory:
# elinks 127.0.0.1/sharing
Go to a remote system and try accessing the same Web directory. For example, if the IP address of the local system is 192.168.0.50, navigate to http://192.168.0.50/sharing. If possible, try this a second time from a conventional GUI browser.
#<Directory /home/*/public_html> # AllowOverride FileInfo AuthConfig Limit # Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec # <Limit GET POST OPTIONS> # Order allow,deny # Allow from all # </Limit> # <LimitExcept GET POST OPTIONS> # Order deny,allow # Deny from all # </LimitExcept> #</Directory>
Of course, you need to configure firewalls and allow SELinux access in appropriate ways. Firewalls must allow access to the standard HTTP port, 80. SELinux must be configured to "Allow HTTPD To Read Home Directories." (Alternatively, activate the httpd_enable_homedirs boolean with the setsebool -P htttpd.enable.homedirs 1 command.) Finally, the ACL must be revised accordingly. Once the following command is run
# chcon -R -t httpd_sys_content_t /home/michael/public_html
and apachectl reload is executed, you can finally access the files in the public_html/ subdirectory. For example, if I've made these changes on the Enteprise5a system, I'd point my browser to http://Enteprise5a/~michael URL.
There is a way to override inherited permissions in any subdirectory. If you're willing to set the following command in the <Directory> containers of your choice,
you can configure .htaccess files to override previously set permissions. In this way, you can customize permissions on different virtual hosts. For example, you can configure an intranet site that's limited to your employees and an Internet site for general access on the same Apache server.
You can store an .htaccess file in any Web directory. While you can configure all types of Apache directives in this file, the Red Hat Exam Prep guide suggests that all you need to do is configure host-based and user-based security for the service.
There are many ways to activate the Options directive. The simplest two are Options None and Options All. They would do the following:
None For no custom options in force.
All Allows all options except MultiViews.
You can also set finer options with keywords. Some examples include:
ExecCGI Permits Web pages to run CGI scripts.
FollowSymLinks Permits symbolic links to directories outside of DocumentRoot.
Includes Allows server-side includes.
Indexes Permits FTP-style directory indexing; this directive controls directory indexing, which is the name for file lists that are generated automatically by Apache.
Exercise 9-3: Password Protection for a Web Directory
In this exercise, you'll configure password-protection for your regular user account on a subdirectory of DocumentRoot. This involves use of the AuthType Basic, AuthName, and AuthUserFile directives. This will be done with the standard Apache Web site; virtual hosts are covered in the next major section.
Open the main configuration file, httpd.conf from the /etc/httpd/conf directory, in a text editor.
Navigate below the stanza <Directory "/var/www/html">.
Create your own stanza for a DocumentRoot subdirectory. Assuming you've kept the defaults (and haven't yet created this subdirectory), make it the /var/www/html/test directory. In the default version of httpd.conf, it's just before the commented options for the UserDir directive. The first and last directives in the stanza would look like:
<Directory "/var/www/html/test"> </Directory>
Add the following directives: AuthType Basic to set up basic authentication, the AuthName "Password Protected Test" directive to configure a comment that you should see shortly, and the AuthUserFile /etc/httpd/ testpass directive to point to a password file. Substitute your regular username for testuser in Require user testuser.
<Directory "/var/www/html/test"> AuthType Basic AuthName "Password Protected Test" AuthUserFile /etc/httpd/testpass Require user testuser </Directory>
Check the syntax of your changes with either of the following commands.
# httpd -t # httpd -S
Assuming the syntax checks out, make Apache reread the configuration files:
# apachectl restart
If you're concerned about currently connected users, make Apache reread the configuration file, without disconnections, with the service httpd reload command.
Add an appropriate index.html file to the /var/www/html/test/ directory. It's okay to use a text editor to enter a simple line such as "test was successful". No HTML coding is required.
Create the /etc/httpd/testpass file with an appropriate password. On my system, I created a web password for user michael in the noted file with the following command:
# htpasswd -c /etc/httpd/testpass michael
Additional users can be added without the -c switch.
Test the result, preferably from another system. For example, if your Apache server is configured on enterprise5a.example.net, navigate to http://enterprise5a.example.net/test.
You should now see a request for a username and password, with the comment associated with your AuthName directive. Enter the username and password you just added to /etc/httpd/testpass and observe the result.
Close your browser, and restore any earlier configuration.