IIS ARR Proxy WebSockets over HTTP - iis

I have a reverse proxy in our DMZ that translates wss requests into https (at least from what I can see in the IIS logs). That is, JavaScript makes a websocket request to
wss://cname.domain.com
And the reverse proxy sends it to
https://theserver.local
IIS is running on "theserver" and has an https binding. ARR is installed and has the following rewrite rules configured:
<rule name="Rewrite ssl to non-ssl" stopProcessing="true">
<condition logicalGrouping="MatchAll" trackAllCaptures="true">
<add input="{CACHE_URL}" pattern="^(.+):// />
</condition>
<match url="the_app/(.*)" />
<action type="Rewrite" url="{MapProtocol:{C:1}}://theserver.local:8080/{R:1}" />
</rule>
<rewriteMap name="MapProtocol">
<add key="https" value="http" />
<add key="wss" value="ws" />
<rewriteMap>
This should route https and wss incoming requests to the path /the_app to http://theserver:8080/{path_and_query_string} and ws://theserver:8080/{path_and_query_string} respectively.
I also have the following rewrite set up (with the highest priority) to handle these wss requests that come in over https (since I can tell which they are based on the path):
<rule name="Rewrite https to ws" stopProcessing="true">
<match url="the_app/websockets/(%7B.+%7D)" />
<action type="Rewrite" url="ws://theserver:8080/websockets/{R:1}" />
</rule>
the rewrites works perfectly...however IIS throws a 502.2 error trying to route the websockets request from https to ws (Invalid Gateway). I have turned on failed request tracing and can't seem to find any more relevant information.
Can this be made to work?

You need to remove the "Rewrite https to ws" rule that changes the protocol to ws:. At the HTTP level, all Websocket calls start out life as an HTTP CONNECT request with an Upgrade header. You simply need to rewrite this request so that it is forwarded to the correct server as an HTTP request, which you are already doing in your "Rewrite ssl to non-ssl" rule.

Related

Accessing HTTP resource on HTTPS IIS Site with ARR Proxy Setting

I have a https site on IIS requesting resources from a http-only API server(Tomcat). There is no SSL certificate in the backend server. I try to avoid the browser error.
I encountered failure for requesting https/http resources from a https site.
I would like to know if there is any reverse proxy setting with ARR that can resolve this problem?
Is it necessary for the API server has HTTPS?
For instance,
The client application url : https://www.example.com/login
The requesting resource: https://www.example.com:8080/api/login
The working api: http://www.example.com:8080/api/login
I have tried adding the following,but not working
<rule name="web" stopProcessing="true">
<match url="^(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="^example.com$" />
</conditions>
<action type="Rewrite" url="http://example.com/{R:1}" />
</rule>
Thanks a lot.
ARR can solve this problem.
It is no necessary for api server has HTTPS.
Since I only have IIS and no tomcat server, I cannot completely restore your environment, but most of the settings are on the ARR server, so I can give you a reference.
I add two server into server farm and enable URL rewrite at server level. The URL rewrite rule can rewrite https://test2.com/b.html to http://server1IP/api/b.html or http://server2IP/api/b.html.
<rule name="ARR_farm_loadbalance" enabled="true" patternSyntax="Wildcard" stopProcessing="true">
<match url="*" />
<action type="Rewrite" url="http://farm/api/{R:0}" />
<conditions>
<add input="{HTTPS}" pattern="On" />
</conditions>
</rule>
It works very well.
If you want to use HTTPS in api server, change it in URL rewrite module.

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?

IIS Url Rewrite overwriting external urls

On my development machine, I am trying to configure IIS as a reverse proxy to forward requests coming in port 443 to a nodejs application running locally.
The requests are getting forwarded fine, but sometimes the the nodejs application tries to redirect the browser to an external site and the IIS url rewrite module change that also to point to the local server.
I am accessing the site using https://localhost/test
IIS reroutes the requests to the node app http://localhost:14819/test
The node app returns an http 302 with location header set to https://example.com/someroute
IIS transforms this to https://localhost/someroute
I want the external urls to be untouched by IIS. How to do this?
Here is my Web.config content
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<clear />
<rule name="ReverseProxyInboundRule1" patternSyntax="ECMAScript" stopProcessing="true">
<match url="^test(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTP_HOST}" pattern="^localhost" />
</conditions>
<action type="Rewrite" url="http://localhost:14819/test{R:1}" logRewrittenUrl="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
If you have any redirect coming back from the backend proxy and you do
not want to redirect the Location header coming ,You can do that by
unchecking "Reverse rewritehost in response headers" in Application
Request Routing
Select the server node in IIS manager
Go to Application Request routing Cache
Click on Server proxy Settings
UnCheck "Reverse rewritehost in response headers"

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.

Using URL Rewrite for Cross-Domain Http Requests

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

Resources