Scott Forsyth's Blog

Postings on IIS, ASP.NET, SQL Server, Webfarms and general system admin.
IIS URL Rewrite – Hosting multiple domains under one site

In a shared hosting environment, it’s a common desire to have a single IIS website that handles multiple sites with different domain names.  This saves the cost of setting up additional sites with the hoster. 

At ORCS Web, we’ve supported this situation for many years using ISAPI Rewrite.  Now, with URL Rewrite for IIS 7, it’s easier and it’s integrated right into web.config.  In this blog post I’ll set out to cover the essentials for hosting multiple domain names under a single account using URL Rewrite.

This post assumes that you are using URL Rewrite 1.0, 1.1 or 2.0.  I’ll follow-up in a later post on more advanced ways to take this further yet, using the new features of URL Rewrite 2.0.

First, the file structure

Let’s lay out the directory structure for this example.  Assume that you have 3 domain names.  They are: masterdomain.com, site2.com and hawaiivisit.site2.com.  You’ve created your directory structure like this:

image

Let’s assume that masterdomain.com was already in the root of the site and can’t easily be moved.  However, site2.com and hawaiivisit.site.com need to be set up.  Each of these folders have a website within them.

Directing the domain name to the server

First, make sure that when you browse to the website by domain name, that it resolves to the correct IP address.  This is handled at the DNS level.  Your DNS entry for site2.com and hawaiivisit.site2.com will often be identical to masterdomain.com and are managed through your DNS provider.

Catching the site when on the server

If you host with a web hosting company then they will take care of this.  If you host yourself, make sure to set a site binding so that the expected site processes the domain name.  If you use host headers, be sure to add the extra bindings for them.

Redirecting the site to a subfolder

Now that you have the domain name directed to the server and site, URL Rewrite comes in to direct it to a subfolder.

First, make sure that your web host supports URL Rewrite on the server that you’re hosted on.  The following assumes that it’s installed and supported.

You can use IIS 7 Manager which gives a friendly interface for creating rules.  If you prefer to write them directly in web.config, I’ll include the rules below.

First, open up URL Rewrite:

image

I’ve come to prefer RegEx rules instead of wildcard rules.  I find that wildcard rules reach their limit pretty quickly.  Regular expressions can be daunting at first but it’s pretty easy to pick up the basics.  Here’s an excellent reference to get started: http://www.regular-expressions.info/reference.html

To create the rule click on “Add Rules…”.

image

Select the “Blank Rule” template and click OK.

For the name, enter your domain name, or whatever makes the most sense to you.

Match URL section

In the Match URL Section, leave the defaults to match the pattern and Regular Expressions.  For the pattern, enter (.*) without the parentheses.  The “URL” is the part after the domain name.  i.e. www.ThisIsTheDomain.com/ThisIsTheURL.  It’s the domain that we’re interested in now, not the URL.

Conditions

The Conditions section is where we’ll do most of the work.  Expand that section if it’s collapsed and click “Add”. 

The domain name is contained within the HTTP header called {HTTP_HOST}.  Here’s where the fun comes.  The regular expression pattern that will match www.site2.com or site2.com (without the www) looks like this: ^(www.)?site2.com$. 

Here’s what that means. 

  • The ^ is the character that signifies the start of the string.  That ensures that something.www.site2.com doesn’t also get included with this rule.
  • The $ is the character that marks the end of the string.
  • ( ) parentheses are used to create section groups. 
  • ? means that something is optional.
  • Therefore, (www.)? means that with www. or without, either are accepted.

After filling in these fields you should have something like the following:

image

Now, here’s the part that many people wouldn’t guess at first.  Since URL Rewrite works on the URL only, while most code (ASP.NET, ASP, PHP, etc) works at the server level, they aren’t aware of each other.  Just because you rewrite the URL doesn’t mean that the code has any clue of the change.  As a result, any time that ASP.NET automatically creates the path, it will likely clash with the URL Rewrite rule.  For example, Response.Redirect(“~/”) will redirect to the root of the application.  That means that it can create a path like www.site2.com/site2.  Notice the extra site2 in the path.  The login page for ASP.NET will mess with you too.

A future blog post will cover how to hide the /site2 using URL Rewrite 2.0, but the easy solution is to ensure that www.site2.com and www.site2.com/site2 both go to the same place.  Both should be served from …\masterdomain.com\site2.  It means that the URL can be longer than you may prefer, but it allows the site to continue to function.

To achieve this, add an exclusion condition so that this rule doesn’t redirect at all if the URL starts with /site2/.

There are 2 ways to achieve this.  You could go back to the URL section where we previously entered .* and update that section.  There isn’t anything wrong with that at all.  For no particular reason that I can think of right now, I prefer to do this from the conditions section.  Here’s how to do it:

