Case Study: Host header, IP and Port combinations within IIS

 

Talking about IIS website configurations when it comes to IP Address, Port, Host headers cause a lot of confusion to many Web Administrators. Here I will be going (a bit of unnecessary details though) to explain how the configuration resolves to Websites when a web request comes to IIS.

Environment

IIS6.0

I have multiple IP addresses for my demo server (assuming you have multiple NIC cards).

Here is a list:

10.0.1.1

10.0.1.2

10.0.1.3

10.0.1.4

Here is a screenshot of how IIS manager section looks like which I will talk about later.

In the IIS manager console you may have the following scenarios:

Scenario 1:

There are multiple Websites (for our example we will take 2 here) running with following configuration:

Website                   Host Header Value                  IP Address                         Port
================================================================================
Test1                                --                                All Unassigned                        80
Test2                                --                                All Unassigned                        80

Scenario 2:

Website                   Host Header Value                  IP Address                         Port
================================================================================
Test1                                --                                10.0.1.2                        80
Test2                                --                                10.0.1.2                        80

Will this Websites run? No, only one of them can be in started mode. Rest of them will be in stopped state.
Reason: For HTTP sites one cannot have multiple sites running with the same IP/Port/HostHeader combination. For HTTPS sites you cannot have the same IP/Port combination. More specifically you cannot have the same port/IP combination for the “SecureBindings” setting (SSL settings). Technically, you could have an entirely different IP address for the SSL portion of a web site. If you mess up the SSL part, the HTTP part of the site will still start.

 

If you try to start any of the other Websites you will get an error popup like this:

Scenario 3:

Website                   Host Header Value                  IP Address                         Port
================================================================================
Test1                                --                                     10.0.1.1                             80
Test2                                --                                All Unassigned                        80

Test3                                --                                     10.0.1.3                             80 

Test4                                --                                     10.0.1.4                             80

Will these Websites start: Yes. All of the Websites will be up and running. Remember you can have only one website which can have "All Unassigned" and port XX (when there are no host headers in picture and you have all the sites running on same port XX). No two website can have exactly the same combination of Host header, IP Address and Port.

Here remember you can access the site Test1 only with the IP address 10.0.1.1. If you try to use https://localhost (or https://127.0.0.1) , it will go to some other site (discussed soon). Now using https://servername is a bit tricky. Request will actually go to the site to which your servername resolves from the user's machine. If you do a ping servername and if the IP that it resolves to is set for a specific site like Test3, Test3 will serve the page. If https://servername doesn't resolve to any of the IP addresses on which some sites are specifically configured to listen to, the request will be served by a site which is listening on "All Unassigned" (I know it may be confusing but I am giving an example before coming to theory). If none of the Websites are listening on the resolved IP or "All unassigned" then you will see a "Bad Request (Invalid Hostname) " in the browser (You may check the httperr log to confirm the same).

Let's take for our example that ping servername resolves to 10.0.1.2

So seeing the Websites configuration of Scenario 3 above, which site will should serve the page for the following URLs:

https://servername (remember servername resolves to 10.0.1.2) ?        Ans: Test2

https://10.0.1.2 ?              Ans: Test2 

https://10.0.1.3 ?              Ans: Test3

https://10.0.1.4 ?              Ans: Test4

https://10.0.1.1 ?              Ans: Test1

https://localhost ? (Remember it refers to 127.0.0.1)           Ans: Test2

I assume you are getting the logic.

So here comes the explanation:

IIS by default listens on all the IP addresses on the server on a specific port (By default 80).

If you run the command netstat -ano from the command prompt you will see an entry like 0.0.0.0:80. This means that IIS process listens on all IP addresses associated with the server on port 80. Now when you associate a website with a specific IP address and port combination it will listen only on that IP address on that port. It won't accept any request on any other IP address or port associated with the server. When you use "All Unassigned" for a website it means that this website listens on all the IP addresses associated with the server on the specified port. Hence as you may assume from above scenario any web request that is sent to the server on a specific IP address will be served by the website following the above rule...let me clear it again with the above example:

https://servername (remember servername resolves to 10.0.1.2) ?       

