Wednesday, July 28, 2010

Apache Configuration


Apache is a very large piece of software that has hundreds of configuration options and possible setups. There are a number of books that have been written about Apache. This section will look at the most common attributes that can be configured and how they affect your system. It is not meant to be a complete reference to Apache. Version 2.0 is expected to be released within the next year, and with it will come numerous changes and additions. The current shipping version, 1.3.x, is discussed here.

File Locations

Apple has done an excellent job of making the Apache Web server configuration manageable for machines with large numbers of personal Web sites. Instead of a single monolithic configuration, like the standard Linux or Windows installation, the server can be configured on two different levels:
  • System-wide configuration— (path: /etc/httpd/httpd.conf) This is the master configuration file. It contains information about the system as a whole—what directories are accessible, what plug-ins are in use, and so on. Changes to the Web server as a whole are included here.
  • User-directory configuration— (path: /etc/httpd/users/ username.conf ) When the MacOS X Users System Preference panel creates a new account, it automatically adds a basic configuration file for that user within the /etc/httpd/users directory. This mini configuration file determines the security for the Web pages within a user's Sites folder.
By splitting up the configuration, the administrator can quickly adjust Web permissions on a given account. To edit the user or system configuration, you must either log in (or su) as root, or use sudo.
Note
Although the user configuration files are stored based on the user's name, they have no real connection to the actual user other than containing the path to a personal Sites folder. These files can contain any Apache configuration option, including those that affect other users. The division by username is for ease of editing only.
Apache approaches configuration in a very object-oriented manner. The configuration files are XML-like, but not compliant, so don't attempt to edit them using the plist editor. Apache calls each configuration option a directive. There are two types of configuration directives:
  • Global— Global directives affect the entire server. Everything from setting a name for the Web server to loading and activating modules.
  • Container-based— An Apache container is one of a number of objects that can hold Web pages. For example, a directory is a container, a virtual host is a container, and an aliased location is also a container. If you don't know what these are, don't worry, we'll get there. For now, just realize that each container can be configured to limit who has access to what it contains, and what pages within it can do.

Global Options

The global options can fall anywhere within the server configuration file. If you're running a heavy-traffic Web site you'll definitely want to change the defaults. By default, Apache starts only one server and keeps a maximum of five running at any given time. These numbers do not allow the server to quickly adapt to increased server load.
Table 27.2 documents the most important configuration directives contained in the /etc/httpd/httpd.conf file. They are listed in the order that you're likely to encounter them in the httpd.conf file.
Note
Several of the Apache directives refer to the number of server processes that should be started. These processes are subprocesses of the master Apache process. When you use apachectl to control the server, you are controlling all the Apache processes.

Table 27.2. Global Apache Directives

