7.5. Using the Apache Web Server
Apache is the most widely used web server and is a standard part of Fedora Core. One of the reasons that it has garnered a majority market share is that it is highly configurable and can therefore meet a wide range of web-serving needs. Despite the number of options available, Fedora Core ships Apache with a default configuration that is ready to meet most basic web-serving needs.
7.5.1. How Do I Do That?
# cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf-original
184.108.40.206. Starting Apache
# service httpd start
Whenever the Apache configuration is changed, you must instruct Apache to reload its configuration:
# service httpd reload
220.127.116.11. Testing Apache
Using a web browser on the machine running Apache, access the web location http://localhost/. You will see the test page shown in Figure 7-16.
Figure 7-16. Apache test page confirming operation of the web server
Once you can view this web page on the server, you can attempt to access the page from a remote system using the IP address of the server (such as http://192.168.100.1/), or, if DNS has been set up to allow it, the server's hostname (e.g., http://fedorabook.com/).
18.104.22.168. Installing your own web content
Once the web server is running, place the content you wish to serve in the directory /var/www/html. The default page for each directory is index.html; once you have created /var/www/html/index.html, the test page (Figure 7-16) will no longer appear.
Create subdirectories within /var/www/html to create any directory structure you want. These directories will be reflected in the URLs accessible through the web server. For example, you could create the directory /var/www/html/photos/:
# mkdir /var/www/html/photos
22.214.171.124. Changing the default configuration
Apache can be configured by using Fedora's graphical configuration tool or by editing configuration files, but you can't alternate between the two approaches. Most experienced Apache administrators prefer to directly edit the configuration file because it provides direct access to all of Apache's features and because it is more convenient when accessing a remote server. However, Fedora's graphical configuration tool is quite powerful and is a good place to start if you're not familiar with Apache setup.
126.96.36.199. Configuring Apache graphically
To configure Apache graphically, select SystemAdministrationServer SettingsHTTP (or in KDE, AdministrationServer SettingsHTTP). The httpd configuration dialog, a simple tabbed window (shown in Figure 7-17), will appear.
Figure 7-17. Graphical configuration tool for Apache httpd
Start with the Main tab and enter the server name and webmaster's email address. The server name must contain only alphanumeric characters; it will be used as a hostname and combined with the current domain name to build a fully qualified domain name ( FQDN).
The Available Addresses area is used only if you wish to prevent the web server from using some network interfaces, or if you wish to use a nonstandard TCP/IP port (the default for HTTP is port 80). This is usually left at the default setting.
The Virtual Hosts tab shown in Figure 7-18 is used to configure Apache to respond to requests for multiple web sitesfor example, www.fedorabook.com and www.tylers.info. By default, a single entry is present, labeled Default Virtual Host.
Figure 7-18. Virtual host configuration
To edit an existing entry or add a new entry, use the Edit or Add buttons. In either case, the window shown on the right of Figure 7-18 will appear, with these tabs:
There is also a tab for SSLused for secure, encrypted web servingand a tab for Environment, which is used to pass information to web scripts, but the options on those tabs are not used for basic web serving.
Once the virtual host is configured, click OK to return to the main HTTP configuration window (Figure 7-17).
188.8.131.52. Directly editing Apache's configuration file
The main Apache configuration information is stored in /etc/httpd/conf/httpd.conf. Additional configuration information is stored in the directory /etc/httpd/conf.d/. Per-module configuration files are automatically installed and removed along with Apache modules and web applications such as SquirrelMail.
# cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.backup-1
httpd.conf contains a number of directives, each of which consists of a name and one or more values, listed on a single line with a space after the name and each of the values. The directive names are not case-sensitive, but some of the values are. Values must be quoted if they contain spaces.
These directives are all equivalent:
ServerRoot /etc/httpd ServerRoot "/etc/httpd" ServerRoot '/etc/httpd' SERVERROOT /etc/httpd/ serverroot /etc/httpd
# Note: /etc/httpd is the standard Fedora server root.
Directives are global unless they are placed in a container, which limits the scope to which the directive applies. For example, the <Directory> container causes the contained directives to be applied only to a specific directory (and its subdirectories); here, the directives apply only to the contents of /var/www/html:
<Directory "/var/www/html"> Options Indexes Includes FollowSymLinks AllowOverride None Allow from all Order allow,deny </Directory>
184.108.40.206.1. Configuring the server root and document root
The ServerRoot directive sets the directory that contains all files related to the Apache serverincluding configuration files, logs, modules, and runtime informationexcept the actual content being served. By default, all relative paths specified in httpd.conf are relative to this directory. The default is /etc/httpd:
220.127.116.11.2. Configuring the server administrator, IP address and port, and server name
The directive named ServerAdministrator specifies an email address that can be used to reach the person responsible for running the web server. This address appears on certain error pages. This should be a valid address so that your web visitors can contact you if necessary, but since it can be harvested by web spiders, it is a good idea to use a disposable email address and change it regularly. The default value is root@localhost and should always be changed:
If necessary, you can specify an alternate port, or a specific IP address and a port:
Listen 8000 Listen 192.168.10.1:8000
18.104.22.168.3. Configuring access
<Directory /> Options FollowSymLinks AllowOverride None </Directory>
The Options directive is critical: it specifies what is permitted in these directories. In this case, all access to the root directory and all subdirectoriesin other words, the entire systemis prohibited except as the destination of symbolic links.
The next directory container loosens up the restrictions for /var/www/html and its subdirectories:
<Directory "/var/www/html"> Options Indexes FollowSymLinks AllowOverride None Order Allow,Deny Allow from all </Directory>
The values for the Options directive are selected from this list:
Order, Allow, and Deny are directives that work together to define which remote users may access the directory. Order sets the order in which the Allow and Deny directives are used, and the value must be Allow,Deny or Deny,Allow (the default). The Allow and Deny directives accept a list of full or partial domain names, IP addresses, or IP addresses and netmask or network bit count.
For example, to enable access only from computers on your internal network, assuming your network is 12.200.X.X:
Order Allow,Deny Allow from 22.214.171.124/16 Deny from all
On the other hand, you could enable access only from computers that are not in your internal network:
Order Deny,Allow Deny from 126.96.36.199/255.255.0.0 Allow from all
Or you could exclude access from specific domains:
Order Deny,Allow Deny from .gov ourcompetition.com Allow from all
The AllowOverride directive enables the use of a hidden file, .htaccess, which may be placed in directories to override the configuration of that directory and subdirectories. Although there are several possible values for this directive, it is normally set to None (no overrides are permitted) or AuthConfig (the .htaccess file can control whether a user ID and password are required to access the content of that directory).
The next set of directory containers configure special permissions for the icon, cgi-bin, and error directories in /var/www:
<Directory "/var/www/icons"> Options Indexes MultiViews AllowOverride None Order Allow,Deny Allow from all </Directory> <Directory "/var/www/cgi-bin"> AllowOverride None Options None Order Allow,Deny Allow from all </Directory> <Directory "/var/www/error"> AllowOverride None Options IncludesNoExec AddOutputFilter Includes html AddHandler type-map var Order Allow,Deny Allow from all LanguagePriority en es de fr ForceLanguagePriority Prefer Fallback </Directory>
Alias /icons/ "/var/www/icons/" ScriptAlias /cgi-bin/ "/var/www/cgi-bin/" Alias /error/ "/var/www/error/"
These directives make the indicated directories appear to exist within the document tree; for example, a request for http://<hostname>/icons/text.png is fulfilled using the file /var/www/icons/text.png (instead of /var/www/html/icons/text.png). This permits /var/www/html to remain uncluttered by icons, scripts, and error messages.
Since /cgi-bin/ is aliased using a ScriptAlias directive, it is assumed that all files in that directory are actually scripts (executable programs) rather than document files, regardless of their extension. In the default configuration, this is the only directory that may contain scripts, so you only have to look in one place to check for script vulnerabilities.
188.8.131.52.4. Enabling personal web pages
<IfModule mod_userdir.c> # # UserDir is disabled by default since it can confirm the presence # of a username on the system (depending on home directory # permissions). # UserDir disable # # To enable requests to /~user/ to serve the user's public_html # directory, remove the "UserDir disable" line above, and uncomment # the following line instead: # #UserDir public_html </IfModule>
Comment out the line that reads UserDir disable and uncomment the line which reads UserDir public_html:
<IfModule mod_userdir.c> # # UserDir is disabled by default since it can confirm the presence # of a username on the system (depending on home directory # permissions). # #UserDir disable # # To enable requests to /~user/ to serve the user's public_html # directory, remove the "UserDir disable" line above, and uncomment # the following line instead: # UserDir public_html </IfModule>
Then uncomment the container section <Directory /home/*/public_html>:
# # Control access to UserDir directories. The following is an example # for a site where these directories are restricted to read-only. # <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>
184.108.40.206.5. Using virtual hosts
Virtual hosting permits one web server to serve web pages for multiple hostnames. There are two ways of detecting which host a browser is trying to connect to: the web server can respond to multiple IP addresses and serve different content based on which IP address is used (IP-based virtual hosts), or the web server can serve the content based on the Host: header sent by the browser (name-based virtual hosts).
If you're using a port other than 80, enter it on this line.
Next, create a VirtualHost container for each virtual host. There is an example in the comments near the end of the httpd.conf file:
#<VirtualHost *:80> # ServerAdmin firstname.lastname@example.org # DocumentRoot /www/docs/dummy-host.example.com # ServerName dummy-host.example.com # ErrorLog logs/dummy-host.example.com-error_log # CustomLog logs/dummy-host.example.com-access_log common #</VirtualHost>
Copy and uncomment these lines, substituting the correct values for these directives:
<VirtualHost *:80> ServerAdmin email@example.com DocumentRoot /var/www/html/fedorabook ServerName fedorabook.com ServerAlias www.fedorabook.com ww.fedorabook.com wwww.fedorabook.com ErrorLog logs/fedorabook-error_log CustomLog logs/fedorabook-access_log combined </VirtualHost>
220.127.116.11. Enabling CGI scripts in every directory
Fedora's default Apache configuration permits CGI scripts only in the /cgi-bin/ script alias directory, /var/www/cgi-bin/. This makes it easy to keep an eye on all of the scripts, and many webmasters prefer this.
However, on a complex site with different web applications running, it is often desirable to group files by application, allocating one directory for each application and building a structure within that directory for the scripts, HTML, stylesheets, and multimedia files, rather than mixing the scripts for all of the applications together into a single directory.
AddHandler cgi-script .cgi
<Directory "/var/www/html"> ... Options Indexes FollowSymLinks ExecCGI ... </Directory>
If you want individual users to be able to run scripts, do the same for the ~/public_html directories:
<Directory /home/*/public_html> ... Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec ExecCGI ... </Directory>
18.104.22.168. Password-protecting content
First, configure Apache to permit the use of .htaccess files for authentication configuration. If you're using the graphical configuration tool, select the checkbox labeled "Let .htaccess files override directory options."
<Directory "/var/httpd"> ... AllowOverride AuthConfig ... </Directory>
This option is enabled by default for ~/public_html directories.
An .htaccess file is similar to an httpd.conf file, but it is placed in the directory that you wish to protect. Here is an example:
AuthType Basic AuthName "team scores" AuthUserFile /etc/httpd/team_scores_password Require valid-user
The four directives in this file are required for basic password protection:
Figure 7-19. Browser dialog box showing the AuthName value
For security, the password file must be located outside of the directories served by Apache. It is managed with the htpasswd command; to create the file and set the first password, use the -c option and provide the password filename and user ID as arguments:
# htpasswd -c /var/httpd/team_scores_password chris New password: bigsecret Re-enter new password: bigsecret Adding password for user chris
Once the file has been created, leave out the -c option, or you'll erase existing entries:
# htpasswd /var/httpd/team_scores_password diane New password: neverguess Re-type new password: neverguess Adding password for user diane
# htpasswd -b /var/httpd/team_scores_password frank TheBestPitcher Adding password for user frank
If you enter an existing user ID instead of a new one, the old password will be updated instead of creating a new record:
# htpasswd -b /var/httpd/team_scores_password diane new-secret Updating password for user diane
.htaccess files have traditionally been used for access control, and they work well for ~/public_html directories because users can configure them on their own. For directories in your document root, it's just as easy to place the authentication directives in a directory container in httpd.conf:
<Directory /var/www/html/scores/> AuthType Basic AuthName "team scores" AuthUserFile /etc/httpd/team_scores_password Require valid-user </Directory>
7.5.2. How Does It Work?
Apache is the most widely used web server software in the world. It is actively developed by the Apache Software Foundation (http://apache.org) and can be scaled from a static personal web site on a desktop-class computer to a extremely high-volume database-backed web site running on clusters of computers.
In order to meet such a wide range of needs, Apache can be configured using over 370 distinct directives. Although many different graphical configuration tools have been developed, none of them can configure all directives or handle all possible deployment scenarios for the software.
The Fedora graphical configuration tool for Apache is named system-config-httpd. The options entered into the configuration dialogs are saved in XML and then converted into a working httpd.conf by using the XSLT transformation stylesheet /usr/share/system-config-httpd/httpd.conf.xsl. You can customize that file to change the generated httpd.conf file.
The actual Apache server program is /usr/sbin/httpd. It can be started or stopped with the service command or system-config-services, which use the Fedora-specific script file /etc/rc.d/init.d/httpd; it can also be started and stopped with Apache tool /usr/sbin/apachectl, but the SELinux security context will be different.
Apache listens on the configured ports and waits for incoming connections from client software such as web browsers. Once a connection is established, the client sends a request, plus additional headers with information such as the client software version and preferred languages and encodings, followed by a blank line. The server responds with a result code, additional headers, a blank line, and then the content requested (or an error message). In its most basic form, the conversation goes something like this (the request is shown in bold; the response headers are in italic, and the rest of the listing is the body of the response):
GET /testfile.html HTTP/1.1 Host: www.fedorabook.com HTTP/1.1 200 OK Date: Wed, 01 Mar 2006 02:49:54 GMT Server: Apache/2.2.0 (Fedora) Last-Modified: Mon, 27 Feb 2006 21:25:54 GMT ETag: "f0518-4a-5b0edc80" Accept-Ranges: bytes Content-Length: 85 Connection: close Content-Type: text/html; charset=UTF-8 <html> <head><title>Test</title></head> <body> <i><p>Success!</p></i> </body> </html>
In an elementary configuration, Apache is responsible for mapping the web namespace to the local filesystem namespace, performing access control and logging, collecting the requested resource (either by reading a file or executing code), and sending the resource to the client.
7.5.3. What About...
22.214.171.124. ...interpreting the Apache logfiles?
126.96.36.199 - - [28/Feb/2006:22:01:33 -0500] "GET / HTTP/1.1" 200 956
The fields here are the IP address of the remote host (188.8.131.52); the remote user login name (-); the authenticated username on the local system (-, because the user did not authenticate); the date, time, and time zone of the request ([28/Feb/2006:22:01:33 -0500]); the request string (GET / HTTP/1.1); the status code returned to the client (200, meaning OK); and the number of bytes sent to the client (956).
184.108.40.206 - - [28/Feb/2006:22:01:33 -0500] "GET / HTTP/1.1" 200 956 "http://www.fedorabook.com/index.html" "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.12) Gecko/20060202 Fedora/1.0.7-1.2.fc4 Firefox/1.0.7"
The additional fields are the referring page, which linked to or contained the information requested (http://www.fedorabook.com/index.html), and the user agent header, which describes the client software (Firefox on a Fedora system in this case). The user agent information is interesting, but the referrer information is critical if you want to analyze where your visitors are coming from, which pages they visit first, and how they progress through your web site.
The error logfile contains entries like this:
[Tue Feb 28 22:01:33 2006] [error] [client 220.127.116.11] File does not exist: /var/www/html/favicon.ico
This indicates the date and time, the fact that this is an error, the client IP address, and the detail of the error.
18.104.22.168. ...using a more secure authentication scheme than Basic?
To use digest authentication, use the same authentication configuration as you would for basic authentication, but substitute Digest for the AuthType:
AuthType Digest AuthName "prices " AuthUserFile /var/www/digest Require valid-user
Create the password file using the htdigest command instead of htpasswd. htdigest requires one additional argument in front of the username, called the realm; copy the value from the AuthName directive and use it for the realm. Here is an example:
# htdigest -c /var/www/digest prices chris Adding password for chris in realm prices. New password: confidentialpassword Re-type new password: confidentialpassword # htdigest /var/www/digest prices diane Adding user diane in realm prices New password: bigsecret Re-type new password: bigsecret
7.5.4. Where Can I Learn More?