Ans: Test2 , Reason: When the request reaches IIS server, http.sys driver redirects the request to website Test2 because all other Websites are listening on specific IP's which do not match 10.0.1.2.

https://10.0.1.2 ?             

Ans: Test2, Reason: It will be sent to and served by Test2 because this is the website which is set to "All unassigned" which means Website is listening on all IP addresses associated with the server. Also this request won't be served by any other site because they are listening on IP's which are different from 10.0.1.2. 

https://10.0.1.3 ?              

Ans: Test3 , Reason: As expected from explanations so far this will be served by Test3 because Test3 is configured to listen to any request directed on IP 10.0.1.3.

https://10.0.1.4 ?             

Ans: Test4 , Reason: Again the same reason as above, Test4 is configured to listen on IP 10.0.1.4.

https://10.0.1.1 ?             

Ans: Test1 , Reason: Same logic as above.

https://localhost ? (Remember it refers to 127.0.0.1)          

Ans: Test2, Reason: Served by Website Test2, because the request is sent on IP 127.0.0.1 and none of the other Websites are listening on 127.0.0.1. Test2 has "All unassigned" which means it is listening on all IPs on the server including 127.0.0.1 and hence can serve the request. If for testing you change the IP configuration for a website to 127.0.0.1 then all new requests like https://localhost will be served by this specific website.

So the above scenario shows how every request will be served by some site provided we have the configuration like "All unassigned" or specific IP for the sites.

Now let's assume what will happen if we have this scenario:

Scenario 4:

Website                   Host Header Value                  IP Address                         Port
================================================================================
Test1                                --                                     10.0.1.1                             80
Test2                                --                                     10.0.1.2                             80

Test3 (Stopped)               --                                     10.0.1.3                             80 

Test4                                --                                     10.0.1.4                             80

Here we do not have any site configured with "All unassigned". Now if you try to access https://localhost or https://10.0.1.3 what should happen?

You should see "Bad Request (Invalid Hostname) in the browser. This happens because now none of the Websites are capable of serving your requests https://localhost (127.0.0.1) or https://10.0.1.3 

We have just 3 Websites (running) and they are listening on IPs 10.0.1.1, 10.0.1.2 and 10.0.1.4. Had there been a website listening on "All Unassigned" these requests would have been served by this website.

I am pretty sure you might have got rid of some of your doubts by now :) If not it's my bad.

-------------------------------------------------------------------------------------------------------------------------------------------------------

So far I had been talking about scenarios where Host header was not in picture.

Now let's assume you have host headers as well in above scenarios. Let's first see what's the use of a Host header.

IIS identifies Websites on the basis of 3 parameters: IP address, Port and Host header (if present).

Any combination of the above parameters should be able to uniquely identify a website. If there is an ambiguity IIS will throw error.

A host header is of the form www.abcd.com or abcd or abcd.com or abcd.co.in etc....

To create and host multiple Web sites, you must configure a unique identity for each site on the server. To assign a unique identity, distinguish each Web site with at least one of three unique identifiers: a host header name, an IP address, or a TCP port number.

One method for providing each site with a unique identifier is to use IIS Manager to assign multiple host header names.

Typically Host headers are set in IIS manager and its mapping to an IP is set in the DNS entry or hosts file (I assume you know hosts file is a limited simulation of DNS for a client). Users access the sites using their host headers.

A “Host” header is one header out of multiple headers that are included in an HTTP request. The headers are things like User-Agent, Accept, If-Modified-Since, Content-Length, Host, etc. As a request comes in, IIS looks at one particular header… “Host” and uses its value to decide which web site to route the request. “Host Headers” are not an IIS technology. They are an HTTP technology. Browsers typically put into the “Host” header whatever the user put into the “Address” line of the browser. If you put “https://192.25.109.11/Default.aspx” into the address line then the browser will extract the “host name” from that address and put “192.25.109.11” as the value for the “Host” header. Or maybe there is no header at all named “Host” (which makes it an HTTP/0.9 request).

Here is a screenshot of an http request for https://test1.com

and this one for https://10.0.1.1

Scenario 5:

Website                  Host Header Value                  IP Address                         Port
================================================================================
Test1                        test1.com                               10.0.1.1                             80
Test2                        test2.com                               10.0.1.1                             80