DirectiveDescription
ServerTypeThe Server type determines how Apache starts. Standalone servers are the default. Inetd-based servers use the inetd process to activate a server only when it is accessed. This is inefficient and not recommended for all but the lowest- traffic systems.
ServerRoot The base path of the Apache binary files.
PidFileThe path (and filename) of the file that should store Apache's process ID.
Timeout The number of seconds that Apache will wait for a response from a remote client. After the time period expires, the connection will be closed.
KeepAlive Allow more than one request per connection. This is the default behavior ofHTTP/1.1 browsers. Shutting this off might result in a higher server load and longer page load times for clients.
MaxKeepAliveRequests<#>The maximum number of requests that can be made on a single connection.
KeepAliveTimeoutThe amount of seconds to wait between requests on a single connection.
MinSpareServers <#>Apache automatically regulates the number of running servers to keep up with incoming requests. This is the minimum number of servers kept running at any given time.
MaxSpareServers <#>The maximum number of servers that will be kept running when there is no load. This is not a limit on the total number of server processes to start—it limits the number of unused processes that will be kept running to adapt to changes in load.
StartServers <#>The number of servers to start when Apache is first launched.
MaxClients <#>The MaxClients directive sets an upper limit on the number of servers that can be started at a given time.
MaxRequestsPerChild<#>Some systems have memory leaks. A memory leak is a portion of the system software in which memory usage slowly grows in size. Apache recognizes that memory leaks might exist and will automatically kill a server after it has processed a given number of requests, freeing up any memory it was using. The server process is then restarted—fresh and ready to go.
LoadModule Loads an Apache module. Many modules will be installed automatically, so you'll rarely need to adjust anything.
AddModuleActivates a loaded module.
Port <#>The port number that the Apache server will use. The standard HTTP port is 80.
User The user ID that Apache will run under. Apache has the full access permissions of this user, so never, ever, EVER, set this to the root account.
Group The group ID that Apache will run under. Like the User directive, this should never be set to a privileged account. If it is, any broken Web applications could compromise your entire computer.
ServerAdmin The e-mail address of the Web server operator.
ServerName If your server has several different hostnames assigned, use the ServerName directive to set the one that will be returned to the client browser. This cannot be an arbitrary name, it must exist!
DocumentRoot This defines the path to the main server HTML files. The Mac OS X default is /Library/WebServer/Documents.
UserDir The personal Web site directory within each user's home directory. As you already know, OS X uses Sites—the default used in most Apache installs is public_html.
DirectoryIndex When a URL is specified using only a directory name, the Web server will attempt to display a default HTML file with this name.
AccessFileNameThe name of a file that, if encountered in a directory, will be read for additional configuration directives for that directory. Typically used to password-protect a directory. The default name is .htaccess.
DefaultTypeThe default MIME type for outgoing documents. HTML files should be served using the text/html type.
HostnameLookupsIf activated, Apache will store the full hostname of each computer accessing the server rather than its IP address. This is not recommended for servers with more than a trivial load. Hostname lookups can greatly slow down response time and overall server performance.
TypesConfig The path to a file that contains a list of MIME types and file extensions that should be served using that MIME type. For example, the type text/html is applied to files with the .html extension. The default MIME types are located at /private/etc/httpd/mime.types.
LogLevel One of eight different error log levels: debug, info, notice, warn, error, crit, alert, or emerg.
LogFormat  Defines a custom log format and assigns it to a name. Discussed shortly.
CustomLog  Sets a log filename and assigns it to one of the LogFormat types.
Alias  Creates a URL that aliases to a different directory on the server.
ScriptAlias  Creates a URL that aliases to a directory containing CGI applications on the server.
Redirect  Redirects (transfers) a client from one URL to another. Can be used to transfer between URLs on the same server, or to transfer a client accessing a local Web page to a remote site.
AddType  Adds a MIME-type without editing the mime.types file.
AddHandler server-parsed Activates server-side includes for files with the specified extension. The default SSI extension is .shtml.
AddHandler send-as-isWhen activated, files with the defined extension will be sent directly to the remote client as is.
AddHandler imap-fileSets the extension for server-side imagemap features. All modern Web browsers use client-side image maps, but, if you need compatibility with Netscape 1.0 browsers, you'll need to use server-side clients.
ErrorHandler  Sets an error handler from any one of the standard HTML error messages. This will be discussed in greater detail shortly.
Include Reads multiple configuration files from a directory. This is set to /etc/httpd/users.
This is only a partial list of commonly used directives—for a complete list, visit Apache's Web site. To get a handle on configuration, let's take a look at a few different directives in use. Each of these commands, because of its global nature, can be used anywhere within the /etc/httpd/httpd.conf configuration file.

Aliases

As you build a complex Web server, you'll probably want to spread files out and organize them using different directories. This can lead to extremely long URLs, such as /mydocuments/work/project1/summary/data/. This URL is a bit bulky to be considered convenient if it were commonly accessed or publicly advertised.
Thankfully, you can shorten long URLs by creating an alias. Aliases work in a similar manner as the Mac OS X Finder aliases. A short name is given that, when accessed, will automatically retrieve files from another location. To alias the long data URL to something shorter, such as /data/, you would use the following command:
Alias /data/ /mydocuments/work/project1/summary/data
Aliases can be used to access files anywhere on the server, not just within the server document root. Obviously, the files in the alias directory need to be readable by the Apache process owner.

Redirection

