| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> |
| <html><head> |
| <title>Issues Regarding DNS and Apache</title> |
| </head> |
| |
| <!-- Background white, links blue (unvisited), navy (visited), red (active) --> |
| <BODY |
| BGCOLOR="#FFFFFF" |
| TEXT="#000000" |
| LINK="#0000FF" |
| VLINK="#000080" |
| ALINK="#FF0000" |
| > |
| <!--#include virtual="header.html" --> |
| <h1 ALIGN="CENTER">Issues Regarding DNS and Apache</h1> |
| |
| <p>This page could be summarized with the statement: <i>don't require |
| Apache to use DNS for any parsing of the configuration files</i>. |
| If Apache has to use DNS to parse the configuration files then your |
| server may be subject to reliability problems (it might not boot), or |
| denial and theft of service attacks (including users able to steal hits |
| from other users). |
| |
| <h3>A Simple Example</h3> |
| |
| Consider this configuration snippet: |
| |
| <blockquote><pre> |
| <VirtualHost www.abc.dom> |
| ServerAdmin webgirl@abc.dom |
| DocumentRoot /www/abc |
| </VirtualHost> |
| </pre></blockquote> |
| |
| <p>In order for Apache to function properly it absolutely needs |
| to have two pieces of information about each virtual host: the |
| <a href="mod/core.html#servername"><code>ServerName</code></a> |
| and at least one IP address that the server |
| responds to. This example does not include the IP address, so Apache |
| must use DNS to find the address of <code>www.abc.dom</code>. If for |
| some reason DNS is not available at the time your server is parsing its |
| config file, then this virtual host <b>will not be configured</b>. It |
| won't be able to respond to any hits to this virtual host (prior to |
| Apache version 1.2 the server would not even boot). |
| |
| <p>Suppose that <code>www.abc.dom</code> has address 10.0.0.1. Then |
| consider this configuration snippet: |
| |
| <blockquote><pre> |
| <VirtualHost 10.0.0.1> |
| ServerAdmin webgirl@abc.dom |
| DocumentRoot /www/abc |
| </VirtualHost> |
| </pre></blockquote> |
| |
| <p>Now Apache needs to use reverse DNS to find the <code>ServerName</code> |
| for this virtualhost. If that reverse lookup fails then it will partially |
| disable the virtualhost (prior to Apache version 1.2 the server would not |
| even boot). If the virtual host is name-based then it will effectively |
| be totally disabled, but if it is IP-based then it will mostly work. |
| However if Apache should ever have to generate a full URL for the server |
| which includes the server name then it will fail to generate a valid URL. |
| |
| <p>Here is a snippet that avoids both of these problems. |
| |
| <blockquote><pre> |
| <VirtualHost 10.0.0.1> |
| ServerName www.abc.dom |
| ServerAdmin webgirl@abc.dom |
| DocumentRoot /www/abc |
| </VirtualHost> |
| </pre></blockquote> |
| |
| <h3>Denial of Service</h3> |
| |
| <p>There are (at least) two forms that denial of service can come in. |
| If you are running a version of Apache prior to version 1.2 then your |
| server will not even boot if one of the two DNS lookups mentioned above |
| fails for any of your virtual hosts. In some cases this DNS lookup may |
| not even be under your control. For example, if <code>abc.dom</code> |
| is one of your customers and they control their own DNS then they |
| can force your (pre-1.2) server to fail while booting simply by deleting the |
| <code>www.abc.dom</code> record. |
| |
| <p>Another form is far more insidious. Consider this configuration |
| snippet: |
| |
| <blockquote><pre> |
| <VirtualHost www.abc.dom> |
| ServerAdmin webgirl@abc.dom |
| DocumentRoot /www/abc |
| </VirtualHost> |
| </pre></blockquote> |
| |
| <blockquote><pre> |
| <VirtualHost www.def.dom> |
| ServerAdmin webguy@def.dom |
| DocumentRoot /www/def |
| </VirtualHost> |
| </pre></blockquote> |
| |
| <p>Suppose that you've assigned 10.0.0.1 to <code>www.abc.dom</code> and |
| 10.0.0.2 to <code>www.def.dom</code>. Furthermore, suppose that |
| <code>def.com</code> has control of their own DNS. With this config |
| you have put <code>def.com</code> into a position where they can steal |
| all traffic destined to <code>abc.com</code>. To do so, all they have to |
| do is set <code>www.def.dom</code> to 10.0.0.1. |
| Since they control their own DNS you can't stop them from pointing the |
| <code>www.def.com</code> record wherever they wish. |
| |
| <p>Requests coming in to 10.0.0.1 (including all those where users typed |
| in URLs of the form <code>http://www.abc.dom/whatever</code>) will all be |
| served by the <code>def.com</code> virtual host. To better understand why |
| this happens requires a more in-depth discussion of how Apache matches |
| up incoming requests with the virtual host that will serve it. A rough |
| document describing this <a href="vhosts-in-depth.html"> is available</a>. |
| |
| <h3>The "main server" Address</h3> |
| |
| <p>The addition of <a href="host.html">non-IP-based virtual host |
| support</a> in Apache 1.1 requires Apache to know the IP address(es) of |
| the host that httpd is running on. To get this address it uses either |
| the global <code>ServerName</code> (if present) or calls the C function |
| <code>gethostname</code> (which should return the same as typing |
| "hostname" at the command prompt). Then it performs a DNS lookup on |
| this address. At present there is no way to avoid this lookup. |
| |
| <p>If you fear that this lookup might fail because your DNS server is down |
| then you can insert the hostname in <code>/etc/hosts</code> (where you |
| probably already have it so that the machine can boot properly). Then |
| ensure that your machine is configured to use <code>/etc/hosts</code> |
| in the event that DNS fails. Depending on what OS you are using this |
| might be accomplished by editing <code>/etc/resolv.conf</code>, or maybe |
| <code>/etc/nsswitch.conf</code>. |
| |
| <p>If your server doesn't have to perform DNS for any other reason |
| then you might be able to get away with running Apache with the |
| <code>HOSTRESORDER</code> environment variable set to "local". This all |
| depends on what OS and resolver libraries you are using. It also affects |
| CGIs unless you use <a href="mod/mod_env.html"><code>mod_env</code></a> |
| to control the environment. It's best to consult the man pages or FAQs |
| for your OS. |
| |
| <h3>The _default_ Address</h3> |
| |
| <p>Any address that happens to go to your webserver which doesn't match |
| the IP address of any of the webservers will be served from the "main" or |
| "default" server configurations. The "main" server configuration consists |
| of all those definitions appearing outside of any VirtualHost section. |
| You may want instead to define a <code><VirtualHost _default_:*></code> |
| which returns 403 or 404 for all hits. (The trailing <code>:*</code> |
| makes it apply to all ports, which is just a safety measure should you |
| begin using multiple <code><a href="mod/core.html#listen">Listen</a></code> |
| directives.) |
| |
| <h3><a name="tips">Tips to Avoid these problems</a></h3> |
| |
| <ul> |
| <li> use IP addresses in <code><VirtualHost></code> |
| <li> use IP addresses in <code>Listen</code> |
| <li> use IP addresses in <code>BindAddress</code> |
| <li> ensure all virtual hosts have an explicit <code>ServerName</code> |
| <li> create a <code><VirtualHost _default_:*></code> server that |
| has no pages to serve |
| </ul> |
| |
| <h3>Appendix: Future Directions</h3> |
| |
| <p>The situation regarding DNS is highly undesirable. For Apache |
| 1.2 we've attempted to make the server at least continue booting |
| in the event of failed DNS, but it might not be the best we |
| can do. In any event requiring the use of explicit IP addresses in |
| configuration files is highly undesirable in today's Internet where <a |
| href="http://www.ietf.org/html.charters/pier-charter.html">renumbering |
| </a> is a necessity. |
| |
| <p>A possible work around to the theft of service attack described above |
| would be to perform a reverse DNS lookup on the ip address returned by |
| the forward lookup and compare the two names. In the event of a mismatch |
| the virtualhost would be disabled. This would require reverse DNS to be |
| configured properly (which is something that most admins are familiar with |
| because of the common use of "double-reverse" DNS lookups by FTP servers |
| and TCP wrappers). |
| |
| <p>In any event it doesn't seem possible to reliably boot a virtual-hosted |
| web server when DNS has failed unless IP addresses are used. Partial |
| solutions such as disabling portions of the configuration might be worse |
| than not booting at all depending on what the webserver is supposed |
| to accomplish. |
| |
| <p>As HTTP/1.1 is deployed and browsers and proxies start issuing the |
| <code>Host</code> header it will become possible to avoid the use of |
| IP-based virtual hosts entirely. In this event a webserver has no requirement |
| to do DNS lookups during configuration. But as of March 1997 these |
| features have not been deployed widely enough to be put into use on |
| critical webservers. |
| |
| <!--#include virtual="footer.html" --> |
| </BODY> |
| </HTML> |
| |