IIS URL Rewrite behaves differently for HTTP vs HTTPS - iis

I've been trying to use the URL Rewrite module to create a rule that looks for any set of two or more forward-slashes in the URL (past the first set) that will redirect the browser to a URL with all sets of multiple forward slashes replaced with just one. Example:
http://myhost.com/abc//def//ghi//jkl//iisstart.png
should redirect to
http://myhost.com/abc/def/ghi/jkl/iisstart.png
I already understand that IIS sees these two URLs as functionally equivalent, but for this public-facing site we want to avoid any chance that crawlers will index URLs with the multiple forward slashes; hence the redirection. So here's the rule I put together:
<rule name="Redirect URLs with Multiple Forward Slashes" enabled="true" patternSyntax="ECMAScript" stopProcessing="true">
<match url=".*" />
<action type="Redirect" url="{URL}" appendQueryString="true" />
<conditions logicalGrouping="MatchAny">
<add input="{UNENCODED_URL}" pattern="//" />
</conditions>
</rule>
I tested this on my local box, and it produced the expected outcome (the redirection). I copied it into a web.config on a development server and tried it out, but it didn't work. I even took the path of making sure the URL Rewrite installation matched the version on the development server (it's 2.0, and upgrading would be a pain in our large production server farm so I'd like to avoid that). After that, I took into account that our development server, by design, only serves up HTTPS, while I'd been testing in HTTP on my local box. When I enabled HTTPS on my local box, the rewrite rule didn't work with an HTTPS URL but worked fine with an HTTP URL pointing to the same resource.
All the URL Rewrite documentation I've looked at makes reference to HTTP, and there are no references to HTTPS. What am I doing wrong here?
For the record - my local box is running Windows 10, and has IIS version 10. The dev server is running Server 2012, and has IIS version 7.5.

Related

Windows IIS ARR Reverse Proxy Encoding Issue

We have an environment with an Windows 2019 Server IIS 10, which is acting as Reverse Proxy (ARR) for my IIS Server farm (Application Request Routing 3.0 and URL Rewrite 2.1). We send the users name in the HTTP headers. But my ARR somehow screws up the encoding (we are using german special characters, e.g. ö,ü,ß...), so when i check the respone of the WebServer it shows me: H%C3%B6lmuth M%C3%A4%C3%9Fterm%C3%BCller instead of Hölmuth Mäßtermüller.
I have an old environment with Windows 2012R2 Server with the same configuration, in this environment the display of the name is correct. I have checked all kind of settings between old and new servers, but cannot find any difference.
Futher i have used Failed Request Loggins and Network Monitor to see what the server receives and sends, below find the results.
Received Request on the IIS ARR (old and new):
X-AUTHENTICATE-FamilyName: M%C3%A4%C3%9Fterm%C3%Bcller
X-AUTHENTICATE-GivenName: H%C3%83%C2%B6lmuth
X-AUTHENTICATE-cn: H%C3%B6lmuth M%C3%A4%C3%9Fterm%C3%BCller
Request send to the IIS (new):
X-AUTHENTICATE-FamilyName: M%C3%A4%C3%9Fterm%C3%BCller
X-AUTHENTICATE-GivenName: H%C3%83%C2%B6lmuth
X-AUTHENTICATE-cn: H%C3%B6lmuth M%C3%A4%C3%9Fterm%C3%BCller
Request send to the IIS (old):
X-AUTHENTICATE-FamilyName: Mäßtermüller
X-AUTHENTICATE-GivenName: Hölmuth
X-AUTHENTICATE-cn: Hölmuth Mäßtermüller
Anyone has an idea how i can change this behaviour? Help would be much appreciated.
Can you give me an example how to use the {UNENCODED_URL} variable. Currently we are using the rewrite module to route requests to specific Server Farms, see my rules below:
<rewrite>
<globalRules useOriginalURLEncoding="true">
<rule name="ARR_BPBP-DEV_loadbalance" patternSyntax="Wildcard" stopProcessing="true">
<match url="*" />
<action type="Rewrite" url="http://BPBP-DEV/{R:0}" />
<conditions>
<add input="{HTTP_HOST}" pattern="bmi-bpbp-dev.vecos.at" />
</conditions>
</rule>
<rule name="ARR_BPBP-TEST_loadbalance" patternSyntax="Wildcard" stopProcessing="true">
<match url="*" />
<action type="Rewrite" url="http://BPBP-TEST/{R:0}" />
<conditions>
<add input="{HTTP_HOST}" pattern="bmi-bpbp-test.vecos.at" />
</conditions>
<serverVariables>
</serverVariables>
</rule>
</globalRules>
How can i adapt the rules to use the {UNENCODED_URL} variable?
When an HTTP request arrives on Windows, the latest HTTP.sys encodes both URL and HTTP headers, and puts the original URL in UNENCODED_URL server variable so that it can be recovered afterwards.
However, the original headers (such as X-AUTHENTICATE-FamilyName: Mäßtermüller) do not seem to be preserved (no clear documentation on that), so there isn't any easy way to recover them.
If you want to modify the the header from X-AUTHENTICATE-FamilyName: M%C3%A4%C3%9Fterm%C3%BCller back to X-AUTHENTICATE-FamilyName: Mäßtermüller, the only way I can think of is to write a custom IIS module to perform the decoding step.
Alternatively, you might modify your other code to accept such encoded header values (and decode them when needed in your code), as anyway that's how Windows/IIS behaves now and you cannot fight it.
Try to set the useOriginalURLEncoding to false, and URL rewrite will no longer encode the urls when using the {UNENCODED_URL} variable in the rules.
To set the flag to go IIS Manager then select Configuration Editor and go to the section system.webServer/rewrite/rules, where you will find the useOriginalURLEncoding flag.