Add another condition where the condition input is {PATH_INFO}, and set the dropdown to “Does Not Match the Pattern”, and set the Pattern to ^/site2/.  That means that the PATH_INFO must start with /site2/.  Note that you shouldn’t end with the $ this time because you want sub-sub folders to work too.  It should look like this:

image

Action Section

We’re nearly done.  In the Action section, first set the “Action Type” to Rewrite.  Then set the Rewrite URL to \site2\{R:0} and ensure that the “Append query string” checkbox is checked.  The {R:0} is a back reference to the URL.  It will allow the URL to be carried through dynamically in the request.  The Append query string ensures that the query string itself will carry through.

The complete rule should look like this:

image

That’s it.  Save and test.

Using a Text Editor

You may prefer to use a text editor or to see the config directly.  The rule generated for web.config looks like this:

<rewrite>
    <rules>
        <rule name="site2.com" stopProcessing="true">
            <match url=".*" />
            <conditions>
                <add input="{HTTP_HOST}" pattern="^(www.)?site2.com" />
                <add input="{PATH_INFO}" pattern="^/site2/" negate="true" />
            </conditions>
            <action type="Rewrite" url="\site2\{R:0}" />
        </rule>
    </rules>
</rewrite>

And, the rule for hawaiivisit.site2.com is similar.  It looks like this:

<rewrite>
    <rules>
        <rule name="hawaiivisit.site2.com" stopProcessing="true">
            <match url=".*" />
            <conditions>
                <add input="{HTTP_HOST}" pattern="^hawaiivisit.site2.com$" />
                <add input="{PATH_INFO}" pattern="^/hawaiivisit/" negate="true" />
            </conditions>
            <action type="Rewrite" url="\hawaiivisit\{R:0}" />
        </rule>
    </rules>
</rewrite>

The other things

I wanted to briefly mention what isn’t covered in this blog post that you may want to consider. 

  • DNS. The ‘how to’ for your domain name purchase and directing isn’t covered here.
  • Statistics. If you use  a client-side option like Google Analytics then this will work just as well under a single account.  However, if you are using a log based statistics program like SmarterStats then it’s up to you to set rules in SmarterStats to filter out or sub-divide the statistics into useful sections i.e. 1 per site.
  • Email. You will likely need to setup another mail account with your host, or add the new domain as a domain alias to your existing account.
  • ASP.NET inheritance. web.config inherits down the entire path but the ASP.NET folders do not inherit past application boundaries.  More on that here.  One workaround if ASP.NET inheritance fights with you is to not have a site in the website root.  Instead, place all sites in their own subfolder.
  • You’ll likely need to mark the folder as an application so that it is an ASP.NET application.  (assuming ASP.NET of course)

Happy URL Rewriting!

IIS URL Rewrite – Redirect multiple domain names to one

Consider this a 2nd part to IIS URL Rewrite – rewriting non-www to www.  Reader Rubens asked about redirecting multiple domain names in a single rule.  That’s a good question and worth writing a part II blog post about it.

Here’s his question:

If there any generic way to do that if we have multiple domains with
multiple extensions?example:
mydomain.com to www.mydomain.com (already done)
mydomain.net to www.mydomain.com
www.mydomain.net to www.mydomain.com
etccc...
and maybe also
www.mydomain2.net to www.mydomain.com
etccc...
Thanks.


Regular expressions are great for handling .com / .net / .org in a single condition.  You can do this using a “Condition input” check for {HTTP_HOST} with a “Pattern” of:
^domain.(com|net|org)$

Note that the ^ marks the beginning of the pattern and the $ marks the end when using regular expressions. 
 
Additionally, to handle the mydomain2.net, be sure to set the “Logical Grouping” to Match Any.  This allows any of the rules to cause the rule to match the condition and redirect.  After setting to Match Any, you can add as many domains as you want with a single rule with multiple conditions.
 
Let’s look at mydomain2.com and .net.  Here’s a Pattern that will catch all situations:
^(www.)?mydomain2.(com|net)$

This catches www and non-www and .com and .net.
 
The following screenshot shows conditions that will catch the following:
  • domain.com (1st condition)
  • domain.net (1st condition)
  • www.mydomain2.com (2nd condition)
  • www.mydomain2.net (2nd condition)
  • mydomain2.com (2nd condition)
  • mydomain2.com (2nd condition)
  • www.domain.net (3rd condition)
image
 
Note that the Action will redirect all of them to the same place (www.domain.com), which was Rubens’ goal.  Just be sure that no conditions match www.domain.com or you’ll create a loop.
 
The config that results should look like this:
 
