When re-routing the requests from clients to backend node(s) in a web farm, ARR is using by default the farm name as host header in the re-routed requests. But it can be configured to change that host-name, at a per-node level.
For example, let’s say that I have an IIS instance with Application Request Routing (named ARR) with two IIS instances working as backend processing nodes (named IIS-A and IIS-B). Requests are arriving at ARR node (at its IP address) as http://Public-HostName. But the sites on backend nodes are configured for hostname Internal-SiteName. So ARR should address the IIS-A/B nodes with http://Internal-SiteName, not with http://Public-HostName. How do I do that?
I’m creating a very simple web farm in ARR, adding IIS-A and IIS-B as nodes. Even if I configure IIS-A/B machine in the farm, ARR would connect to these machines by their IP addresses in the end, so we need to ensure that these names are DNS-resolvable.
ARR web farm setup
The farm definition in applicationHost.config would end up like:
<configuration> <webFarms onDemandHealthCheck="true"> <webFarm name="Public-HostName" enabled="true"> <server address="IIS-A" enabled="true" /> <server address="IIS-B" enabled="true" /> </webFarm> </webFarms> </configuration>
A corresponding URL Rewrite rule is being created. Since I have several farms defined on my ARR node, I am tweaking a bit the rule created by default, adding an {HTTP_HOST} condition:
URL Rewrite rule for the farm
With this rule in place, it looks like this in the applicationHost.config:
<configuration> <system.webServer> <rewrite> <globalRules> <rule name="ARR_Public-HostName_loadbalance" enabled="true" patternSyntax="Wildcard" stopProcessing="true"> <match url="*" /> <conditions> <add input="{HTTP_HOST}" pattern="Public-HostName" /> </conditions> <action type="Rewrite" url="http://Public-HostName/{R:0}" /> </rule> </globalRules> </rewrite> <proxy enabled="true" arrResponseHeader="true" /> </system.webServer> </configuration>
The rule says something like this:
But wait! My nodes Internal-SiteName expect as hostname. If I change the URL Rewrite rule to re-route to “Internal-SiteName”, then the ARR farm would not be recognized. I could change the farm name to “Internal-SiteName” instead, but sometimes this is not possible or desired. Is there an alternative?
When ARR is addressing the backend nodes, to get a response for the request, it could have the hostname changed. Instead of using the farm name as the host header when addressing IIS-A/B, it could use a custom hostname, which may be defined per-node.
There are 2 steps needed, both involving configuration settings that are hidden; meaning that they are not accessible via the ARR configuration UI. We would need to manually edit the applicationHost.config or better use Configuration Editor feature from IIS Manager.
Firstly, change the applicationRequestRouting > protocol settings for the server farm, setting the preserveHostHeader to False. This tells ARR to not enforce placing the farm name in the host header for requests it sends to IIS-A/B. To do that:
Configuration editor
Edit collection of web farms
Select farm, change settings: preserveHostHeader under protocol, under applicationRequestRouting
Don't forget to save changes
Secondly, change the hostName of the farm node(s) that are placed in the ARR server farm. You need to do that for each of the farm nodes that has to be addressed with a hostname different than the farm’s name.
Configuration editor
Edit server farms collection
Edit nodes collection in the selected server farm
Change hostName for the selected farm node, under applicationRequestRouting
Don't forget to save changes
With that, if the Public-HostName is resolvable to the IP address of the ARR machine, then we can access the site from a client.
Test the site, the internal routing changing the host header
For reference, the farm definition in the applicationHost.config now looks like this:
<configuration> <webFarms onDemandHealthCheck="true"> <webFarm name="Public-HostName" enabled="true"> <server address="IIS-A" enabled="true"> <applicationRequestRouting hostName="Internal-SiteName" /> </server> <server address="IIS-B" enabled="true"> <applicationRequestRouting hostName="Internal-SiteName" /> </server> <applicationRequestRouting> <protocol preserveHostHeader="false" /> </applicationRequestRouting> </webFarm> </webFarms> </configuration>
All the best!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.