Thursday 29 March 2012

URL Rewrite module in IIS 7 with shared config

We've waited a long time for a relatively simple URL Rewrite module in IIS.  It's not news that we've now got it, in IIS 7 onwards, but it's not baked in as standard (unlike most distributions of Apache where mod_rewrite is most likely the first module on the list).

You can download URL Rewrite from here (x64): http://go.microsoft.com/?linkid=9722532 or here (x86): http://go.microsoft.com/?linkid=9722533 and there's plenty of documentation here: http://www.iis.net/download/urlrewrite

One area that causes a bit of difficulty though is when Shared Configuration comes into play.  Shared Configuration is a handy little facility built into IIS that lets you maintain one configuration across multiple IIS servers - so it's great for a web farm setup.

What's not so great is that it doesn't play nice with the URL Rewrite module.  So having been through the pain of getting the two working together, I thought I'd write it all down, so you don't have to.

So I'm assuming you already have your shared config up and running, everything is fine and dandy, but (like me) you've just got an SSL certificate and you now want to force all HTTP traffic to HTTPS. This is what we do:

  1. Disable shared config on both nodes.  This is at the server level:

    Shared configuration - it's at the server level, not the site

    Untick the check box, and hit 'Apply'.  You'll see a scary-looking dialog box:

    Looks scary, but it's only asking whether you'd like to hold on to the config you know works, or swap it for something ancient that probably doesn't.  The right answer is 'Yes'.

    The question here is 'do you want to overwrite your local config with the shared config to keep things working the same as when they were shared'? 'Yes' is the answer here - you simply don't know what's in that local config directory so you'll want to overwrite it with what you do know.

    Don't worry, we're not restarting IIS, just the Manager.  Oh, and the Management Service.

    Close and re-open IIS Manager.  At the server level, find 'Management Service' - it's at the bottom of the page, under 'Management'.  Right-click and select 'Restart'.

    That's the Management Service. That's at the server level too.

    Now repeat on the other nodes that share the same config!

    Check that your site still works - load balancing and DFS should still be working just the same, but remember that the IIS configurations are now managed separately, down in the bowels of C:\Windows\system32\inetsrv.
  2. MAKE SURE NO OTHER CONFIG CHANGES HAPPEN!!

    Now you can't rely on IIS to keep the config the same between the servers, so you need to be very careful not to introduce any un-controlled differences between your configs. Tread very carefully...
  3. Install the URL Rewrite module on both nodes, and make sure it's working.

    The module comes as a standalone installer, so it should just be a case of clicking through the wizard and letting it do its thing.

    Close and re-open the IIS Manager, and you should see the URL Rewrite module available under 'IIS' at the site level.

    Success! URL Rewrite is alive! At the site level...

    Check this is available on each node in the web farm.
  4. Re-create the shared configration

    Firstly, we need to export the local configuration on one of our servers to use that as the new shared config. At the server level, go to 'Shared Configuration' and firstly select 'Export Configuration' (it's over on the right).

    Select the 'physical path' as the original shared config location (that's right, we're going to overwrite the old shared config with the local config from this server!).  Choose an encryption password - make a note of it as you'll need it for every node you do this on.

    Now, tick the 'Enable shared configuration' box and choose the physical path that you just saved the config to.  Don't worry about user name or password.

    Apply this change (again, it's over on the right) and you'll have to enter the encryption password, and restart IIS Manager (and management service) again.
  5. DON'T BE SCARED!!!!

    You might find that this momentarily generates some 503's (Service Unavailable) on your site - don't worry, it's momentary and everything should be up and running again very quickly.
  6. You should now have a shared config running URL Rewrite.
  7. Add your rules into the 'URL Rewrite' section against the site config in IIS.

    You can add this into your web.config file (there will probably already be some stuff in the <system.webServer> area)

    <system.webServer>
            <rewrite>
                <rules>
                    <rule name="Force HTTP to HTTPS" stopProcessing="true">
                        <match url="(.*)" />
                        <conditions>
                            <add input="{HTTPS}" pattern="off" />
                        </conditions>
                        <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="Found" />
                    </rule>
                </rules>
            </rewrite>
    </system.webServer>


    Or, if you prefer the GUI, your rules should look like this:

    The rewrite rules. At the site level.

    And the rule detail looks like this:

    The detail.

  8. Remember, the shared config ensures that your changes get propagated throughout your web farm, so that should be that, your site should now successfuly rewrite all HTTP requests seamlessly to HTTPS.
At least, that's the theory.  I completed this successfully on a pair of fresh VMs today, I'll update when I've done it for real on our boxes that have been in production for months...

No comments:

Post a Comment