<rewrite>
    <globalRules>
        <rule name="Redirects to www.domain.com" patternSyntax="ECMAScript" stopProcessing="true">
            <match url=".*" />
            <conditions logicalGrouping="MatchAny">
                <add input="{HTTP_HOST}" pattern="^domain.*(com|net)$" />
                <add input="{HTTP_HOST}" pattern="^(www.)?mydomain2.(com|net)$" />
                <add input="{HTTP_HOST}" pattern="^www.domain.net$" />
            </conditions>
            <action type="Redirect" url="http://www.domain.com/{R:0}" />
        </rule>
    </globalRules>
</rewrite>
 
You can do this using wildcards too.  It would take more conditions.  It’s also possible to do this with rewrite maps, another feature of URL Rewrite.
Posted: Nov 30 2009, 02:40 PM by OWScott | with 11 comment(s)
Filed under: , ,
IIS URL Rewrite – rewriting non-www to www

If you’re using IIS 7.0 (or 7.5), URL Rewrite is a valuable tool, well worth installing and using.

One common use of URL Rewrite is redirecting http://domain.com to http://www.domain.com.  Many people are doing this for search engine optimization (SEO) so that search engines only see the one site, rather than two sites.  The goal is to set a permanent 301 redirect.

You can download URL Rewrite from http://www.iis.net/expand/URLRewrite.  For this walkthrough and screenshots I’ll use URL Rewrite 2.0 RC1, but everything that I’ll cover also works for version 1.0 and 1.1.

URL Rewrite works at the global level, or site level (or application level for that matter).  Where you apply it is really up to how you manage your server.  Either will work for a domain name redirect like this.

You can choose to create the rules using IIS Manager, or using a text editor and updating web.config directly.  I’ll show both, starting with IIS Manager.

Let’s get started.  First, open IIS Manager and double-click on the “URL Rewrite” icon.

image

Next, click on “Add Rules…” from the Actions pane.

Here you’ll have a choice from a few wizard options, and with URL Rewrite 2.0 you can also create outbound rules.  Create a Blank rule (inbound rules).

image

Give your rule a good friendly “Name”.  I’ll call mine “Redirect domain.com to www”.

In the “Using” dropdown box you can choose between Regular Expressions and Wildcards.  Use wildcards if you aren’t familiar with regular expressions since they are much more intuitive.  However, if you later need to create more complex rules, regex may be necessary.

For this demo select WildcardsHowever, I’ll include instructions for those wanting to use regular expressions.

Enter * for the “Pattern”.  That means anything qualifies.  We’ll use a condition later instead of matching to the URL.  (for Regular Expressions, use .*).

Now expand the “Conditions” section and click “Add”.  In the “Add Condition” dialogue enter the following:

Condition input: {HTTP_HOST}
Check if input string: Matches the Pattern
Pattern: domain.com
(for regex, enter ^domain.com$)
Ignore case: checked

image

Click OK.

Finally, it’s time to set the Action.

In the Action section make sure that the “Action Type” is set to Redirect

For the “Action Properties”, enter http://www.domain.com/{R:0}.  The {R:0} retains the existing URL so if someone typed something like http://domain.com/aboutus it would retain the aboutus as it adds the www.

Be sure that the “Append query string” remains checked so that the querystring part is also retained.

Also, be sure that the “Redirect Type” is set to Permanent (301), which is what the search engines like.  This tells the search engines to do a permanent redirect, use the new location and ignore the previous location.

image

Finally, Apply the rule and test!

Using a Text Editor

You can also create this rule manually by adding the following to your site’s web.config (or applicationHost.config if you set this at the server level).

In the <system.webServer> section of your web.config, add the following:

Wildcards

<rewrite>
    <rules>
        <rule name="Redirect domain.com to www" patternSyntax="Wildcard" stopProcessing="true">
            <match url="*" />
            <conditions>
                <add input="{HTTP_HOST}" pattern="domain.com" />
            </conditions>
            <action type="Redirect" url="http://www.domain.com/{R:0}" />
        </rule>
    </rules>
</rewrite>

 

Save and you should be set.

Or, if you prefer Regular Expressions, use this instead:

Regular Expressions

<rewrite>
    <rules>
        <rule name="Redirect domain.com to www" patternSyntax="ECMAScript" stopProcessing="true">
            <match url=".*" />
            <conditions>
                <add input="{HTTP_HOST}" pattern="^domain.com$" />
            </conditions>
            <action type="Redirect" url="http://www.domain.com/{R:0}" />
        </rule>
    </rules>
</rewrite>

This is just the start to great SEO, but it’s a common step and one that I hope you find helpful.