Web sites change. URLs change. For established Web sites, changing the location of a single page can be a nightmare for users—bookmarks break and advertised URLs fail. Although this might seem trivial to experienced Web surfers, some users might not be persistent enough to figure out where the page has gone.
Many Web sites put a redirection page up in place of the missing page. This type of redirection relies on a browser tag to take the user to another URL after a set timeout period. This is effective for most modern browsers, but it takes several seconds between loading the original page and the redirection. In addition, a page needs to be created for each location that might be accessed by the client. This could be hundreds of pages!
A simpler, faster, neater way is to use the Redirect directive. Redirect forces the client browser to transfer to a different URL before the original page even opens. Entire URL structures can be redirected using a single command. The destination URL can even be on a remote server!
For example, if you've decided to move all of the files under a URL called /ourcatalog/toys to a new server with the URL www.mynewstoreonline.com/toys, you could use
Redirect /ourcatalog/toys http://www.mynewstoreonline.com/toys.
If a user attempted to access the URL /ourcatalog/toys/cooltoy1.html, he would immediately be transferred to www.mynewstoreonline.com/toys/cooltoy1.html.
Using redirects is more reliable and transparent for the end user. Avoid using HTML-based redirects and rely on the Apache Redirect directive to hide changes in the structure of your Web site.

Logs

Apache on Mac OS X stores its log files in the directory /var/log/httpd. By default, there are two logs—access_log and error_log.
The access_log file contains a record of what remote computers have accessed Apache, what they asked for, and when they did it. For example:
140.254.85.2 - - [02/May/2001:16:49:47 -0400] "GET /extimage/images/26_thumb.jpg HTTP/1.1"

ccc.gif
 200 27012
140.254.85.2 - - [02/May/2001:16:49:47 -0400] "GET /extimage/images/27_thumb.jpg HTTP/1.1"

ccc.gif
 200 35793
140.254.85.2 - - [02/May/2001:16:49:47 -0400] "GET /extimage/images/28_thumb.jpg HTTP/1.1"

ccc.gif
 200 26141
140.254.85.2 - - [02/May/2001:16:49:47 -0400] "GET /extimage/images/30_thumb.jpg HTTP/1.1"

ccc.gif
 200 29316
140.254.85.2 - - [02/May/2001:16:49:47 -0400] "GET /extimage/images/ 29_thumb.jpg HTTP/1

ccc.gif
.1" 200 33626
This log excerpt shows five requests for .jpg images from the Apache server. There are five fields stored with each log entry:
  • Remote Client— The machine accessing the Apache Web server. In these examples, that client is 140.254.85.2.
  • Date and Time— A time and date stamp for when the request was made. These five requests were made on May 2, 2001 at 4:49 p.m.
  • Request String— The actual request that the remote machine made. Most requests begin with GET and are followed by the resource to retrieve, then the version of the HTTPprotocol to retrieve it with. The five requests in the example are for files within the /extimage/images/ directory of the server's documents folder.
  • Response Code— Identifies how the remote server responded to the request. The code 200 shows that the request was successfully served. A 404, on the other hand, indicates that the request couldn't be satisfied because the resource wasn't found. The response codes for HTTP 1.1 are available from http://www.w3.org/protocols/rfc2616/rfc2616-sec6.html.
  • Response Size— The number of bytes sent to the remote client to satisfy the request.
Note
There are actually seven fields in this log format. The second and third fields contain a - that indicates a value could not be determined. It is unlikely you'll see values here.
Apache knows this style of access log as the common log format. Log formats are completely customizable using the LogFormat directive. The common format is defined as
LogFormat "%h %l %u %t \"%r\" %>s %b" common
Each of the %h elements denotes an element to be stored in the log file. The \" is an escaped quote, meaning that a quote will also be stored in that location. You can build a log format using:
  • %h— Hostname of the requesting computer.
  • %a— IP address of the remote computer.
  • %r— Request string.
  • %t— Time of request.
  • %T— Amount of time taken to serve the request.
  • %b— Bytes sent.
  • %U— URL Path requested.
  • %P— Process ID of the child that served the request.
  • %>s— The last status reported by the server.
  • %{Referer}i— The referring URL (the URL that contained the link to current page).
  • %{User-Agent}i— The string identifies the remote browser.\
