IIS reverse proxy outbound rule doesn't work - iis

I have a web site under IIS 10.0 v1809. A specific link https://domain.name/report/ should be proxied to the local service http://localhost:7577/dashboard/. So I need to change the word dashboard to report in the server answer. To do this I set up ReverseProxy rule:
<rule name="MyReverseProxy" enabled="true" stopProcessing="true">
<match url="report(/)?(.*)" />
<action type="Rewrite" url="http://localhost:7577/dashboard/{R:2}" appendQueryString="true" />
</rule>
And the OutBound rule:
<outboundRules>
<rule name="MyReverseProxy" enabled="true" stopProcessing="false">
<match filterByTags="None" pattern="dashboard(/)?(.*)" />
<action type="Rewrite" value="report/{R:2}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
but for some reason, the outbound rule does not work for me. I get a 404 error and https://domain.name/dashboard/ appears in the browser's address bar.
What am I doing wrong? My pattern test works correctly, but why does the browser switch to dashboard?

Related

Keycloak behind IIS Reverse Proxy

I just cant get my reverse proxy to work properly and I hope that someone can help me with that.
A few Informations:
1 VM Windows Server 2019,IIS 10 (with ARR and URL Rewrite Module),"keycloak" App under the "Default Website", proxy-address-forwarding="true" were added in the standalone.xml
keycloak is locally available at "localhost:8080". The default website is available from intern network (Port 80 is open, 8080 is closed). I want to use the IIS as a reverse proxy for keycloak. It should look like the following URL.
Request: "http://server_fqdn/keycloak" -> IIS Reverse Proxy -> localhost:8080
At first I tried it without "/keycloak" and it worked perfectly. After I added "/keycloak" it just shows 404 Errors. I saw that it tries to open "http://server_fqdn/auth" instead of "http://server_fqdn/keycloak/auth". If I enter "/keycloak/auth" manually it works. My first thought was to just write another Blank Inbound Rule which redirects "http://server_fqdn/auth" to "http://server_fqdn/keycloak/auth". It works, but now there is another problem. If i want to enter the admin console I get an error which says "Invalid parameter: redirect_uri".
It stops at the following URL (not complete, but the necessary part is there)
http://server_fqdn/keycloak/auth/realms/master/protocol/openid-connect/auth?client_id=security-admin-console&redirect_uri=http%3A%2F%2Fserver_fqdn%2Fkeycloak%2Fauth%2Fadmin%2Fmaster%2Fconsole%2F&state=.....
If i remove %2Fkeycloak after "redirect_uri" it works and i get the keycloak login screen. Maybe someone can help me here.
Inbound Reverse Proxy Rule:
<rule name="ReverseProxyInboundRule1" enabled="true" stopProcessing="true">
<match url="^keycloak/(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Rewrite" url="http://localhost:8080/{R:1}" />
<serverVariables>
</serverVariables>
</rule>
Outbound Reverse Proxy Rule:
<outboundRules>
<clear />
<rule name="ReverseProxyOutboundRule1" preCondition="ResponseIsHtml1" enabled="true">
<match filterByTags="A, Area, Base, Form, Head, IFrame, Img, Input, Link, Script" pattern="^http://localhost:8080/(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="true">
</conditions>
<action type="Rewrite" value="http://server_fqdn/keycloak/{R:1}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
Inbound Reverse Proxy Rule:
<rule name="keycloak" enabled="true" stopProcessing="true">
<match url="^auth/(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
<action type="Redirect" url="http://server_fqdn/keycloak/{R:0}" redirectType="Permanent" />
</rule>

IIS Rewrite rule, url modify himself