See Part II on how to redirect multiple domain names to a single domain name: http://weblogs.asp.net/owscott/archive/2009/11/30/iis-url-rewrite-redirect-multiple-domain-names-to-one.aspx

Posted: Nov 27 2009, 05:55 PM by OWScott | with 17 comment(s)
Filed under: , ,
The SID Myth

Amazing!

Admins, myself included, have worried about the machine SID for years and years.  Way back it was ghosting, now it’s with virtualization.  We made sure to create a new SID after creating servers from server images.

It turns out that this has been a non-issue all of this time, a non-issue that everyone, Microsoft, Mark Russinovich and administrators all over bought into for over a dozen years.

A few weeks back I heard rumor that Mark Russinovich was going to expire NewSID.  I figured it was because there were just too many SID references to keep track of that he wasn’t going to maintain that tool forever.  It turns out that it’s for a completely different reason.

The machine SID does not have to be unique for security reasons, and Microsoft applications don’t depend on it in their usage.  Mark’s blog post here covers all of the details:

http://blogs.technet.com/markrussinovich/archive/2009/11/03/3291024.aspx

However, it’s important to note the difference between machine SIDs and domain SIDs.  Additionally the machine name must be different, and the domain controllers themselves can’t have the same SID as any member servers.

I am watching this thread with interest because situations do arise where people run into issues with WSUS and other tools where generating a new SID resolves their issues.  However Mark’s comments suggest that it’s related to the domain SID or the domain controller having the same SID as the members. 

If, after some burn-in time, this is confirmed to be the case, it will save a lot of work that administrators spend considerable time worrying about . . . apparently needlessly.

Read the post, it covers it in great details.

Posted: Nov 03 2009, 08:40 PM by OWScott | with 2 comment(s)
Filed under:
Web Deployment Tool released to web (RTW)

The final release of the Web Deployment Tool (aka Web Deploy or MsDeploy) has been released to the web.  This is likely more significant than many people realize. 

At first glance, Web Deploy seems like a tool for system administrators to copy sites and settings between servers (IIS6 to IIS6, IIS6 to IIS7 and IIS7 to IIS7).  It does do that, including SSL, COM, GAC, ACLs, registry, content and more.

However, Web Deploy is likely to become a major deployment method for developers too.  Visual Studio 2010 will have native support for Web Deploy, offering the ability to deploy a entire website with the single-click feature of VS2010.  What’s also impressive is that it’s so lightening fast.  Only the file changes are copied to the server rather than an entire push like you would normally see with FTP.  Furthermore, everything is over SSL, making it a highly secure technology.

It doesn’t stop there.  Web Deploy extends IIS and addresses some of the common limitations of remote delegated management in IIS.  With the Web Deployment Tool properly configured by a web host or system administrator, it’s possible to mark folders as applications with IIS Manager and even recycle, stop or start app pools.

At ORCS Web, we’ve installed this on all of our IIS7 Shared Server solutions so that our customers can enjoy Web Deploy.  Until Visual Studio 2010 comes out, IIS 7 Manager is the best tool to leverage Web Deploy features.

Taking Web Deploy for a Spin

To try it out you’ll need a web host or server that supports the Web Deployment Tool.  Using the information provided by your server administrator (or web host), connect remotely to IIS 7 using IIS Manager.

Once connected, you will likely get prompted to install some add-ons.  Confirm that you want them and approve the install.  Don’t let the install fool you.  You *must* still install Web Deploy separately since the IIS Manager install doesn’t include everything necessary.  Go to the Web Deployment Tool page and download the Web Deployment Tool and install on your local computer.  Only the UI components are necessary on the client side.  When completed make sure to restart IIS Manager.

Recycling and managing Application Pools

Once you’ve connected and have the Web Deployment Tool installed, you can start to manage your website through IIS Manager in ways not previously possible.

image

Clicking on “Recycle…” will give another screen allowing you to choose between 4 options:

image

Hopefully your host or system administrator makes sure that you aren’t sharing the app pool with any other sites, otherwise you will indirectly impact them.  Note that these features are only available if your host or administrator supports them.  At ORCS Web, we support all features shown in the blog post.

Marking/Setting and Removing Applications

Notice that you can also delete an Application and Content, or if you right-click on a normal folder, you can convert it to an application, as shown in the following image:

image

Deploying Website

The actual copy features of the Web Deployment Tool aren’t quite as easy, but they aren’t too bad when you understand the concepts.  The power of the Web Deployment Tool will make much more sense with Visual Studio 2010, but I’ll detail here how to deploy your website using IIS Manager and the Web Deployment Tool.

First, you need to “export” whatever site you want to deploy, then you “import” it where you want to deploy it to.

To export your site, right-click on the root of the site or any application and select Deploy –> Export Application.  You cannot export a normal folder without first converting to an application. The export step is likely your local site that you want to deploy to the web.