Tip
This is only a partial listing. You can find a complete list of the Apache Log elements athttp://httpd.apache.org/docs/mod/mod_log_config.html#logformat.
You define a log format by using the LogFormat line, a string containing the format elements, and a name for the file. For example, to define a log called mylog that stores only the hostname of the remote client for each request, you would use:
LogFormat "%h" mylog
Except for custom solutions, you'll be best served by one of Apache's default log formats. Although the common log is common, it probably isn't the best thing for doing extensive reporting. A better choice is Apache's combined log format. The combined log format includes referer and user-agent strings with each request. Most Web analysis packages use the combined log style.
To activate a log format, use the CustomLog directive, followed by the pathname for the log and the log name. To activate the combined log format, use within the /etc/httpd/httpd.conf file:
CustomLog "/private/var/log/httpd/access_log" combined
Log files are an important part of any Web server. They can provide important data on the popular pages of the server, errors that have occurred, and how much traffic your system is getting.
Note
The error_log is not shown here because it should only contain startup and shutdown messages. If a security violation or configuration error occurs, it is recorded to this file. In addition, programmers can find detailed information about program errors written to this location. We'll see it again later, so don't worry!

Log Analysis Software

There is an abundance of log analysis software available for Unix operating systems (and thus MacOS X). Log analysis is more of an art than a science. As you've seen by looking at the logfile formats, you can determine the remote host, requested resource, and time of request from the logfile. Unfortunately, many analysis packages try to go even further by providing information on how long visitors were at your page, or where (geographically) they are located. Neither of these pieces of information is tracked in the Apache logs.
To determine how long someone has been at your site, the analysis software must look at all accesses and determine which are related, and the amount of time between them. This is entirely guesswork on the part of the server. Assume a user opens her browser, views a page, walks away for 15 minutes, and then accidentally clicks on another page before closing her browser. If the software is set with a session timeout period greater than 15 minutes, it sees two separate hits on the page. The software assumes the user spent at least 15 minutes reading both pages, and registers that the browser spent 30 minutes on the site. In reality, only a minute or two was spent looking at the site content.
When determining geographic information, analysis software performs an even more amazing task—locating what city a user is coming from. To do this, the analysis utility looks up the domain of the client accessing the system. It retrieves the city and state that the domain was registered in. Unfortunately, this is almost completely worthless data. I recently ran a WebTrends report on a local (Columbus, Ohio) e-commerce site to see how it would perform.
The results showed that more than 95% of the remote requests are coming from Herndon, VA. In fact, an analysis of other (non-related) sites shows a similar amount of traffic from Virginia. The reason is simple—the RoadRunner cable model network. The rr.com domain is registered in Herndon, VA. There are thousands of users with RoadRunner-based access—no matter where they are actually coming from, the report displays Herndon, VA. That isn't very useful, is it?
The final Web statistic fallacy is the number of hits a page receives. Many people are delighted when they find that they're getting a few thousand hits a day, but they don't realize what constitutes a hit. The Apache Web server counts any information requested as a hit. If a Web page has ten tiny icons on it, it takes at least 11 hits to load the page (1 for the page, 10 for the icons). As pages become more graphically rich, it takes even more requests to load them. A 10,000-hit-per-day site might only be serving a few hundred pages per day!
As long as you realize that log analysis data can be deceiving, it can still provide useful information. Here are a few popular Web statistics packages available for Mac OS X:
  • Analog— The world's most popular statistics software, Analog provides all the basics in a very simple layout. Analog doesn't create DTP-quality graphs or have the snazziest interface you've ever seen, but it's fast, does a good job, and it's free.http://www.summary.net/soft/analog.html.
  • Sawmill— The Sawmill software provides complete statistics including search engine identification and a unique Calendar view for located information by month and date. Sawmill is a commercial package costing $99 and up. http://www.flowerfire.com/sawmill/samples.html.
  • Summary— Summary is a great entry-level piece of software with advanced reporting features. Data can be exported directly to spreadsheet format for external graphing. Single-user licenses for Summary start at $59. http://summary.net/download.html.
  • Urchin— Urchin has, without a doubt, the most user-friendly and attractive interface, as shown in Figure 27.2. Behind the interface is one of the most comprehensive Web statistics applications available—exceeding such industry stand-bys as WebTrends. Urchin is the ultimate stats solution for serious Web sites. Urchin starts at $199 for an individual server license, but can operate in Lite mode for free. http://www.urchin.com/download/.
    27fig02.jpgFigure 27.2 Web statistics can provide valuable information about your site's operation. The Urchin log analysis software is shown here.
