1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
4<html xmlns="http://www.w3.org/1999/xhtml">
5  <head>
6    <meta name="generator" content="HTML Tidy, see www.w3.org" />
7
8    <title>An In-Depth Discussion of VirtualHost Matching</title>
9  </head>
10  <!-- Background white, links blue (unvisited), navy (visited), red (active) -->
11
12  <body bgcolor="#FFFFFF" text="#000000" link="#0000FF"
13  vlink="#000080" alink="#FF0000">
14        <div align="CENTER">
15      <img src="../images/sub.gif" alt="[APACHE DOCUMENTATION]" />
16
17      <h3>Apache HTTP Server Version 1.3</h3>
18    </div>
19
20
21    <h1 align="CENTER">An In-Depth Discussion of VirtualHost
22    Matching</h1>
23
24    <p>This is a very rough document that was probably out of date
25    the moment it was written. It attempts to explain exactly what
26    the code does when deciding what virtual host to serve a hit
27    from. It's provided on the assumption that something is better
28    than nothing. The server version under discussion is Apache
29    1.2.</p>
30
31    <p>If you just want to "make it work" without understanding
32    how, there's a <a href="#whatworks">What Works</a> section at
33    the bottom.</p>
34
35    <h3>Config File Parsing</h3>
36
37    <p>There is a main_server which consists of all the definitions
38    appearing outside of <code>VirtualHost</code> sections. There
39    are virtual servers, called <em>vhosts</em>, which are defined
40    by <a
41    href="../mod/core.html#virtualhost"><samp>VirtualHost</samp></a>
42    sections.</p>
43
44    <p>The directives <a
45    href="../mod/core.html#port"><samp>Port</samp></a>, <a
46    href="../mod/core.html#servername"><samp>ServerName</samp></a>,
47    <a
48    href="../mod/core.html#serverpath"><samp>ServerPath</samp></a>,
49    and <a
50    href="../mod/core.html#serveralias"><samp>ServerAlias</samp></a>
51    can appear anywhere within the definition of a server. However,
52    each appearance overrides the previous appearance (within that
53    server).</p>
54
55    <p>The default value of the <code>Port</code> field for
56    main_server is 80. The main_server has no default
57    <code>ServerName</code>, <code>ServerPath</code>, or
58    <code>ServerAlias</code>.</p>
59
60    <p>In the absence of any <a
61    href="../mod/core.html#listen"><samp>Listen</samp></a>
62    directives, the (final if there are multiple) <code>Port</code>
63    directive in the main_server indicates which port httpd will
64    listen on.</p>
65
66    <p>The <code>Port</code> and <code>ServerName</code> directives
67    for any server main or virtual are used when generating URLs
68    such as during redirects.</p>
69
70    <p>Each address appearing in the <code>VirtualHost</code>
71    directive can have an optional port. If the port is unspecified
72    it defaults to the value of the main_server's most recent
73    <code>Port</code> statement. The special port <samp>*</samp>
74    indicates a wildcard that matches any port. Collectively the
75    entire set of addresses (including multiple <samp>A</samp>
76    record results from DNS lookups) are called the vhost's
77    <em>address set</em>.</p>
78
79    <p>The magic <code>_default_</code> address has significance
80    during the matching algorithm. It essentially matches any
81    unspecified address.</p>
82
83    <p>After parsing the <code>VirtualHost</code> directive, the
84    vhost server is given a default <code>Port</code> equal to the
85    port assigned to the first name in its <code>VirtualHost</code>
86    directive. The complete list of names in the
87    <code>VirtualHost</code> directive are treated just like a
88    <code>ServerAlias</code> (but are not overridden by any
89    <code>ServerAlias</code> statement). Note that subsequent
90    <code>Port</code> statements for this vhost will not affect the
91    ports assigned in the address set.</p>
92
93    <p>All vhosts are stored in a list which is in the reverse
94    order that they appeared in the config file. For example, if
95    the config file is:</p>
96
97    <blockquote>
98<pre>
99    &lt;VirtualHost A&gt;
100    ...
101    &lt;/VirtualHost&gt;
102
103    &lt;VirtualHost B&gt;
104    ...
105    &lt;/VirtualHost&gt;
106
107    &lt;VirtualHost C&gt;
108    ...
109    &lt;/VirtualHost&gt;
110</pre>
111    </blockquote>
112    Then the list will be ordered: main_server, C, B, A. Keep this
113    in mind.
114
115    <p>After parsing has completed, the list of servers is scanned,
116    and various merges and default values are set. In
117    particular:</p>
118
119    <ol>
120      <li>If a vhost has no <a
121      href="../mod/core.html#serveradmin"><code>ServerAdmin</code></a>,
122      <a
123      href="../mod/core.html#resourceconfig"><code>ResourceConfig</code></a>,
124      <a
125      href="../mod/core.html#accessconfig"><code>AccessConfig</code></a>,
126      <a href="../mod/core.html#timeout"><code>Timeout</code></a>,
127      <a
128      href="../mod/core.html#keepalivetimeout"><code>KeepAliveTimeout</code></a>,
129      <a
130      href="../mod/core.html#keepalive"><code>KeepAlive</code></a>,
131      <a
132      href="../mod/core.html#maxkeepaliverequests"><code>MaxKeepAliveRequests</code></a>,
133      or <a
134      href="../mod/core.html#sendbuffersize"><code>SendBufferSize</code></a>
135      directive then the respective value is inherited from the
136      main_server. (That is, inherited from whatever the final
137      setting of that value is in the main_server.)</li>
138
139      <li>The "lookup defaults" that define the default directory
140      permissions for a vhost are merged with those of the main
141      server. This includes any per-directory configuration
142      information for any module.</li>
143
144      <li>The per-server configs for each module from the
145      main_server are merged into the vhost server.</li>
146    </ol>
147    Essentially, the main_server is treated as "defaults" or a
148    "base" on which to build each vhost. But the positioning of
149    these main_server definitions in the config file is largely
150    irrelevant -- the entire config of the main_server has been
151    parsed when this final merging occurs. So even if a main_server
152    definition appears after a vhost definition it might affect the
153    vhost definition.
154
155    <p>If the main_server has no <code>ServerName</code> at this
156    point, then the hostname of the machine that httpd is running
157    on is used instead. We will call the <em>main_server address
158    set</em> those IP addresses returned by a DNS lookup on the
159    <code>ServerName</code> of the main_server.</p>
160
161    <p>Now a pass is made through the vhosts to fill in any missing
162    <code>ServerName</code> fields and to classify the vhost as
163    either an <em>IP-based</em> vhost or a <em>name-based</em>
164    vhost. A vhost is considered a name-based vhost if any of its
165    address set overlaps the main_server (the port associated with
166    each address must match the main_server's <code>Port</code>).
167    Otherwise it is considered an IP-based vhost.</p>
168
169    <p>For any undefined <code>ServerName</code> fields, a
170    name-based vhost defaults to the address given first in the
171    <code>VirtualHost</code> statement defining the vhost. Any
172    vhost that includes the magic <samp>_default_</samp> wildcard
173    is given the same <code>ServerName</code> as the main_server.
174    Otherwise the vhost (which is necessarily an IP-based vhost) is
175    given a <code>ServerName</code> based on the result of a
176    reverse DNS lookup on the first address given in the
177    <code>VirtualHost</code> statement.</p>
178
179    <h3>Vhost Matching</h3>
180
181    <p><strong>Apache 1.3 differs from what is documented here, and
182    documentation still has to be written.</strong></p>
183
184    <p>The server determines which vhost to use for a request as
185    follows:</p>
186
187    <p><code>find_virtual_server</code>: When the connection is
188    first made by the client, the local IP address (the IP address
189    to which the client connected) is looked up in the server list.
190    A vhost is matched if it is an IP-based vhost, the IP address
191    matches and the port matches (taking into account
192    wildcards).</p>
193
194    <p>If no vhosts are matched then the last occurrence, if it
195    appears, of a <samp>_default_</samp> address (which if you
196    recall the ordering of the server list mentioned above means
197    that this would be the first occurrence of
198    <samp>_default_</samp> in the config file) is matched.</p>
199
200    <p>In any event, if nothing above has matched, then the
201    main_server is matched.</p>
202
203    <p>The vhost resulting from the above search is stored with
204    data about the connection. We'll call this the <em>connection
205    vhost</em>. The connection vhost is constant over all requests
206    in a particular TCP/IP session -- that is, over all requests in
207    a KeepAlive/persistent session.</p>
208
209    <p>For each request made on the connection the following
210    sequence of events further determines the actual vhost that
211    will be used to serve the request.</p>
212
213    <p><code>check_fulluri</code>: If the requestURI is an
214    absoluteURI, that is it includes <code>http://hostname/</code>,
215    then an attempt is made to determine if the hostname's address
216    (and optional port) match that of the connection vhost. If it
217    does then the hostname portion of the URI is saved as the
218    <em>request_hostname</em>. If it does not match, then the URI
219    remains untouched. <strong>Note</strong>: to achieve this
220    address comparison, the hostname supplied goes through a DNS
221    lookup unless it matches the <code>ServerName</code> or the
222    local IP address of the client's socket.</p>
223
224    <p><code>parse_uri</code>: If the URI begins with a protocol
225    (<em>i.e.</em>, <code>http:</code>, <code>ftp:</code>) then the
226    request is considered a proxy request. Note that even though we
227    may have stripped an <code>http://hostname/</code> in the
228    previous step, this could still be a proxy request.</p>
229
230    <p><code>read_request</code>: If the request does not have a
231    hostname from the earlier step, then any <code>Host:</code>
232    header sent by the client is used as the request hostname.</p>
233
234    <p><code>check_hostalias</code>: If the request now has a
235    hostname, then an attempt is made to match for this hostname.
236    The first step of this match is to compare any port, if one was
237    given in the request, against the <code>Port</code> field of
238    the connection vhost. If there's a mismatch then the vhost used
239    for the request is the connection vhost. (This is a bug, see
240    observations.)</p>
241
242    <p>If the port matches, then httpd scans the list of vhosts
243    starting with the next server <strong>after</strong> the
244    connection vhost. This scan does not stop if there are any
245    matches, it goes through all possible vhosts, and in the end
246    uses the last match it found. The comparisons performed are as
247    follows:</p>
248
249    <ul>
250      <li>Compare the request hostname:port with the vhost
251      <code>ServerName</code> and <code>Port</code>.</li>
252
253      <li>Compare the request hostname against any and all
254      addresses given in the <code>VirtualHost</code> directive for
255      this vhost.</li>
256
257      <li>Compare the request hostname against the
258      <code>ServerAlias</code> given for the vhost.</li>
259    </ul>
260
261    <p><code>check_serverpath</code>: If the request has no
262    hostname (back up a few paragraphs) then a scan similar to the
263    one in <code>check_hostalias</code> is performed to match any
264    <code>ServerPath</code> directives given in the vhosts. Note
265    that the <strong>last match</strong> is used regardless (again
266    consider the ordering of the virtual hosts).</p>
267
268    <h3>Observations</h3>
269
270    <ul>
271      <li>It is difficult to define an IP-based vhost for the
272      machine's "main IP address". You essentially have to create a
273      bogus <code>ServerName</code> for the main_server that does
274      not match the machine's IPs.</li>
275
276      <li>
277        During the scans in both <code>check_hostalias</code> and
278        <code>check_serverpath</code> no check is made that the
279        vhost being scanned is actually a name-based vhost. This
280        means, for example, that it's possible to match an IP-based
281        vhost through another address. But because the scan starts
282        in the vhost list at the first vhost that matched the local
283        IP address of the connection, not all IP-based vhosts can
284        be matched.
285
286        <p>Consider the config file above with three vhosts A, B,
287        C. Suppose that B is a named-based vhost, and A and C are
288        IP-based vhosts. If a request comes in on B or C's address
289        containing a header "<samp>Host: A</samp>" then it will be
290        served from A's config. If a request comes in on A's
291        address then it will always be served from A's config
292        regardless of any Host: header.</p>
293      </li>
294
295      <li>
296        Unless you have a <samp>_default_</samp> vhost, it doesn't
297        matter if you mix name-based vhosts in amongst IP-based
298        vhosts. During the <code>find_virtual_server</code> phase
299        above no named-based vhost will be matched, so the
300        main_server will remain the connection vhost. Then scans
301        will cover all vhosts in the vhost list.
302
303        <p>If you do have a <samp>_default_</samp> vhost, then you
304        cannot place named-based vhosts after it in the config.
305        This is because on any connection to the main server IPs
306        the connection vhost will always be the
307        <samp>_default_</samp> vhost since none of the name-based
308        are considered during <code>find_virtual_server</code>.</p>
309      </li>
310
311      <li>You should never specify DNS names in
312      <code>VirtualHost</code> directives because it will force
313      your server to rely on DNS to boot. Furthermore it poses a
314      security threat if you do not control the DNS for all the
315      domains listed. <a href="dns-caveats.html">There's more
316      information available on this and the next two
317      topics</a>.</li>
318
319      <li><code>ServerName</code> should always be set for each
320      vhost. Otherwise A DNS lookup is required for each
321      vhost.</li>
322
323      <li>A DNS lookup is always required for the main_server's
324      <code>ServerName</code> (or to generate that if it isn't
325      specified in the config).</li>
326
327      <li>If a <code>ServerPath</code> directive exists which is a
328      prefix of another <code>ServerPath</code> directive that
329      appears later in the configuration file, then the former will
330      always be matched and the latter will never be matched. (That
331      is assuming that no Host header was available to disambiguate
332      the two.)</li>
333
334      <li>If a vhost that would otherwise be a name-vhost includes
335      a <code>Port</code> statement that doesn't match the
336      main_server <code>Port</code> then it will be considered an
337      IP-based vhost. Then <code>find_virtual_server</code> will
338      match it (because the ports associated with each address in
339      the address set default to the port of the main_server) as
340      the connection vhost. Then <code>check_hostalias</code> will
341      refuse to check any other name-based vhost because of the
342      port mismatch. The result is that the vhost will steal all
343      hits going to the main_server address.</li>
344
345      <li>If two IP-based vhosts have an address in common, the
346      vhost appearing later in the file is always matched. Such a
347      thing might happen inadvertently. If the config has
348      name-based vhosts and for some reason the main_server
349      <code>ServerName</code> resolves to the wrong address then
350      all the name-based vhosts will be parsed as ip-based vhosts.
351      Then the last of them will steal all the hits.</li>
352
353      <li>The last name-based vhost in the config is always matched
354      for any hit which doesn't match one of the other name-based
355      vhosts.</li>
356    </ul>
357
358    <h3><a id="whatworks" name="whatworks">What Works</a></h3>
359
360    <p>In addition to the tips on the <a
361    href="../dns-caveats.html#tips">DNS Issues</a> page, here are some
362    further tips:</p>
363
364    <ul>
365      <li>Place all main_server definitions before any VirtualHost
366      definitions. (This is to aid the readability of the
367      configuration -- the post-config merging process makes it
368      non-obvious that definitions mixed in around virtualhosts
369      might affect all virtualhosts.)</li>
370
371      <li>Arrange your VirtualHosts such that all name-based
372      virtual hosts come first, followed by IP-based virtual hosts,
373      followed by any <samp>_default_</samp> virtual host</li>
374
375      <li>Avoid <code>ServerPaths</code> which are prefixes of
376      other <code>ServerPaths</code>. If you cannot avoid this then
377      you have to ensure that the longer (more specific) prefix
378      vhost appears earlier in the configuration file than the
379      shorter (less specific) prefix (<em>i.e.</em>, "ServerPath
380      /abc" should appear after "ServerPath /abcdef").</li>
381
382      <li>Do not use <em>port-based</em> vhosts in the same server
383      as name-based vhosts. A loose definition for port-based is a
384      vhost which is determined by the port on the server
385      (<em>i.e.</em>, one server with ports 8000, 8080, and 80 -
386      all of which have different configurations).</li>
387    </ul>
388        <hr />
389
390    <h3 align="CENTER">Apache HTTP Server Version 1.3</h3>
391    <a href="./"><img src="../images/index.gif" alt="Index" /></a>
392    <a href="../"><img src="../images/home.gif" alt="Home" /></a>
393
394  </body>
395</html>
396
397