Follow the wizard and make any changes that you need.  There are a number of changes and customizations that you can do, although it’s likely that not all of them will be supported by your web host or server administrator.

image

Press Next –> Next.  When you’re prompted for the filename, save to somewhere on your computer and give it a .zip extension.  For example c:\MySite.zip.

Now you have a bundled package of your site which the Web Deployment Tool will use on the Import step.

After you’ve created the package, select the destination, which is likely the site or vdir on the remote web server.  By now, you know the drill.  Right-click –> Deploy –> Import Application.  Select the file that you just saved to your local computer.

image

Press Next and you’ll be presented with a similar screen to what you received during the export.  You can edit this for your particular deployment.

image

Press Next and you’ll be given a choice of the subfolder that you will create during this deployment. 

image

After pressing Next, your site will be deployed to the server.  If you have a large site, only changed will be copied to the server on subsequent deployments.

I expect that the Web Deployment Tool will be used a lot more in months to come.  The tool itself works behind the scenes but it will be leveraged from tools like IIS Manager, Visual Studio and likely many more in the coming days.  Keep an eye on this tool since we may see more of it.

Posted: Oct 08 2009, 09:12 PM by OWScott | with 8 comment(s)
Filed under: ,
Hyper-V – getting host information from the guest VM

Sometimes it’s necessary to find out host machine information from a particular guest virtual machine.

With Hyper-V Integration Services installed, the following registry key contains information about the Host server:

HKLM\SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters

Some keys of interest are:

  • HostName
  • PhysicalHostName
  • PhysicalHostNameFullyQualified
  • VirtualMachineName
  • Plus a number of settings about the Host Server’s version

This is maintained in real-time.  For example, if you rename the virtual machine name in Hyper-V, VirtualMachineName is immediately updated in the guest server, assuming that it’s running.  And, even if it’s not running at the time that you rename the server in the host, it will be reflected when powering on the VM or restoring from a saved state.

Posted: Oct 08 2009, 02:01 PM by OWScott | with 2 comment(s)
Filed under:
Keyboard Shortcuts in Windows 7

Keyboard shortcuts can be huge time savers, so I’ve been pleased to see the many additional shortcuts and mouse movements supported with Windows 7. 

This is a quick blog post on a couple favorites of mine. 

image

  1. When you have a program already opened on the taskbar and you want to open a new instance of that program rather than displaying the already opened instance, Shift-Click.  This will start a new instance.  I use it all the time for applications like Chrome and Notepad.
  2. Use the Windows key plus a number to open a program.  For example, I have Chrome as my 2nd icon so Win-2 will always open Chrome.
  3. If you want to open a new instance using your keyboard use Shift-Win-2.
  4. Be sure to pin your favorite icons to the Task Bar, and your secondary icons to the top of the Start menu.

Here are some links to more good shortcuts:

http://windows7news.com/2009/03/22/master-list-of-windows-7-keyboard-shortcuts/

http://lifehacker.com/5132073/the-best-new-windows-7-keyboard-shortcuts (includes video)

Posted: Sep 29 2009, 01:34 PM by OWScott | with 2 comment(s)
Filed under:
Windows Server 2008 R2 DNS Issues

I recently upgraded my home Windows Server 2008 Domain Controller to R2.  The upgrade process itself wasn’t too much work but was a bit more than ‘next, next, finish’ because the AD schema needed to be updated and the installer required that WSUS be uninstalled first.  But, those weren’t a big deal.

However, after the install, I got the strangest behavior.  Visiting some websites like www.microsoft.com, www.bing.com, www.windowsupdate.com and a number of other Microsoft websites didn’t work.  However, other websites worked perfectly.  In fact, www.google.com still worked.  It’s almost as if Microsoft decided they didn’t want to grow their search engine market share anymore and would start blocking their visitors. :)

What made it even more confusing was that if I viewed the errors in my browser, it timed out and gave a DNS error. However, if I pinged the DNS name, it worked. 

(feel free to skip to the bottom for the fix if you don’t want to read the details)

I did some searching and didn’t find an answer (although now that I know what search terms to look for, I see that others have run into this now).  I tried all the basic troubleshooting methods to no avail.

I skimmed some R2 release notes I found and I saw that there were EDns (EDNS0) changes with R2 but it was pretty vague.  EDns is a relatively new DNS protocol extension that is still coming of age.  Later I realized that I was on to something here.

I realized that I would need to fire up Network Monitor to get the story.  After running Network Monitor, an issue was immediately apparent as seen from the following screen shot snippet:

image