Note
I do not endorse any stats package over another. The primary difference in Web statistics packages is the interface and data presentation. Remember, there is a very finite amount of data stored in the log file. The best log analysis software is one that creates the reports with the information you need, in the format you need it.

Container Options

The second type of Apache directives are container based. These directives control how Apache serves a certain group of files. Files are chosen based on pattern or location and are denoted by a start and end tag in the Apache configuration file. For example, the /etc/httpd/users/ configuration files define a container consisting of each user's Sites directory. This is the configuration file created for my jray user account (in my case, that file would be /etc/httpd/httpd.conf):

Options Indexes MultiViews
AllowOverride None
Order allow,deny
Allow from all

In this example, the directory /Users/jray/Sites is the container. Web pages within this container can use the Indexes and Multiviews options. The AllowOverride, Order, and Allow directives control who has access to the files within this container. This will be explained in more detail shortly.
Besides a directory container, there are other constructs that can also be added to the configuration file(s):
  • Directory— Creates a directory-based container. All files within the named directory are part of the container.
  • DirectoryMatch— Like Directory, but uses a regular expression to match directory names. Check Chapter 22, "Perl Scripting and SQL Connectivity," for more information on regular expressions.
  • Files— Groups files based on their name. All files matching the specified name are included in the container. The filename should be given exactly, or using the ? and * wildcards to match a single unknown character or any number of unknown characters.
  • FilesMatch— Similar to Files, but matches filenames based on a regular expression rather than an exact name.
  • Location— The Location container is similar to Directory but matches Web content based on a URL, rather than a full-server directory.
  • LocationMatch— If you've been following along, you'll probably guess correctly that LocationMatch is the same as Location, but matches the URL based on a regular expression.
  • VirtualHost— The VirtualHost container defines a virtual server within the main server. For external clients, the virtual host appears identical to any other Web server. To you, the system administrator, it is a directory on your server that gets its very own domain name. You'll see how this can be set up shortly.
Within the container objects, the administrator can add a number of directives to control access to the contents, or what special features are available in that location. Table 27.3 includes the container directives you'll encounter most often. We're going to explicitly set up password protection and virtual hosting shortly because this can be a bit tricky just going on the directive definitions alone.

Table 27.3. Apache Container Directives

DirectiveDescription
OptionsSets the special abilities of the server container. There are eight possible options; each can be preceded by an optional + or – to add or remove it. ExecCGI—Enables CGI execution; FollowSymLinks—Follow symbolic links in the directory; Includes—Enable server-side includes, IncludeNOEXEC—Enable server-side includes without allowing application execution; Indexes—Displays a directory listing if an index document doesn't exist; MultiViews—Activates multiple views using content negotiation; SymLinksIfOwnerMatch—Follow symbolic links only if the owner of the link matches the owner of the linked directory; and All—Enable all options.
AllowOverride Chooses the server-defined directives that a local hta c cess file can override. The .htaccess file is used to apply directives outside of the main Apache server configuration and can be edited by any user with access to the directory. For that reason, it is important to allow only trusted users to override options. None—disables all overrides; All—allows all server directives to be overridden, or specifies a combination of AuthConfig, FileInfo, Indexes, Limit, or Options to allow these directive types to be overridden.
Order |Allow> ,Allow>Controls the order in which security controls are evaluated. Whether or not the list of allowed hosts (Allow) or denied hosts (Deny) is checked first.
Allow fromtworks |all >A list of IP addresses, networks and subnets, or domain names that can be allowedaccess to the resource.
Deny fromtworks |all >A list of IP addresses, networks and subnets, or domain names that should bedenied access to the resource.
AuthType Attaches HTTP authorization password protection to a directory.
AuthNameIdentifies the password-protected resource to the end user.
AuthUserFileSets a path to the userfile being used for authentication.
Require user|group| valid userAllows only listed users, groups, or any valid user to access a directory. The users and groups are not Mac OS X users. They are created with the htpasswd command.
ErrorDocumentUsed to substitute a custom-error page in place of the default Apache pages. Use the standard HTTPD error codes (such as 404) and a path to the HTML page to display when the error occurs within the given resource.
ServerAdminThe e-mail address of the administrator of a virtual host.
DocumentRootThe root-level directory for a virtual host.
ServerNameThe fully qualified domain name for a virtual host, such as www.poisontooth.com.
Now let's see how these directives can be used to refine and secure your Apache Web server.

