IIS reverse proxy to virtual private ip - iis

I am trying to use IIS 7.5 to Reverse Proxy incoming requests on a specific port to a docker container bound to a port on the private ip of a VirtualBox vm so that my application can be accessible to external hosts on my LAN.
Please assume the following:
I am running docker with the b2d image inside Windows 7
docker machine receives a virtual private ip such as 192.168.99.100 which is only resolvable to the host machine.
I have a container built on the rabbitmq:3-management image and the management portal is bound to port 32771 on the default gateway of my virtual machine
I want requests across the network to http://mymachine:32771 to reverse proxy through IIS 7.5 for port 32771 from my virtual machine and show the RabbitMQ management portal that displays privately for me if I navigate to http:192.168.99.100:32771
Can anyone show me examples of the inbound and outbound rewrite rules that I would need to accomplish this?
This is what I have tried so far based on the sparse samples I've found on IIS reverse proxying, and I placed this inside a web.config at my inetpub/wwwroot but the rules are not applying (even after an iisreset)
Note that in my config below, I was looking to RP any requests containing "rabbit/" -rather than a specific port- but it is not proxying either.
Edit: [Note] I have also tried http://rabbit.(my-machine-name?)(/+?.*)?$|(.*)/rabbit(/+?.*)?$ to capture anything coming to my machine on either the rabbit. sub or the /rabbit path. I validated the capture rule but the RP still does not proxy.
<rewrite>
<rules>
<rule name="RP requests for Rabbit to virtual private IP" stopProcessing="false">
<match url="(.*)rabbit/(.*)" />
<conditions>
<add input="{CACHE_URL}" pattern="^(https?)://" />
</conditions>
<action type="Rewrite" url="{C:1}://192.168.99.100:32771/{R:1}" />
<serverVariables>
<set name="HTTP_ACCEPT_ENCODING" value="" />
</serverVariables>
</rule>
</rules>
<outboundRules>
<rule name="RP requests from Rabbit to outbound" preCondition="ResponseIsHtml">
<match filterByTags="A, Area, Base, Form, Frame, Head, IFrame, Img, Input, Link, Script"
pattern="^http(s)?://192.168.99.100:32771/(.*)" />
<action type="Rewrite" value="/rabbit/{R:1}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
In the past, I would just stand up Apache and bring in mod_proxy for its simplicity and documentation, but I would prefer to know how to implement this in IIS.

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.

IIS Reverse Proxy for specific URL path - URL Rewrite Module Error

I have one windows service which is running some application with REST endpoint on localhost:5001/api/...
So I installed IIS 10 with rewrite module to create reverse proxy for HTTPS to that service. That worked great.
Now I want to use the same IIS site for hosting a website, which should consume that service on same url.
So I tried to change the pattern of my iis rewrite url to 'api/(.*)' so it should just proxy the /api requests. Testing the pattern is exactly what I want to: Browsing server.domain/api/function matches and the rewrite is done and server.domain is not rewritten.
But now browsing server.domain will often return 'HTTP Error 500.52 - URL Rewrite Module Error'.
Sometimes loading the page works great. But after reload I will get that error again.
My web.config:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<outboundRules>
<rule name="ReverseProxyOutboundRule1" preCondition="ResponseIsHtml1" enabled="true">
<match filterByTags="A, Form, Img" pattern="^http(s)?://localhost:5001/(.*)" />
<action type="Rewrite" value="https://server.domain/{R:2}" />
</rule>
<rule name="ReverseProxyOutboundRule2" preCondition="ResponseIsHtml1" enabled="true">
<match filterByTags="A, Form, Img" pattern="^http(s)?://localhost:5001/(.*)" />
<action type="Rewrite" value="https://server.domain/{R:2}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
<rules>
<rule name="ReverseProxyInboundRule1" enabled="true" stopProcessing="true">
<match url="api/(.*)" />
<action type="Rewrite" url="http://localhost:5001/{R:0}" logRewrittenUrl="true" />
</rule>
</rules>
</rewrite>
<security>
<requestFiltering allowDoubleEscaping="true" />
</security>
<httpErrors errorMode="Detailed" />
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="POST, GET, OPTIONS, DELETE, PUT" />
<add name="Access-Control-Max-Age" value="1000" />
<add name="Access-Control-Allow-Headers" value="x-requested-with, Content-Type, origin, authorization, accept, client-security-token" />
</customHeaders>
</httpProtocol>
<urlCompression doDynamicCompression="false" />
</system.webServer>
</configuration>
I have no idea why there are two outboundRules. IIS created them automatically when I decided to create reverse proxy rules.
If I disable static content compression, all will work without problems.
Dynamic compression module is not installed.
So I have multiple questions:
- why do I get the "Rewrite URL" error for pages which should not be rewritten and the rewritten ones will work without any problem
- why static compression creates rewrite url errors
- how should I configure my IIS to do compression and work with rewriting (I checked the module order and the static compression module is above the rewrite module).
Best,
Robin
Did you create reverse proxy rule by using URL rewrite rule template? If so, you might enable outbound rules. These outbound rules are mainly used when a client can't access source file behind DMZ server. If you client are able to access the domain on backend server, then you don't need these outbound rule.
The reason for IIS return 500.52 error is IIS can't apply outbound rule for a encoded response body from backend server.
So you have to either disable httpcompression or rewrite the incoming accept-encoding header.
I'm afraid it is unavailable to make httpcompression and outbound rule work side by side because rewrite module can't rewrite a compressed entity.
https://learn.microsoft.com/zh-cn/archive/blogs/friis/iis-with-url-rewrite-as-a-reverse-proxy-part-2-dealing-with-500-52-status-codes