First, I wondered why my search for bing.com returned search.ms.com.edgesuite.net.  The answer to that wasn’t hard to find.  Those are the DNS names of the Akamai CDN which Microsoft uses for a lot of their sites.  The real issue there is the “Response – Format error”. 

I looked at the request and the results for a while and it seemed straight forward, so I did a network trace on a working server and found that R2 added some extra information.  Notice the bottom line of the following image with the “AdditionalRecord:  of type OPT on class Unknown DNSClass”.  The network trace on the working server didn’t have that.

image

So, I knew at this point that R2 was adding something that the Akamai DNS servers didn’t like.  I did a search for OPT and discovered that OPT is used in EDns.  I found a registry setting called EnableEDNSProbes which disables EDNS when set to 0.  After setting that and restarting the DNS Server service, everything worked perfectly.  I set it back again and it stopped working, so I knew I had narrowed it down.

While searching for information on EDns, I discovered that some DNS servers will attempt to make a EDNS probe, and if it fails then it will try again with a plain query.  That allows it to always work regardless of the support of the other DNS servers.  However, after testing I found that Microsoft DNS doesn’t do that.  EDNS can either be ‘on’ or ‘off’.  Bummer, I thought that was a good idea.

Testing further I discovered that it’s not enabled by default on Windows Server 2008 RTM.  I tried on another R2 server that wasn’t in production yet and confirmed that the issue appeared there too.  So, the issue wasn’t that something changed with EDns, it’s simply that it was enabled in R2 for the first time.

The reason that it failed in the web browser but worked with a ping is because the browser followed a redirect and failed on the redirected address and not the original address.  The ping didn’t follow the redirect so the failure never occurred.

It appears that the same issue occured when Windows Server 2003 was released: http://support.microsoft.com/kb/832223.  I don't remember that occuring and being a big deal so I suspect that Microsoft must have made changes to the default with later service packs or hot fixes.

Conclusion

It appears that the Internet isn’t fully up to date and ready to use EDns quite yet.  The solution for this is to disable EDns and wait another year or two until Akamai and other DNS servers catch up, or Microsoft releases a hot fix to support the failback option I mentioned above.

Note that this isn’t a problem for most Windows Server 2008 R2 member servers.  It’s only a problem for DNS *servers* that do recursive lookups.  i.e. likely only your domain controller will be affected if that is where your DNS Server role exists.

Fix

To disable EDns, you can do it from the command prompt, or by editing the registry.

From the command prompt, no restart of DNS is required.  If from the registry, make sure to restart the DNS Server service.

Command prompt: 

dnscmd /config /EnableEDNSProbes 0

No restart is needed.  It takes effect immediately.

or Registry: </>

Create a DWORD called EnableEDNSProbes and set to 0 in HKLM\SYSTEM\CurrentControlSet\services\DNS\Parameters

Restart the DNS Server service for it to take effect.

Understanding Reverse Proxy Servers – and the Mailman

Ok, the goal isn’t to learn about the mailman, but he’s going to come in handy later.

Proxy servers have been around since the early days of computing and they play a large role on the web today: sometimes obvious, sometimes not.  They can be used for good or they can be used for harm, like man-in-the-middle attacks.  Today I want to provide a visual representation of a reverse proxy server used for load balancing.  I also want to address some concepts and potential issues and solutions that often come up with proxy based load balancing.

Definition

Proxy: Dictionary.com: “the agency, function, or power of a person authorized to act as the deputy or substitute for another.”

Proxy server: Wikipedia: In computer networks, a proxy server is a server (a computer system or an application program) that acts as a go-between for requests from clients seeking resources from other servers.

Reverse Proxy: Wikipedia: A reverse proxy or surrogate is a proxy server that is installed in a server network. Typically, reverse proxies are used in front of Web servers.

The proxy server drawn out

This can be easily represented with the following diagrams.  This is oversimplifying the meaning slightly, but it communicates the essence of forward and reverse proxies.

Proxy Server

Reverse Proxy Server

Proxy ReverseProxy

The difference between a forward and reverse proxy server is essentially where it lives and who it targets.  If it’s on the perimeter of the client’s network (like a corporate network or ISP) then it’s a proxy server.  If it sits in front of servers or devices on the web (like in a data center) then it’s a reverse proxy server. 

Proxy servers can be used for any numbers of applications, some of them include:

Forward Proxy Server Examples

  • Caching web pages to increase the perceived speed of the internet.  AOL has been known over the years for their poor implementation of proxy servers for their users.  Many corporate networks use proxies successfully.
  • Filtering to ensure that inappropriate or unapproved content isn’t allowed to the end user.  These are common in corporate environments, schools and colleges. A NetNanny-type of product functions as a proxy server/service.

