IIS Url Rewrite overwriting external urls - iis

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"

Related

Can an Azure App Service redirect www to non-www?

Is it possible to redirect www to non-www at the azure app service level?
I need this at the app service level and not in the configuration file of my app. I have been able to get http to https working under the tls/ssl blade, but I don't see a way to redirect for www.
Do I need another resource like front door or application manager? I'd like to handle it in the app service itself.
My app server is running a docker container that is using an nginx server. I'm not an expert with nginx, and haven't been able to get the redirect to work in the nginx configuration. Plus, I'd like to set this up in my bicep file.
To rewrite a URL, you need to create a web.config file in your wwwroot folder and put the necessary entries in there, if you don't already have a web.config file for your site.
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Redirect requests to default azure websites domain" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAny">
<add input="{HTTP_HOST}" pattern="^yoursite\.azurewebsites\.net$" />
</conditions>
<action type="Redirect" url="http://yoursite.com/{R:0}" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Original answer: https://learn.microsoft.com/en-us/answers/questions/193377/how-to-redirect-in-app-service

How to force IIS to use a specific value for the http host header during a rewrite

I'm trying to create a rewrite rule that configures a web site to be used as a reverse proxy, but I'm having some issues setting the host http header to a predefined value different from the domain used in the rewrite (the objective is to use IIS as a reverse proxy for forwarding urls to sendgrid with a custom host value).
In order to illustrate the problem, I've created 2 web sites named url and sendgrid with the bindings url.com and sendgrid.net (I've added custom entries for these names on the hosts file so that the names can be resolved). Now, I need to redirect all requests received on the url web site to the sendgrid website, making sure that the request to the sendgrid web site sets the host http header to url.com. I've started by adding a rewrite rule to the url web site that looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{CACHE_URL}" pattern="^(https?)://" />
</conditions>
<action type="Rewrite" url="http://sendgrid.net/{R:1}" logRewrittenUrl="true" />
<serverVariables>
<set name="HTTP_HOST" value="url.madeira.gov.pt" />
</serverVariables>
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
The applicationhost.config file has also been updated so that the HTTP_HOST can be changed:
<location path="url">
<system.webServer>
<rewrite>
<allowedServerVariables>
<add name="HTTP_HOST" />
</allowedServerVariables>
</rewrite>
</system.webServer>
</location>
In order to see what's going on, I've activated Failed Request Tracing and I've noticed that the host header file defined through the previous rule is not applied. I can see that the rule is processed and that the HTTP_HOST header is processed (SET_SERVER_VARIABLE), but when the request is rewritten, it will always set the http host to sendgrid.net (instead of setting it to url.com):
So, is there a way to force the use of a specific value to the host header when a IIS web site is configured to be used as a reverse proxy?
try to set the preserveHostHeader to true by following the below steps:
1)open IIS manager, select the server node.
2)double clic configuration manager.
3)from the section drop down select system.webServer/proxy
4)set preserveHostHeader to true
Note: if you are trying to change the request header it is not possible by using iis URL rewrite rule.

Nest JS Web Socket IIS Web.config setting

I want to know if anybody here can help. I have using Nest.js for my program and I have added some web socket code into my program for some new feature. However, when I deploy to the server and there are a problem to the IIS Setting.
Now I use URL rewrite for my http server. My HTTP server run on port 8200 in localhost. My web socket port is 8085. What I have tested is that I can call it in local using ws://localhost:8085/socket.io/?EIO=3&transport=websocket and also ws://192.168.X.X:8085/socket.io/?EIO=3&transport=websocket in internal network. However, I cannot call by ws://myurl.com/socket.io/?EIO=3&transport=websocket. The URL is binding with a IIS server. Below is my IIS server web.config. Is it because we socket cannot called by url? or is my web.config have something wrong? Can anybody help me?
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="WebSocketsReverseProxy" enabled="true" stopProcessing="true">
<match url="ws://(.*)"/>
<action type="Rewrite" url="ws://localhost:8085/{R:1}"/>
</rule>
<rule name="HttpsReverseProxy" stopProcessing="true">
<match url="(.*)"/>
<conditions>
<add input="{CACHE_URL}" pattern="^(https?)://"/>
</conditions>
<action type="Rewrite" url="http://localhost:8200/{R:1}"/>
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
remove ws:// from the first rule. iis match rule only matches folder or file but does not match the domain name. if you want to match the domain use condition server variable {HTTP_HOST}.

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 rewrite to local apps - fails with 404

I want to use IIS8 to route traffic from ports 80/443 to two applications running on the same server - one sitting on port 8080 (node.js app, running as a separate service), another on port 8090 (a .NET application, running on the same IIS, handling api calls).
I have setup an app on port 80, with the following web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="rewrite api to backend calls" stopProcessing="true">
<match url="^api/(.+)$"/>
<action type="Rewrite" url="http://127.0.0.1:8080/{R:1}"/>
</rule>
<rule name="rewrite everything else to frontend" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://127.0.0.1:8090/{R:1}"/>
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Unfortunately this approach doesn't work - whatever resource I try to query, I get 404 error.
In the FREB logs, requests are properly translated from OldUrl, to the NewUrl, nothing is found in cache and then the following is mentioned in logs as MODULE_SET_RESPONSE_ERROR_STATUS
ModuleName="IIS Web Core", Notification="MAP_REQUEST_HANDLER", HttpStatus="404", HttpReason="Not Found", HttpSubStatus="4", ErrorCode="The filename, directory name, or volume label syntax is incorrect.
(0x8007007b)", ConfigExceptionInfo=""
Proxy in Application Request Routing had to be enabled as per the IIS Rewrite not working (but redirection does) topic. Issue solved :)

Resources