Password Protection: htpasswd

Password protecting a directory is extremely simple. For example, suppose a user wants to password protect his entire public Web site for development purposes. The first step is to set up a username and password file that will contain the login information for those who are allowed to access the resource. This is accomplished using htpasswd. There are two steps to the process—first, create a new password file with a single user; second, add additional usernames/passwords to it.
To create a new file, use the syntax htpasswd -c   . For example:
[primal:~/Sites] jray% htpasswd -c /Users/jray/webpasswords jray
New password:
Re-type new password:
Adding password for user jray
A new password file (/Users/jray/webpasswords) is created, and the initial user jray is added.
Subsequent users can be added by calling htpasswd -b < pat name   :
[primal:~/Sites] jray% htpasswd -b /Users/jray/webpasswords testuser testpass
Adding password for user testuser
The password file now has two entries: the initial jray user, and now testuser.
Next, create a directory container that encompasses the files that need to be protected. Because this example is protecting a personal Web site, the container already exists as a username .conf file in /etc/httpd/users:

Options Indexes MultiViews ExecCGI
AllowOverride None
Order allow,deny
Allow from all

Note
This example file has been modified slightly since the initial Mac OS X installation. The Options directive includes ExecCGI to allow CGI development to take place.
To this directory container, add AuthType, AuthName, AuthUserFile, and R e quire directives. You must be root or using sudo to edit the file:

AuthType Basic
AuthName "John's Development Site"
AuthUserFile /Users/jray/webpasswords
Require valid-user
Options Indexes MultiViews ExecCGI
AllowOverride None
Order allow,deny
Allow from all

The AuthUserFile is set to the name of the password file created with htpasswd, whereas the Require valid-user directive allows any user in the password file to gain access to the protected resource. To activate the authentication, use sudo /usr/sbin/apachectl restart:
[primal:~/Sites] jray% sudo /usr/sbin/apachectl restart
/usr/sbin/apachectl restart: httpd restarted
Attempting to access the /Users/jray/Sites directory (~jray) now opens an HTTP authentication dialog, as seen in Figure 27.3.
27fig03.jpgFigure 27.3 The directory is now password protected.
Access to a directory can be restricted even further using the Allow, Deny, and Order directives.

Restricting Access by Network

To create more stringent control over the users who can access a given resource, use Allow and Deny to set up networks that should or shouldn't have access to portions of your Web site. This is extremely useful for setting up intranet sites that should only be accessible by a given subnet. For example, assume that you want to restrict access to a resource from everyone except the subnet 192.168.0.x. The following rules define the access permissions:
Allow from 192.168.0.0/255.255.255.0
Deny from all
Because there isn't an ordering specified, what really happens with these rules is ambiguous. Is the connection allowed because of the allow statement? Or denied because all the connections are denied?
To solve the problem, insert the Order directive:
Order Deny,Allow
Allow from 192.168.0.0/255.255.255.0
Deny from all
With this ordering, an incoming connection is first compared to the deny list. Because all access is denied by default, any address matches this rule. However, the Allow directive is used for the final evaluation of the connection and will allow any connection from the network 192.168.0.0 with the subnet 255.255.255.0.
Using different orderings and different Allow/Deny lists, you can lock down a Web site to only those people who should have access, or disable troublesome hosts that misuse the site.
Tip
As with any change to the Apache configuration file, you must use /usr/sbin/apachectl to restart the server.
An alternative to restarting is to add an .htaccess file to the directory you want to protect. This file can contain any of the standard directory container directives and will be automatically read when Apache attempts to read any file from the directory.