Reverse Proxy Server Examples

  • Caching content for performance for a web server at the data center.  Speeds up a website for all users of that website.
  • Load balancing a few servers to distribute load.  Allows scalability or redundancy.
  • Webpage treatments for client-side performance gains.

 

 

As you can see, there are many reasons for proxy servers, and they are in operation all over the web.  It’s possible that a proxy server is being used for you to see this website right now.

Direct Server Return

I want to briefly mention another type of method used by some load balancers, called Direct Server Return (DSR). It’s helpful to contrast this with a Proxy Server.

Load Balancer using Direct Server Return

ProxyDSR

Notice that the load balancer isn’t as aggressive as the ones in the previous diagrams.  It passes on the request from the client to the web server and then it minds its own business and stays out of the rest of the communication.  In fact, with this solution, the web server barely even realizes that the load balancer played a role.  In this role, a load balancer is not taking the role of a reverse proxy server.  It does not stand in the middle for the whole process.

Additionally, even though routers and switches are middle-men between the client and server, they are not considered proxy devices either. 

Reverse Proxy Servers and Load Balancers

Now on to the main points that I want to cover.  Recently I’ve started to work with Microsoft’s new Application Request Routing (ARR) load balancer which I’ve been extra impressed with.  I plan to post more over time on how to really leverage this as a full blown flexible, stable and scalable load balancing solution.  Over the last few years I’ve been using DSR based load balancers for the most part.  As a result of working with ARR, I’ve run into a few concepts and addressed a few issues that I want to cover here.

The Mailman as a Proxy

The biggest issue that comes up with proxying requests is that it’s nearly impossible for the proxy (or reverse proxy) server to stay hidden.  Consider the mailman who delivers mail to your house each day.  He’s not the original sender, but he’s the person that, at first glance, appears to be the sender.  How many jokes are made of the mailman building a romantic relationship with the wife?

Mailman

The mailman is a type of proxy.  The trick is to make sure that you can tell who the original sender is, and that you don’t get confused and give the mailman credit for a letter that’s not from him.  You certainly don’t want your love letters to your spouse or significant other being credited to the wrong person. 

In the case of the mailman, there is some evidence of the postal system proxying the mail, in the form of markings in the top right corner.  However the larger markings are the ‘return’ and ‘to’ addresses.  It’s important for the receiver to understand which markings to pay attention to and which to ignore.

The Proxy Server Leaves a Mark

When a server acts as a proxy, it will change some of the request headers.  In particular, the headers to watch for are:

  • REMOTE_ADDR
  • REMOTE_HOST
  • Some proxy servers can also off-load SSL, which means that it will proxy from SSL to HTTP.  In that case SERVER_PORT and some certification headers come into play.

In the case of IIS and the web server, it will try to set REMOTE_ADDR and REMOTE_HOST to the IP of the proxy server.  Any code that depends on these headers will get confused.  For example, if you check for blog spam by client IP, you may check REMOTE_ADDR from code.  With the proxy server in-between, it will appear that all traffic comes from a single IP.  Additionally the web server will log the traffic as coming from the proxy server.

To avoid this impacting affect caused by the proxy server, it’s necessary to rewrite all relevant header and log information back again so that it appears to come from the original sender.  This can be done various different ways, but I’ll cover a common method, and how ARR handles this.

ARR’s Header Rewriting

With ARR, this can be handled one of four ways:

  1. Ignore the issue.  Some people don’t have any site features that depend on knowing the client IP, and they are fine with not knowing the client IP in their site statistics. 
  2. Update your code to use the custom headers that ARR sets, namely X-Original-URL, X-Forwarded-For, X-ARR-SSL, X-ARR-LOG-ID.  This won’t address the IIS logs, but it can address everything else.
  3. ARR Helper.  Anil Ruia, one of the primary ARR developers, has written a helper module that works in IIS7 to rewrite the relevant headers back.  The ARR Helper module is not officially supported by Microsoft, but works like a charm.  ARR itself will place the original client’s site in a configurable request header, which is X-Forwarded-For by default.  It will also place certificate information for SSL offloading in X-ARR-SSL.  On the actual web server, the ARR Helper runs silently in the background and will rewrite those headers back to REMOTE_ADDR, REMOTE_HOST, SSL and REMOTE_PORT.  It will also ensure that the logs recover the original client IP.  It’s installed at the server level and doesn’t have any impact on non-load balanced sites and performance overhead is negligible (for load balanced or non-load balanced).  We’re running this in production at ORCS Web and are very pleased with the results.  No code changes are necessary for the site owner.
  4. With ARR and URL Rewrite 2.0, currently in Beta, it can also do the same thing.  ARR itself takes care of the writing on the ARR server, and URL Rewrite 2.0 can rewrite the X-Headers back to the appropriate locations.  URL Rewrite 2.0 needs to be installed and configured on each of the web servers.  Currently I’m running this in testing only since version 2.0 does not have a go-live license, but the end goal is to use URL Rewrite for the web server rewriting.  While Anil’s solution works perfectly, this will be the Microsoft supported solution moving forward.