web.config redirect to another domain on 404 error

We are migrating our old site to a new one (wordpress hosted on Azure) but for some reasons we need to maintain the old one one online. Suppose the site are:
new site www.site.com
old site www.oldsite.com
This is what we need:
if a user enter www.site.com/somepath and this doesn't exist, it must be redirected to www.oldsite.com/somepath.
Is it possible by setting url rewrites in web.config or by redirecting 404 error to the old domain?
Thank you in advance,
Marco
From your information, I'd assume you are using WordPress template (not WordPress on Linux) from Azure Marketplace (in which during the WordPress web provisioning, you are asked to chose whether Azure MySQL or MySQL in App option). You can download IIS Manager extension and remotely connect to your site then start writing your rule. You can also download the web.config file (via FTP and make it up yourself). Here is the reference of web.config https://social.technet.microsoft.com/wiki/contents/articles/32229.azure-create-an-url-rewrite-azure-web-app.aspx
The below is sample rule
<rewrite>
<outboundRules>
<rule name="404redirection">
<match filterByTags="None" serverVariable="{RESPONSE_STATUS}" pattern="^404" />
<conditions>
<add input="{HTTP_HOST}" type="Pattern" pattern="^http://newwebsite.net/somepath(.*)">
</conditions>
<action type="Redirect" value="http://oldwebsite.net/somepath(.*)" />
</rule>
</outboundRules>
</rewrite>
Note that this is the sample rule based on the web server variable with HTTP response (404). If you WordPress uses some custom query strings or so on, the rule is supposed to be more complicated than this one.

Redirect to FQDN in IIS Not Working

None of the answers I've found to questions like this (notably this one) work for me, so here I go.
We are running IIS 8 on Windows Server 2012 R2. We have a wildcard certificate (*.mydomain.com) installed on the server. On the Default Web Site we have a single binding to accept incoming https requests on port 443. I have a second Web Site set with a single binding to accept incoming http requests on port 80.
On the latter Web Site I've created a URL Rewrite rule to redirect all incoming non-HTTP traffic to https://myserver.mydomain.com{REQUEST_URI}, and this works perfectly. If I browse to either http://myserver.mydomain.com/homepage or http://myserver/homepage, I am sucessfully redirected to the HTTPS version of the site with the full domain name included and thus it loads just fine.
If I browse to https://myserver.mydomain.com/homepage, the site also loads perfectly.
However, I am trying to create another URL Rewrite rule on the Default Web Site so that requests to https://myserver/homepage (Note: HTTPS but the full domain name is omitted) are redirected to the https://myserver.mydomain.com/homepage. The reason for this is that the SSL certificate is only matched if the full domain is included. As it stands, if I enter https://myserver/homepage I get a security warning (NET::ERR_CERT_COMMON_NAME_INVALID).
I've created the rule which I think should work, based on the answer I linked to above, but it doesn't work and I don't know why. My rule look like this:
<rewrite>
<rules>
<rule name="Redirect to FQDN" enabled="true" patternSyntax="ECMAScript" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^myserver$" />
<add input="{HTTPS}" pattern="^ON$" />
</conditions>
<action type="Rewrite" url="https://myserver.mydomain.com/{R:1}" />
</rule>
</rules>
</rewrite>
Even with this rule in place and enabled, when I browse to https://myserver/homepage I get the security message. What am I doing wrong with this rule?
Problem is that you have SSL only for *.mydomain.com. And when you accessing https://myserver it will return certificate error because your cert is not valid for this domain.
For better understanding about steps during SSL connection:
In your case, the problem is between step 2 and 3