I have write a rewrite rule to redirect an incoming request to the correct server.
Here my web.config :
<rules>
<rule name="ToMonceau">
<match url="test/(.*)" />
<action type="Rewrite" url="http://10.5.5.83/{R:1}" />
<serverVariables>
<set name="HTTP_X_ORIGINAL_ACCEPT_ENCODING" value="{HTTP_ACCEPT_ENCODING}" />
<set name="HTTP_ACCEPT_ENCODING" value="" />
</serverVariables>
</rule>
</rules>
<outboundRules>
<rule name="AddPrefix" preCondition="IsText" enabled="true">
<match filterByTags="A, Img, Link, Script" pattern="(http://10.5.5.83/mantis/)?(/mantis/)?(.*)" />
<conditions>
<add input="{URL}" pattern="(test/mantis)/(.*)" />
</conditions>
<action type="Rewrite" value="./{R:3}" />
</rule>
<rule name="RestoreAcceptEncofing" preCondition="NeedsRestoringAcceptEncoding">
<match serverVariable="HTTP_ACCEPT_ENCODING" pattern="^(.*)" />
<action type="Rewrite" value="{HTTP_X_ORIGINAL_ACCEPT_ENCODING}" />
</rule>
<preConditions>
<preCondition name="IsText">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/(.+)" />
</preCondition>
<preCondition name="NeedsRestoringAcceptEncoding">
<add input="{HTTP_X_ORIGINAL_ACCEPT_ENCODING}" pattern=".*" />
</preCondition>
</preConditions>
</outboundRules>
My problem when I go to http://localhost/test/mantis (my server hosts a mantis here), the url change automatically to http://localhost/mantis/, I have to put again the "test/" and it change to http://localhost/mantis/login_page.php. I reput again "test/" and this time the login's page of mantis shown.
The problem continue when I try to log in, the url changes continously by removing the "test/" part.
If I go directly to my mantis without the redirect (http://10.5.5.83/mantis) everything is working like a charm.
What am I missing in my rule to do it correctly ?
I take the exemple here with mantis but I have the same problem on every sites host by different server.
Thanks in advance and sorry if my english is not perfect.
Go to IIS manager and click on URL rewrite:
Keep pattern .*
Action type should be Rewrite
Rewrite URL: http://yourdesiredurl/{R:0}

Reverse proxy with IIS

I'm trying to integrate ASP.net and Node.js on a server.
My expectation is here.
client ----> IIS Server ----> ASP.NET (except /api/. localhost:80)
(test.foo.com) |---> Node.js (starting with /api/. localhost:4000)
Node app is executed as a windows service, and serve localhost:4000/api/ in locally. And should be accessed with http://test.foo.com/api/signin
All request excepting /api/ should be served normal IIS asp.net. (ex. http://test.foo.com/index.aspx)
My trial:
- Installed urlrewrite module and application request routing cache module.
- Added rewriting rule as below
pattern: /api/(.*)
URL rewrite : http://localhost:4000/api/{R:1}
My result:
- http://test.foo.com/api/signin returned as 503 Service Unavaile
Question:
- Using URLrewrite is the right solution for my case?
Append
I tried to with 127.0.0.1 instead localhost with below web.config setting.
That result was same "503".
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url="/api/(.*)" />
<action type="Rewrite" url="http://127.0.0.1:4000/api/{R:1}" />
</rule>
</rules>
<outboundRules>
<rule name="ReverseProxyOutboundRule1" preCondition="ResponseIsHtml1">
<match filterByTags="A, Form, Img" pattern="^http(s)?://127.0.0.1/(.*)" />
<action type="Rewrite" value="http{R:1}://127.0.0.1:4000/{R:2}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
Append again
Instead loop adapter, change to ipv4 address. And tried to access anther PC. But result was same.
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://192.168.123.12:4000/api/{R:1}" />
</rule>
</rules>
<outboundRules>
<rule name="ReverseProxyOutboundRule1" preCondition="ResponseIsHtml1">
<match filterByTags="A, Form, Img" pattern="^http(s)?://192.168.123.12:4000/api/(.*)" />
<action type="Rewrite" value="http{R:1}://192.168.123.12/{R:2}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>

IIS Reverse Proxy Apply outbound rule on specific path

I have the following inbound and outbound rules defined to get my reverse proxy working.
<rewrite>
<rules>
<rule name="Route the requests for backend app" stopProcessing="true">
<match url="^foldera/folderb/(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="www.site1.com" />
</conditions>
<action type="Rewrite" url="http://www.site2.com/{R:1}" />
<serverVariables>
<set name="HTTP_ACCEPT_ENCODING" value="" />
</serverVariables>
</rule>
</rules>
<outboundRules>
<rule name="RewriteRelativePaths" preCondition="ResponseIsHtml" enabled="true" stopProcessing="false">
<match filterByTags="A, Area, Base, Form, Frame, Head, IFrame, Img, Input, Link, Script" pattern="^/(.*)" />
<action type="Rewrite" value="/foldera/folderb/{R:1}" />
<conditions>
<add input="{URL}" pattern="^/foldera/folderb/.*" />
</conditions>
</rule>
<preConditions>
<preCondition name="ResponseIsHtml">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
Now, the site "http://www.site2.com/" is correclty loaded in "http://www.site1.com/foldera/folderb/" and the outbound rule is making sure that every resource from site2 is rewritten to http://www.site1.com/foldera/folderb/{resourcefromsite1}
Unfortunately, the outbound rule is also crashing the rest of my site. Probably because he's trying to rewrite every native resource to this same "http://www.site1.com/foldera/folderb/" folderstructure.
How can I make the outbound rule only to respond to resources that are requested/loaded through path http://www.site1.com/foldera/folderb/ and for instance not through http://www.site1.com/foldera
Cheers
Jeroen
You were very close to solution. To solve this you must add {URL} as input inside your preCondition. Your rewrite rules should look like this finally:
<rewrite>
<rules>
<rule name="Route the requests for backend app" stopProcessing="true">
<match url="^foldera/folderb/(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="www.site1.com" />
</conditions>
<action type="Rewrite" url="http://www.site2.com/{R:1}" />
<serverVariables>
<set name="HTTP_ACCEPT_ENCODING" value="" />
</serverVariables>
</rule>
</rules>
<outboundRules>
<rule name="RewriteRelativePaths" preCondition="ResponseIsHtml" enabled="true" stopProcessing="false">
<match filterByTags="A, Area, Base, Form, Frame, Head, IFrame, Img, Input, Link, Script" pattern="^/(.*)" />
<action type="Rewrite" value="/foldera/folderb/{R:1}" />
<!-- Removed condition from here -->
</rule>
<preConditions>
<preCondition name="ResponseIsHtml">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
<add input="{URL}" pattern="^/foldera/folderb/.*" /> <!-- Added your condition here -->
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
This way Outbound Rule will be applied only when Response is HTML and current URL got specified pattern.

IIS reverse proxy to nodejs app via https problem

I am building a nodejs api that is hosted by iis. It works perfectly over (using port 5000) http. However, when trying to use the https connection if fails(ssl are installed). I either get a connection failed message or a refused message.
<handlers accessPolicy="Read, Execute, Script" />
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://localhost:5000/{R:1}" />
<conditions>
<add input="{HTTPS}" pattern="off" />
</conditions>
</rule>
<rule name="ReverseProxyInboundRule2" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://api.mysite.com:5000/{R:1}" />
</rule>
</rules>
<outboundRules>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
Seems like IIS is refusing the connection. any help is appreciated.
According to your url rewrite rule, I found all your https request will match the ReverseProxyInboundRule2 and rewrite to "http://api.mysite.com:5000". I suggest you could firstly check you could access the "http://api.mysite.com:5000".
I guess there is something wrong with this url. It seems you doesn't bind the domain in the IIS binding configuration.
I suggest you could try to open the IIS web application binding to add the domain for the http://api.mysite.com.

Resources