and in the DNS or hosts file you have mapping like:

10.0.1.1                test1.com

10.0.1.1                test2.com

Will these two Websites run simultaneously? Yes they will.

They will run even when they have same IP and same port because now IIS has a way of distinguishing the Websites using a 3rd parameter called host header. So it knows that when a request comes for https://test1.com and https://test2.com it can direct them to the right Websites on the basis of host headers present in the request headers.

When you access a site with host header the request is resolved to the website corresponding to DNS/Hosts mapping for the host header and not the IP address mentioned in the IIS manager. This is IMPORTANT. The request then reaches the IIS server and goes to the website which is listening on that resolved IP.

Let's see here.

DNS/Hosts setting:

10.0.1.1              test1.com                                    10.0.1.3           test3.com

10.0.1.2              test2.com                                    10.0.1.4           test4.com

Scenario 6:

Website                   Host Header Value                  IP Address                         Port
================================================================================
Test1                          test1.com                              10.0.1.1                             80
Test2                          test2.com                              10.0.1.2                             80

Test3                          test3.com                              10.0.1.3                             80 

Test4                          test4.com                              10.0.1.4                             80

Now when you try to browse to https://test3.com which site should serve the page from the above IIS configuration? Obviously Test3, now this is simple:). what happens if you try to access any of these Websites with their IP addresses? You will see "Bad Request (Invalid Hostname) ". So use judiciously as to how users should access the site. If you have host header set use it instead of IP address in the URL.

If you really want to use an IP address along with an alias (a friendly name) for a website (like https://abcd.com , or https://wxyz ) , then just don’t assign the host header value in the IIS manager. And have an entry in DNS or hosts file mapping abcd.com or wxyz to the IP address for the website (there are other ways to but this neat).

Scenario 7:

Website                   Host Header Value                  IP Address                         Port
================================================================================
Test1                          test1.com                              10.0.1.1                             80
Test2                          test2.com                              10.0.1.2                             80

Test3                          test3.com                              10.0.1.1                             80 

Test4                          test4.com                              10.0.1.4                             80

Which site should serve the content when accessed with https://test3.com in the URL..............?

"Bad Request (Invalid Hostname) " in the browser. Reason being that https://test3.com resolves to IP 10.0.1.3 through DNS/Hosts and then in IIS mmc it is configured to listen on IP 10.0.1.1. Rest of the Websites work fine because both the DNS/host entry and IP in IIS mmc for the Websites match.

Scenario 8:

Website                   Host Header Value                  IP Address                         Port
================================================================================
Test1                          test1.com                              10.0.1.1                             80
Test2                          test2.com                              10.0.1.2                             80

Test3                          test3.com                              10.0.1.1                             80 

Test4                          test4.com                              All unassigned                   80

 

What site should https://test4.com resolve to..............? Test4, because it is listening on All Unassigned (which means all the IP addresses on the server) which includes DNS/hosts mapping for the site (here 10.0.1.4).

Similarly if we have       

Website                   Host Header Value                  IP Address                         Port
================================================================================

Test3                           test3.com                        All Unassigned                        80 

It should still work fine for https://test4.com and also https://test3.com

Let us consider another scenario

If you have multiple entries for a website in the IIS manager->Web Site->Advanced, you may have different host headers but should have same IP (and/or All unassigned) and TCP Port.

If you use a different port for the entries you need to add the port entry after the host header like: https://testX:port.

If you use a different IP address for the 2nd host header you may again see the blunt "Bad Request (Invalid Hostname) " error when you use this host header to access the website.

So all these explanations and pain for one reason: Avoid setting a specific IP address for the Websites in IIS mmc to avoid any conflicts or confusion with the DNS/Hosts mapping. Instead use "All unassigned" and if really required to use an IP make sure that IP address in IIS mmc and DNS/Hosts entry is same. There is no benefit to “over configuring” the IP and host header settings. It is “unnecessary administrative overhead”. For any site that don’t use SSL, assign one or more host headers and leave the IP at "All unassigned". For anything with SSL, give it a specific IP and leave the host header field blank. Leave port alone because that confuses most end users.

Hope this helps!