HTTP to HTTPS on domain hosted in VPS using IIS

I have a domain which has the DNS setting pointing to a VPS.
The VPS has an IIS 10 instance which hosts the simple website using html using bootstrap.
I installed an SSL certificate and added bindings for the https part.
I am able to browse the domain on http and https.
I added the following rule to the web.config:
<system.webServer>
<rewrite>
<rules>
<rule name="HTTP to HTTPS redirect" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect" redirectType="Permanent" url="https://{HTTP_HOST}/{R:1}" />
</rule>
</rules>
</rewrite>
</system.webServer>
However this does not seem to help. I am still able to browse on http.
I tried the following:
Tried installing URL Rewrite but it looks like Windows Server 2016 and IIS 10 does not allow the installation
Tried enabling Requires SSL option.
This shows the website in http without images but with text
The website is properly displayed in https
What am I missing here?
I was installing the wrong URL rewrite.
This article helped me fix the problem with the right links.
Automatic IIS redirect http to https on Windows Server 2016: https://gridscale.io/en/community/tutorials/iis-redirect-http-to-https-windows/

MVC Application using ADFS 3.0 and ARR URL Rewrite getting incorrectly redirected after authentication

I have pretty much the same problem as mentioned in this question
SSO ADFS redirection issue with reverse proxy with ARR. However, I have tried the solution without success. The 302 from ADFS still goes to the private site instead of public.
I have also tried using wreply to explicitly define the public endpoint. I checked using browser Debug Tool and I can see that the ADFS request has the correct wreply value, however, redirection from ADFS is ignoring this.
I have verified the RP identifier in ADFS and it is correct.
Everything works fine in local environment when I host both the proxy and application in a single server and use the same ADFS endpoint for SSO.
The redirection from ADFS also works fine when I use idpinitiated sigon to login to the application.
Where could I be going wrong?
ARR changes the base URL after authentication happens. You need to restore the ADFS Base URL. I made it working using below ARR Rules.
You can use ADFS Rule mentioned in below rule set
<rewrite>
<rules>
<clear />
<rule name="ApplicationRule" stopProcessing="true">
<match url="^dnApplication/?(.*)" />
<action type="Rewrite" url="https://application.cloud.azurewebsites.net/dnApplication/{R:1}" logRewrittenUrl="true" appendQueryString="true" />
</rule>
<rule name="AdfsRule" stopProcessing="true">
<match url="^.*adfs/?(.*)" />
<action type="Redirect" url="https://gfs.private.companyName.com/adfs/{R:1}" logRewrittenUrl="true" />
</rule>
</rules>
<outboundRules>
<rule name="RedirectToHomeDNS" preCondition="3xx Redirect">
<match serverVariable="RESPONSE_LOCATION" pattern="^https://application-dv1.azurewebsites.net/" />
<action type="Rewrite" value="{HTTP_URL}" />
</rule>
<preConditions>
<preCondition name="3xx Redirect">
<add input="{RESPONSE_STATUS}" pattern="3[0-9][0-9]" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>

