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 <VirtualHost A> 100 ... 101 </VirtualHost> 102 103 <VirtualHost B> 104 ... 105 </VirtualHost> 106 107 <VirtualHost C> 108 ... 109 </VirtualHost> 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