Using URL Rewrite for Cross-Domain Http Requests - iis

I am trying to write an inbound rewrite rule that basically captures all the requests to the root folder /api/*, and rewrite it to api.v2.movideo.com respecting the HTTP vs HTTPS traffic.
I followed the step by step instructions here: http://code.movideo.com/Setting_up_IIS7_to_use_URL_Rewrite_2.0_for_Cross-Domain_XMLHttpRequest_Calls
I installed Application Request Routing http://www.iis.net/expand/URLRewrite
Followed all the steps on that page, removed the instructed headers, did everything by the book, but all I get is this:
HTTP Error 500.50 - URL Rewrite Module Error.
There is a problem with the resource you are looking for, so it cannot be displayed.
When I change the rule from REWRITE to REDIRECT, it works fine, but it redirects, not rewrites! Ugh. What's going on here?
Here is my Rule:
<rule name="ReverseProxyInboundRule1" stopProcessing="false">
<match url="^api/(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{CACHE_URL}" pattern="^(https?)://" />
</conditions>
<action type="Rewrite" url="{C:1}://api.movideo.com/{R:1}" />
<serverVariables>
<set name="HTTP_ACCEPT_ENCODING" value="" />
</serverVariables>
</rule>
(2nd question: Are there any problems or things I should know installing Application Request Routing? It added a new 'Server Farms' section in my IIS, hmmmm...I have no idea what this is all about. )

If there are processing rules AFTER this rule, consider setting the stopProcessing attribute to true
Because you are using a serverVariables node, you must add the server variable to the allowedServerVariables collection for your server. Your can do this from using the IIS UI (details here: Setting HTTP request headers and IIS server variables) or from the command line:
%windir%\System32\inetsrv\appcmd.exe set config -section:system.webServer/rewrite/allowedServerVariables /+"[name='boo']" /commit:apphost

Related

Unable to remove server header details with URLRewrite in IIS 8.5

I have two queries regarding URLRewrite module.
To remove server information from header I had installed URLRewrite module in IIS8.5 and added changes in web.config.
<outboundRules rewriteBeforeCache="true">
<rule name="Remove Server header">
<match serverVariable="RESPONSE_Server" pattern=".+" />
<action type="Rewrite" value="" />
</rule>
</outboundRules>
</rewrite>
but I am still able to see server details. Do I need to configure these values in IIS to work?
Also, can URLRewrite cause delay in response time?
1.I tested your outboundRules and it works normally on my side. did you add RESPONSE_Server to Server Variables? If not, please add it.
2.URL Rewrite will cause delay in response time, but usually it can be ignored.

IIS Rewrite Module: Change set-cookie path rule

I am modifying my tor reverse proxy in IIS so that it must be accessed through a php page in my cgi-bin.
Here's where I'm stuck: I need to change the path value of all cookies set by the reverse proxy.
Example:
I request /cgi-bin/tor.php?url=easycoinsayj7p5l.onion/register.php in my browser. A backend local request is made to /tor/easycoinsayj7p5l.onion/register.php. A php session cookie is set with the path=/tor/easycoinsayj7p5l.onion/. This cookie does not set properly because the request is being made by /cgi-bin/tor.php. The path needs to be changed to /cgi-bin/ so the cookie can be set and accessed.
Below is the rule I've come up with to change this in the outbound requests section, however, it doesnt seem to do anything.
<rule name="rewritecookiepath" preCondition="" enabled="true">
<match serverVariable="RESPONSE_Set_Cookie" pattern="(.*)(Path=(.*); )(.*)" />
<conditions logicalGrouping="MatchAny" trackAllCaptures="true">
<add input="{URL}" pattern="(.*)" />
</conditions>
<action type="Rewrite" value="{R:1} Path=/cgi-bin/; {R:4}" />
</rule>
Please advise me what I'm missing!
-Thanks
The rule works fine on my side.
So please enable failed request tracing and it will show the root cause. I asssume there was something wrong with the value of Set-Cookie header.
https://learn.microsoft.com/en-us/iis/extensions/url-rewrite-module/using-failed-request-tracing-to-trace-rewrite-rules#:~:text=If%20the%20Failed%20Request%20Tracing,module%20installer%20in%20repair%20mode.

Socket.io + IIS 10 + reverse proxy setup

The goal is to host a socket.io server on the same port and domain as my website, hosted on IIS 10 using a reverse proxy. And Ideally configure SSL in IIS rather than the socket.io app.
From what I read, this can be achieved using a reverse proxy URL rewrite rule.
However my javascript client application is showing this error:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'serve://dist' is therefore not allowed access. The response had HTTP status code 502.
I have setup a reverse proxy URL rewrite rule to match (regex) the URL socket\.io\/(.*) and rewrite it to localhost:8001/{R:0}
My web.config contains this:
<rewrite>
<rules>
<clear />
<rule name="ReverseProxyInboundRule1" enabled="true" patternSyntax="ECMAScript" stopProcessing="true">
<match url="socket\.io\/(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="localhost:8001/{R:0}" />
</rule>
</rules>
</rewrite>
I don't see anywhere where you can differentiate between http:// and ws://.
I honestly don't have a clue what I'm doing. A lot of the stuff I read online is outdated and really not very helpful.
Any help would be appreciated?

URLRewrite "Redirect" rule works, but "Rewrite" rule fails (404)

I have following rewrite rule:
<rule name="First Rule" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^Tracking/(.*)" ignoreCase="true" />
<action type="Rewrite" url="http://www.example.com/" />
</rule>
This failes, calling http://www.myserver.com/Tracking/123 returns a 404.
However, if I change the action type into Redirect, the rule suddenly works fine, performing a redirect:
<rule name="First Rule" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^Tracking/(.*)" ignoreCase="true" />
<action type="Redirect" url="http://www.example.com/" />
</rule>
But I need a rewrite rule, as I need a reverse proxy to an internal server.
I'm working on a Windows 2008R2 Server (IIS 7.5), have "IIS URL Rewrite Module 2" installed,...
What is wrong with the Rewrite rule ?
Since you mentioned that you're setting up a reverse proxy to an internal server. If a URL Rewrite destination is outside of the server performing the rewrite, you will need to install Application Request Routing to enable proxy capabilities. After installing Application Request Routing (ARR), you'll need to go to its proxy settings and check the Enable Proxy feature. A full blog on this setup can be found here. If this has already been performed, I would recommend using Failed Request Tracing on both the reverse proxy and destination server (if the destination server is IIS) in order to better understand where the HTTP 404 response is coming from.

IIS Reverse Proxy Re-Encoding URLs Containing Percent Sign (%)

I am trying to set up a reverse proxy for Jenkins using IIS 7.5, Application Request Routing 3.0 (ARR), and URL Rewrite 2.0.
I have the proxy mostly working, but am running into issues with URLs that contain the percent symbol (%).
No matter what I try, the proxy insists on either de-encoding or re-encoding the percent sign in the rewritten URL.
This is how I want the URLs rewritten:
http://my.proxy/a%2Fb -> http://my.host:8080/a%2Fb
This is how the URLs are actually being rewritten:
http://my.proxy/a%2Fb -> http://my.host:8080/a/b
- or -
http://my.proxy/a%2Fb -> http://my.host:8080/a%252Fb
How can I get IIS\ARR\Rewrite to stop re-encoding my rewritten URLs?
Things I've tried:
A normal reverse-proxy (rewrites the URL as http://my.host:8080/a/b):
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url="(.*)" ignoreCase="true" />
<action type="Rewrite" url="http://my.host:8080/{R:1}" />
</rule>
Using the UNENCODED_URL server variable (rewrites the URL as http://my.host:8080/a%252Fb):
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url="(.*)" ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="{UNENCODED_URL}" pattern="/(.*)" />
</conditions>
<action type="Rewrite" url="http://my.host:8080/{C:1}" />
</rule>
Just entering the URL in straight (as a test - also rewrites the URL as http://my.host:8080/a%252Fb):
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url="(.*)" ignoreCase="false" />
<action type="Rewrite" url="http://my.host:8080/a%2Fb" />
</rule>
All the ideas in Scott Hanselman's excellent "Experiments in Wackiness: Allowing percents, angle-brackets, and other naughty things in the ASP.NET/IIS Request URL"
<httpRuntime requestValidationMode="2.0" requestPathInvalidCharacters="*,:,&,\" relaxedUrlToFileSystemMapping="true" />
<security>
<requestFiltering allowDoubleEscaping="true" />
</security>'
Note: I ran into this behavior when my IIS reverse proxy ran afoul of Jenkins' built-in reverse proxy checking system which attempts to do an HTTP redirect to a URL of this form.
Joseph, that is a great summary of all the ways I've tried to resolve the exact same issue, having IIS with SSL routing traffic to my Gerrit instance. When I found your post I hoped that maybe someone figured out a magic way to configure it but I guess it's not possible. I have tried one more thing, I've written a custom rewrite provider for IIS so that I can undecode the percent signs before routing is done, but then I realized that the encoding takes place later and this is pointless (I forgot about your step nr 3 that shows it very good).
I couldn't however get rid of IIS like out did, so I have figured a workaround. I have implemented a simple service that acts as additional proxy between IIS and Gerrit. When you configure IIS like in step 2, requests that are forwarded will get %25 in place of percent characters in the urls. Instead of reaching Gerrit, IIS forwards the requests to the proxy service. The service changes all occurrences of %25 to % (decodes percents) and forwards it to Gerrit. Nothing needs to be done with the response. For those who want to go this way you can start from my simple implementation of the proxy in C#:
https://gist.github.com/gralin/b5edfd908a41fc7268a7757698af1e66
I was able to fix this issue using the second approach and setting useOriginalURLEncoding="false":
<rules useOriginalURLEncoding="false">
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url="(.*)" ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="{UNENCODED_URL}" pattern="/(.*)" />
</conditions>
<action type="Rewrite" url="http://my.host:8080/{C:1}" />
</rule>
</rules>
See also the official blog post for background information. The wording of useOriginalURLEncoding is a bit unfortunate.
I have thought using proxy with url contains % symbol has the problem, but after that i have found out it wasn't. The issue that the proxy URL too long.
I use datatable with option server-side: true and type: GET. Then when loading content from server with the proxy url too long, there is a problem. I have improve the size of url request and the issue has been fixed.
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxQueryString="4000" maxUrl="2000" />
</requestFiltering>
</security>
<rewrite>...</rewrite>
...
</system.webServer>
But keep in mind that allowing long query string and url is a security risk, more over, it’s a bad design.

Resources