4

For the moment I'm stuck with an IIS-server, unfortunately not my best subject (I'm much better w. Apache). We have a site on a Win 2008 R2 Server with IIS 7.5. It's an old site and we are working on a new site on a new server. But until the new site is up and running, we need the old site.

The company has the name "examplesite" but is called "example".

I have 8 URLs, with all combinations of:

  • HTTP and HTTPS
  • www and no-www
  • example.com and examplesite.com

And I want, no matter what you write in a web browser's address bar, you will go to:

https://example.com

I have tried for a couple of days now with both rewrite and redirect and I can't get it working. (I get some of the addresses working correctly, but not all)

Please, how do I fix this?


Edit to add:

Sorry, but my problem seems to be another than I thought from the beginning. I have only one SSL-cert on the server, a single binding cert for example.com. As I understand I can only have one single binding cert per IP-address on the server.

So the part that doesn't work now is the https part for www.example.com, examplesite.com and www.examplesite.com. I use Let's Encrypt and they have "SAN certificate for all bindings on multiple IIS sites" - I have have to figure how to use that choice when I create the cert.

  • To confirm, you already have SSL certs configured for all combinations of www/no-www and example.com and alias.example? Please include the config you have tried that gets you part way there. And for the URLs that aren't redirected, presumably it just doesn't do anything? – MrWhite Sep 5 at 13:34
2

Assuming you're using the URL Rewrite Module, you can use the following set of rewrite rules in the web.config:

<system.webServer>
  <rewrite>
    <rules>
      <rule name="ForceToExample.com" stopProcessing="true">
        <!-- Match any path -->
        <match url="(.*)" />
        <conditions>
          <!-- Domain is "examplesite.com" regardless of any subdomain -->
          <add input="{HTTP_HOST}" pattern="^.*examplesite\.com" />
        </conditions>
        <action type="Redirect" url="https://example.com/{R:1}" redirectType="Permanent" />
      </rule>
      <rule name="ForceFromWww" stopProcessing="true">
        <!-- Match any path -->
        <match url="(.*)" />
        <conditions>
          <!-- Domain starts with "www." regardless of actual domain -->
          <add input="{HTTP_HOST}" pattern="^www\..*" />
        </conditions>
        <action type="Redirect" url="https://example.com/{R:1}" redirectType="Permanent" />
      </rule>
      <rule name="ForceToSsl" stopProcessing="true">
        <!-- Match any path -->
        <match url="(.*)" />
        <conditions>
          <!-- If the request wasn't secure, regardless of domain -->
          <add input="{HTTPS}" pattern="ON" negate="true" />
        </conditions>
        <action type="Redirect" url="https://example.com/{R:1}" redirectType="Permanent" />
    </rules>
  </rewrite>
</system.webServer>

Ordering can be important - rules are processed from top to bottom, and can "fall through", so that subsequent rules can also affect a request - in this case as the action type is Redirect, the stopProcessing directive is probably redundant.

Each of these rules will honour the original path, so a request to http://www.examplesite.com/folder/page1.aspx should end up on https://example.com/folder/page1.aspx.

To explain the rules:

  • ForceToExample.com
    This will redirect any request to examplesite.com or www.examplesite.com to https://example.com, regardless of the original scheme (http or https).
  • ForceFromWWW
    This will redirect any request (that wasn't already redirected) from www.example.com to https://www.example.com/, regardless of the original scheme.
  • ForceToSsl
    This will redirect any request (that wasn't already redirected) from http://example.com to https://example.com

I've deliberately left the element of redundancy in those rules as I feel it makes it easier to read and understand what each one does.

Expected behaviour:

  • http://www.examplesite.com/ would match ForceToExample
  • https://www.examplesite.com/ would match ForceToExample
  • http://examplesite.com/ would match ForceToExample
  • https://examplesite.com/ would match ForceToExample
  • http://www.example.com/ would match ForceFromWww
  • https://www.example.com/ would match ForceFromWww
  • http://example.com/ would match ForceToSsl
  • https://example.com/ wouldn't match any rules and will be handled by your application

A couple of additional points to note:

  1. If you have moved the <rewrite> or <rules> elements out of your web.config file, you will need to restart the application to see your changes in action.
  2. While testing, I prefer to use redirectType="Found" in the action - this issues a 302 redirect and your browser doesn't cache the new request.

Edit to cover the single certificate issue

You're right that normally you can only have one SSL binding per IP address on an server, however Server Name Identification (SNI) allows you to have multiple SSL bindings on a single IP address in a way that works with all modern browsers.

Unfortunately IIS 7.5 only supports this for wildcard certificates and even then only for one wildcard certificate, installed with a leading * in the name (i.e. *.example.com rather than Wildcard example.com). This would allow you to handle requests to https://www.example.com and https://example.com, but wouldn't help you with either Let's Encrypt certificates or examplesite.com (you can't get a wildcard SAN certificate).

Possible solutions would be to use SSL termination features of some CDNs (CloudFlare, Azure Front Door and others for example) to secure requests to their CDN, and then requests from the CDN to your server are sent unsecure (these aren't seen by the client browser) and they also allow you to do redirects at the edge (from www.example.com to example.com), which might help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.