Do I need anything besides code written in web.config to redirect website hosted on azure to https

I have a website that I host on azure. I recently bought an SSL and configured it. Now users can visit my site by typing in either http://example.com or https://example.com.
What I want is for users who type in the former to be automatically redirected to the latter while also keeping anything after the .com
So if a user types in http://example.com/about they will be redirected instead to https://example.com/about.
After some reading, I've come across this code that seems to do what I want
<system.webServer>
<rewrite>
<rules>
<rule name=”Redirect to https”>
<match url=”(.*)”/>
<conditions>
<add input=”{HTTPS}” pattern=”Off”/>
<add input=”{REQUEST_METHOD}” pattern=”^get$|^head$” />
</conditions>
<action type=”Redirect” url=”https://{HTTP_HOST}/{R:1}”/>
</rule>
</rules>
</rewrite>
</system.webServer>
But before I add this to my web.config file I have a few questions.
What is the IIS url rewrite module? IIS Rewrite and is it required to be installed on my azure hosted websites before I upload my new web.config file.
How can I also include removing www from my URL when a user enters it. For example if a user types in www.example.com they should be redirected to https://example.com instead. The reason that I want this is because in my google search console I've told google to display URLs as example.com rather then www.example.com
and finally, will this code do what I'm looking for? Is there a more professional way to achieve this? What are the benefits. I should note that my sites are asp .net web forms. I know MVC has routing options but that is not an option for me.
Edit : I don't think How to force HTTPS using a web.config file solves my issue because I don't even know if I can install the URL Rewrite module since I am not hosting IIS myself. Does azure give you access to the IIS settings? I am unfamiliar with azure details.
The Microsoft URL Rewrite Module for IIS enables IIS administrators to create powerful customized rules to map request URLs to friendly URLs that are easier for users to remember and easier for search engines to find.
This module is pre-installed for Azure Web App, as shown when inspect the applicationHost.config of the Azure Web App in Kudu.
Hence, you do not need to worry about the availability of the module for Azure Web App.
The URL Rewrite configuration to enforce HTTPS redirection for Azure web app is the simplest way to achieve what you intend. Your above configuration will apply
only if the request method is either HTTP GET or HTTP HEAD. The below configuration will not have such limitation.
<system.webServer>
<rewrite>
<rules>
<rule name="Force HTTPS Redirection" enabled="true" stopProcessing="true">
<match url="^$" ignoreCase="false"/>
<conditions>
<add input="{HTTPS}" pattern="^OFF$"/>
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/" redirectType="Permanent"/>
</rule>
</rules>
</rewrite>
</system.webServer>
I would add one last thing. Assuming you are running on Azure Web Apps, they have various probes to your site for warm up and initialization. You probably don't want these probes to also be redirected, otherwise, you may have some issues when you restart or use Azure's swaps feature for stuff like blue/green deployments. These probes would then be return with a 301/302 rather than actually hitting your site (and Azure doesn't actually follow the redirect)
More examples https://github.com/projectkudu/kudu/wiki/Xdt-transform-samples
<rule name="Redirect to non-WWW" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" pattern="www.example.com$" />
<add input="{HTTP_USER_AGENT}" pattern="Initialization" negate="true" /> <!-- IIS Application Initialization Warmup -->
<add input="{HTTP_USER_AGENT}" pattern="SiteWarmup" negate="true" /> <!-- Azure WebApps Warmup Request -->
<add input="{HTTP_USER_AGENT}" pattern="AlwaysOn" negate="true" /> <!-- Azure WebApps AlwaysOn Probes -->
</conditions>
<action type="Redirect" redirectType="Permanent" url="https://example.com/{R:1}" />
</rule>
<!-- Redirect to HTTPS Version -->
<rule name="HTTP to HTTPS redirect" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
<add input="{HTTP_USER_AGENT}" pattern="Initialization" negate="true" />
<add input="{HTTP_USER_AGENT}" pattern="SiteWarmup" negate="true" />
<add input="{HTTP_USER_AGENT}" pattern="AlwaysOn" negate="true" />
</conditions>
<action type="Redirect" redirectType="Permanent" url="https://{HTTP_HOST}/{R:1}" />
</rule>

Resources