Virtual Hosts

A virtual host is a unique container object, in that it can define an entirely separate Web space unrelated to the main Apache Web site or user sites. For example, the three domainspoisontooth.comvujevich.com, and shadesofinsanity.com are all being served from a single computer. To the end user, these appear to be different and unique hosts. To Apache, however, they're just different directories on the same hard drive.
There are two types of virtual hosts, name-based and IP-based:
  • Name-based— Name-based virtual hosts rely on the HTTP/1.1 protocol to work. A single IP address is used on the server, but there are multiple DNS name entries for that single address. When connecting to the server, the client browser sends a request for a Web page, along with the name of the server it should come from. Apache uses that information to serve the correct page. This works for all but the oldest 2.0 revision browsers.
  • IP-based— IP-based virtual hosts rely on Apache's capability to listen to multiple IP addresses simultaneously. Each domain name is assigned to a different IP address. Apache can differentiate between the different incoming addresses and serve the appropriate documents for each. This works on any browser, but is costly in terms of the IP addresses that it consumes.
To set up a virtual host, you must first have an IP address and a domain name assigned for the host. If you're using name-based hosts, you will have a single IP address but multiple hostnames. Your ISP or network administrator should be able to help set up this information.
Tip
Mac OS X users who are attempting to configure IP-based virtual hosts will find that no GUI currently exists for adding multiple addresses to a single machine. Luckily, they can be added from the command line using ifconfig  alias dress> 255.255.255.255. For most single network card systems, the interface will be en0. AirPort cards are usually identified with en1. For example:

ifconfig en0 alias 192.168.0.200 255.255.255.255
This adds the IP address 192.168.0.200 as an additional address to the Mac OS X system.
There are only two differences in the Apache configuration of name-based and IP-based virtual hosts. Name-based hosts must include the NameVirtualHost directive, whereas IP-based hosts will need to use Listen to inform Apache of all the available addresses.
Let's take a look at two different ways to configure the virtual hosts www.mycompany.com andwww.yourcompany.com. First, using named-based hosting:
Assume that both mycompany and yourcompany domain names point to the IP address 192.168.0.100. To configure name-based virtual hosts, you could add the following directives to the end of the /etc/httpd/httpd.conf file:

NameVirtualHost 192.168.0.100

ServerName www.mycompany.com
DocumentRoot /Users/jray/mycompany
ServerAdmin president@mycompany.com


ServerName www.yourcompany.com
DocumentRoot /Users/jray/yourcompany
ServerAdmin president@yourcompany.com

The NameVirtualHost sets up the IP address that Apache will expect multiple domain name requests to come in on. The two VirtualHost directives define the basic properties of the two sites: what their real domain names are, where the HTML documents are loaded, and the e-mail address for the person who runs the site.
Creating this same setup using IP-based hosts doesn't require much additional effort. For this sample configuration, assume that www.mycompany.com has the address 192.168.0.100 andwww.yourcompany.com uses 192.168.0.101. The configuration becomes:

Listen 192.168.0.100
Listen 192.168.0.101

ServerName www.mycompany.com
DocumentRoot /Users/jray/mycompany
ServerAdmin president@mycompany.com


ServerName www.yourcompany.com
DocumentRoot /Users/jray/yourcompany
ServerAdmin president@yourcompany.com

This time, the Listen directive is used to tell Apache to watch for incoming Web connections on both of the available IP addresses. The VirtualHost containers remain the same, except they now use different IP addresses for the two different sites.
Virtual hosting provides an important capability to the Mac OS X Web server. Although available with a GUI configuration tool in the Mac OS X Server, the Apache distribution included in Mac OS X is every bit as powerful. It just takes a bit of manual editing to get things done!