URL ReWriting to a different server - rules are ignored and default website is answering requests

I'm struggling with IIS' URL Rewrite and ARR Modules.
Basically, here's the current state of affairs:
I have a main webserver, awnsering all of my requests. Let's name this MAINWEBSERVER.
I have a secondary server with a specific application that's working as intended if you access it internally but needs to be exposed to the outside via domain to work as a webservice. Let's name this server APPSERVER.
I wish to receive my requests on MAINWEBSERVER and rewrite the URL if it matches my wildcard.
In this case, my Wildcard is https://example.com/MYAPPLICATION* .
And my desired redirect is https://APPSERVER/MYAPPLICATION/WhateverIsLeftInTheUrl .
So here's my rule sitting on my MAINWEBSERVER:
<rewrite>
<rules>
<rule name="Rewrite to Application" patternSyntax="Wildcard" stopProcessing="true">
<match url="https://example.com/MYAPPLICATION*" />
<action type="Rewrite" url="https://APPSERVER/MYAPPLICATION{R:1}" logRewrittenUrl="true" />
</rule>
</rules>
</rewrite>
NOTE: I need the URL rewritten for certificate SAN purposes (it won't validate APPSERVER/MYAPPLICATION, so I want to use a mask that is validated by my certificate, such as https://example.com/MYAPPLICATION).
The steps I took were:
Installing ARR (activating proxy settings);
Installing URL ReWrite Module;
Configuring wildcard rule for https://example.com/MYAPPLICATION;
Configuring rewrite for https://APPSERVER/MYAPPLICATION{R:1} (in case it has querystrings I wish to keep them);
Generated personal certificates to validate HTTPS requests between MAINWEBSERVER and APPSERVER;
Whenever I make my request the rule is ignored (despite the same URL matching the wildcard perfectly) and the default website application awnsers, considering my wildcard a querystring parameter.
I've tried this both at server level and at default website level, even with Reverse Proxy Rules. I also have experimented with Fiddler and Failed Request Tracing but to no effect.
In the FRT all that is displayed is a 302 HTTP CODE and in the end a 200 Status Code when the default website loads.
Note that I believe this was working on a different server before, using this same rule although there was no default website.

ARR/URL Rewriter within a .net Web API application

I have two applications. One of which is going to handle authentication across a range of products. Because of this, from each one I want to rewrite a URL from each individual website to our "authentication" project. It would look something like this.
http://www.mywebsite.com/api/profile/login -> http://www.myauthentication.com/api/profile/login.
So essentially pushing the request cross domain.
For this I have setup ARR and URL Rewriting in IIS. However I can't seem to get it to work, and I have a feeling URL Rewriting is not running on requests that would normally cause a 404. I think this because on a REDIRECT request (301 redirect), the config works perfectly. When I use a rewrite, I get a generic 404 page.
The rules configuration looks as per below :
<rules>
<rule name="Route the requests for the Profile API." enabled="true" stopProcessing="true">
<match url="^profiles/(.*)" />
<action type="Rewrite" url="http://authentication.local/api/profiles/{R:1}" logRewrittenUrl="true" />
</rule>
</rules>
It should be noted that I am using the WebAPI, not MVC, which I'm not sure if that is causing issues or not. Because the redirect works but not the rewrite, I'm sure I've got everything installed OK in IIS.
For ARR, I have simply ticked "Enable Proxy" but I am unsure if I need to do anything else.
I managed to solve this by adding an ignore route for ARR.
RouteTable.Routes.IgnoreRoute("api/profiles/{*pathInfo}");

Resources