In future blog posts, I hope to dig deeper into ARR technically, but I wanted to lay the groundwork first on the concept of proxying, and what you need to consider by having a middle man between the client and web server.

Posted: Aug 08 2009, 12:46 PM by OWScott | with 4 comment(s)
Filed under: ,
Creating WinPE with Integration Services for Hyper-V

At ORCS Web, we’re using System Center Configuration Manager (SCCM) with Microsoft Deployment Toolkit (MDT) and have it set to deploy new images to physical or virtual hardware. 

Most everything works great, but the one thing I’ve wanted to get working is to add the Hyper-V Integration services to the Boot Image (WinPE in this case) so that 1) the regular Network Adapter (not the Legacy adapter) works and 2) there is mouse support right from the beginning.  Once the boot image is created, the Hyper-V virtual machine can have the .ISO image mounted as bootable media. 

Note that PXE boot with Hyper-V still requires the legacy network adapter (as far as I’ve been able to determine anyway).  The better way to go is to use bootable media that can be mounted to the VM as a virtual CD/DVD drive. I’ll set out to cover how to do that here.

The following three links got me going in the right direction.  However, it appears that the vmguest.iso file changed from when they wrote their blog posts until now, so I used different files then they did:

Here are the key steps:

  1. Go to an existing Hyper-V VM and insert the Integration Services Setup Disk. This is easiest with a server which you have already installed the Integration Services on so that you will have your mouse for the remaining steps.
    image 
  2. Don’t run the installation now.  Instead, use Windows Explorer and navigate to the new drive and the Support folder.  There are 2 subfolders: amd64 and x86.  To create your 32-bit image, use the x86 folder.  To create your 64-bit image, use the amd64 folder (even if it’s Intel 64-bit).  I created two folders on my SCCM server.  One for x86 and one for x64.
  3. Simply double click on the .cab file to view the contents.  The file will be named Windows6.0-HyperVIntegrationServices-x64.cab or Windows6.0-HyperVIntegrationServices-x86.cab.
  4. Copy the contents of that cab file to your SCCM server.  I do it over a UNC network path, but you can use whatever means of copying that you prefer.  You don’t need all of the files in the cab, but it’s a small cab and easiest just to copy everything over.

    Note: Now that you have the drivers, add them to your boot image.  You can use whatever method that you use for your boot image, but I’ll include instructions for SCCM here.
  5. Fire up Configuration Manager Console (ConfigMgr Console).
  6. Expand Site Database (your instance) / Computer Management / Operation System Deployment.
  7. Right-click on Drivers and click Import. The Import New Driver Wizard appears.
  8. In the Locate Driver step, point to the folder where you copied the cab contents to.  Run this twice, once for 32-bit and once for 64-bit.
  9. In the next step I imported all drivers even though I only use 4 on a later step.  I figured that I may use them for something else in the future.  So, leave everything checked.
  10. Assign a category that mentions the bitness of the drivers so that you can tell the difference later.
  11. In the Add Driver to Packages step, create a new package or assign to an existing package.
  12. Don’t do anything on the Add Driver to Boot Images step since we don’t want all of the drivers assigned to the boot images.  Click Next.
  13. Click Next to finish the Driver import.

    Now that the drivers are imported into SCCM, you need to add them to your boot image
  14. In the Drivers section of SCCM, find and select the following drivers for either x86 or x64:
    1. Microsoft Virtual Machine Bus Network Adapter (for network support)
    2. Microsoft Virtual Machine Bus Input Device Miniport (for mouse support)
    3. Virtual Machine Bus (I’m not sure if this is needed, but I added it anyway)
  15. Right-click and click Add or Remove Drivers to Boot Images.
  16. Check the boot image that you want to add to and click Update distribution points when finished.
  17. Finally, recreate your boot media. 

Now you will be able to install an OS on a Hyper-V VM using the regular network adapter and mouse support.

As a side, I hoped that I could use x64 boot media and install both x64 and x86 operating systems.  That would save me from choosing between the images as long as the hardware supports x64.  Unfortunately it didn’t appear to work.  I ran into driver issues later in the install process.  I’m not saying that someone else can’t get it figured.  It may be possible to embed the x86 drivers into the x64 boot image, but I didn’t take it that far. What I did prove is that configuring the x86 and x64 images identically wouldn’t allow the x64 boot image to deploy an x86 OS.

More Posts Next page »