Change Host Header with IIS URLRewrite - iis

I have requests coming to my webserver at
http://www.example.com/blog
I want to Rewrite that to another server listening on
http://blog.example.com
Here is my rewrite rule:
<rule name="blogredirect1" stopProcessing="true">
<match url="^blog(.*)" />
<action type="Rewrite" url="http://blog.example.com{R:1}" />
</rule>
What ends up happening is the rewrite sends the request to the second servers IP at blog.mysite.com but the request header's host is still www.mysite.com.
How do I make sure that the redirected request HOST is set to blog.mysite.com (which is set in the redirect rule)

May I know how did you check the HOST header?
It is recommended to check {HTTP_HOST} variable instead of view the HTTP header directly. Because if you view the request header, you will always see www.mysite.com.
You could fetch {HTTP_HOST} request variable from backend server blog.mysite.com.
However,If you means page in blog.mysite.com also displayed {HTTP_HOST} as www.mysite.com.Then please check whether you have set system.webServer/proxy/preserveHostHeader to true?
By the way, IIS support to rewrite HTTP_HOST manually, you could modify your rule like this:
<rule name="blogredirect1" stopProcessing="true">
<match url="^blog(.*)" />
<action type="Rewrite" url="http://blog.example.com{R:1}" />
<serverVariables>
<set name="HTTP_HOST" value="blog.example.com" />
</serverVariables>
</rule>
Please remember to Allow Server Variable{HTTP_HOST} in URL rewrite.
https://learn.microsoft.com/en-us/iis/extensions/url-rewrite-module/setting-http-request-headers-and-iis-server-variables
You could also set this in applicationhost.config <location path="sitename"> section.
<location path="Default Web Site">
<system.webServer>
<rewrite>
<allowedServerVariables>
<add name="HTTP_HOST" />
</allowedServerVariables>
</rewrite>
</system.webServer>
</location>

Related

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.

How to set IIS url rewrite for http header

This is an inbound rule in my iis web site.
<rewrite>
<rules>
<rule name="ToBackEnd">
<match url="^v1/api/(.*)" />
<action type="Rewrite" url="https://172.16.8.78/v1/api/{R:1}" />
</rule>
</rules>
</rewrite>
I want to add a header (Access-Control-Allow-Origin) to the response for oly this request. There are some solutions tags in . But I do not want this? How can I set in rule?
URL rewrite outbound rule can help override the Access-Control-Allow-Origin from your application for specific URL but it can't add response header. So if you can get the expected header by rewriting your existingAccess-Control-Allow-Origin. Then outbound rule can be involved.
<outboundRules>
<rule name="outbound rule" enabled="false">
<match serverVariable="Access-Control-Allow-Origin" pattern=".*" />
<action type="Rewrite" value="*" />
</rule>
</outboundRules>
If you only need to add a header only for specific page. You can use CORS module with <location> tag
https://www.iis.net/downloads/microsoft/iis-cors-module
If you need to add another header for wildcard URL like v1/api/*. Then custom httpmodule in integrated pipeline would be a choice.

IIS Reverse proxy/Global URL Rewrite for "/api/" folder for all sites

I would like to reverse proxy any requests to an IIS instance for any sites where the request is in the '/api/' folder. I set up a server farm and have the reverse proxy working for everything using the '*' wildcard, but when I want to limit the scope to a RegEx it will not rewrite/proxy to the backend server. The steps I took at the IIS INSTANCE level:
Set up a web farm - only one server in it, machine2
Set up a rewrite for '*'
Tested against 'http://machine1/site1/api/api1' - it was successfully routed to machine2/site1/api/api1
Changed inbound rule from Wildcard to Regular Expressions
Changed Pattern to '.(/./api/.*)' (without the single quotes)
Tested against 'http://sarjhennew10vm/site1/api/api1'
Request was not routed to machine 2.
Below is a snippet from my applicationHost.config [the root of IIS].
<rewrite>
<globalRules>
<rule name="ARR_Farm1_loadbalance" patternSyntax="ECMAScript" stopProcessing="true">
<match url=".*(\/.*\/api\/.*)" />
<action type="Rewrite" url="http://Farm1/{R:1}" />
</rule>
</globalRules>
</rewrite>
<proxy enabled="true" />
Is it possible to to a global URL re-write to the server farm for any site on the instance for specific folders?
Edit: It was answered below - I am including a picture in case others run into this. The test pattern isn't clear to me - and counters documentation found here.
Your pattern is incorrect, you can try below code, and change the rewrite url to https://Farm1/{R: 0}
<rule name="ARR_Farm1_loadbalance" patternSyntax="ECMAScript" stopProcessing="true">
<match url=".*(\/api\/.*)" />
<action type="Rewrite" url="https://Farm1/{R:0}" />
</rule>

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?

IIS7 rewrite rule to another domain?

I have two domains: first.com and second.com.
In these domains there are two ASP.NET applications hosted in IIS 7.
Page in application http://first.com.index references a script which source is http://second.com/script.js
Script is doing some ajax POST but browser is blocking is because cross domain restriction.
Is it possible to create rule on IIS so a specific request for http://first.com/script.js
would be passed to http://second.com/script.js (executed there and returned to client) ?
I tried to add rewrite rule in first.com but it does not work:
<system.webServer>
<rewrite>
<rules>
<rule name="test" enabled="true" stopProcessing="false">
<match url=".*/script.js" />
<action type="Rewrite" url="http://second/script.js" appendQueryString="false" logRewrittenUrl="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
Action type="Redirect" works but it is not what I am looking for cause it returns 302 response to client. I want pass request directly to second application instead.

Resources