Using Azure Web Site as a reverse proxy

IIS has been supporting reverse proxy configuration since URL Rewrite and Application Request Routing modules were released a few years ago. It is possible to configure an IIS hosted web site to act as a reverse proxy and forward web request to other URL’s based on the incoming request URL path. This is described in details in Reverse Proxy with URL Rewrite v2 and Application Request Routing.

Not too many people know however that the same kind of configuration can be achieved with a web site hosted in Azure Web Sites. This blog post explains the configurations steps to enable that.

For example if I want to forward all the requests that come to https://ruslany.net/proxy/ to some other URL I’ll need to do two things:

  1. Enable proxy functionality in ARR
  2. Add a proxy rewrite rule

Any site hosted in Azure Web Sites has URL Rewrite and ARR enabled. However the proxy functionality is disabled by default in ARR. To enable that we will use the Azure Site Extension XDT transform which will modify the applicationHost.config file for our site and will enable proxy features.

This is the xdt transform file content to enable proxy:

<!--?xml version="1.0"?-->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <system.webServer>
    <proxy xdt:Transform="InsertIfMissing" enabled="true" preserveHostHeader="false" reverseRewriteHostInResponseHeaders="false" />
  </system.webServer>
</configuration>

Create a file named applicationHost.xdt and copy paste this code in there. Then upload this file into the “site” directory of your web site:

After that restart your site for the change to take effect.

Next add the following rewrite rule:

<configuration>
  <system.webserver>
    <rewrite>
      <rules>
        <rule name="Proxy" stopprocessing="true">
          <match url="^proxy/?(.*)" />
          <action type="Rewrite" url="http://www.iis.net/{R:1}"/>
        </rule>
      </rules>
    </rewrite>
  </system.webserver>
</configuration>

For the purposes of this example I configured proxy to forward all requests to http://www.iis.net/ but you can replace it with the target url of your site.  Now if I browse to http://ruslany.net/proxy/ the url rewrite rule will rewrite the request to a different url and then ARR will forward the request (notice the URL in the browser window. It is still my domain name which confirms that this not an HTTP redirect).

This functionality enables some interesting use cases. For example I could have two separate azure web sites ruslany-forum.azurewebsites.net and ruslany-blog.azurewebsites.net that can appear as if they are under same hostname but in different subfolders, e.g. http://ruslany.net/blog/ and http://ruslany.net/forum/.

Update:

Thanks to Bill Harts who discovered one additional important configuration step that is required if your site also uses ASP.NET MVC. When MVC is enabled on the web site used as a proxy then the MVC Router intercepts all the requests so they are not processed by ARR. So instead of request being forwarded to a destination server you get HTTP 404 – File Not Found error.

In order to fix this you’ll need to exclude the proxy route from the MVC routes by adding the following code to you MVC application:

routes.IgnoreRoute("proxy/{*pathInfo}");

53 thoughts on “Using Azure Web Site as a reverse proxy”

  1. Wow, this is super helpful.
    Before your post, there’s NO any official post mention about ARR on azure. Cannot believe it. Without ARR , even in memory cache will hit its bottleneck for session id sync and lookup. Now we feel easy to build up new website on Azure!

  2. Ruslan,

    Thanks for writing this. I’m not able to get it working yet. Questions:

    1. You wrote, “Next add the following rewrite rule:” but you didn’t say which file to add it to, is it web.config or applicationHost.xdt? And what directory it should be in?

    2. Is there some way to debug the rules? I’m seeing a cryptic error message in the eventlog.xml file (see below) but it doesn’t really tell me much. Can I enable more detailed logging on Azure that will tell me if the rules are being matched?

    Thanks,
    Bill

  3. Thanks again, Ruslan. I’m still not getting it to work.

    I have followed your instructions exactly, adding the http://www.iis.net rewrite rule to my web.config and enabling via applicationHost.xdt. When I submit an URL with /proxy on it, the URL Rewrite logic detects it, rewrites it correctly to http://www.iis.net, but when the ApplicationRequestRouting module runs it gives an ARR_WEBFARM_NOT_ROUTED message and changes the URL back to the original /proxy. This then leads to a NOT FOUND error. I have attached the ferb log below as well as my web.config.

    Any ideas why this isn’t working?

    Thanks in advance.
    Bill

  4. Further info:
    I verified that the transform is working by looking at Config/applicationHost.config. But it still does not route out. Thanks in advance for any ideas.
    Bill

    1. Hi Bill,
      Same issue we also facing in azure app.

      Any idea how to resolve that?

      This below we done,
      1.Added redirect rules in web.config
      2.Added proxy key transform in azure and checked transformed successful.

  5. Thanks, Ruslan. I sent the requested files to your gmail. Let me know if they don’t make it through the firewall.

    Bill

  6. You can use http://www.pinproxy.com
    It is the best online proxy found i have listed some features of it to help you.
    They have no ads.(this is why i like them)
    Supports almost every website.
    Best support for youtube,facebook,myspace and much more.
    They are on seperate private servers.not in a shared host so youget the best performance.
    and the best part is youcan use what ever of the subdomain and access there proxy.
    example: you can access the proxy from *.domain.com replace * with whatever word you like.

  7. Hi, Ruslan.

    I want to reverse proxy my azure website (abc.azurewebsites.net) to xyz.com:1234 domain.

    Basically, what I need is :

    1. My web app is on abc.azurewebsites.net
    2. API I am consuming is on xyz.com:1234/api
    3. I want to make my web app IE8 compatible
    4. But to avoid CORS. I want to implement something like Reverse Proxy so that all the requests made to my API will be through Proxy..

    Will this method help?

    Regards..

  8. Woops.. below are my web.config

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
    <system.webServer>
    <rewrite>
    <rules>
    <rule name="ReverseProxyInboundRule1" stopProcessing="true">
    <match url="*" />
    <action type="Rewrite" url="http://www.google.com&quot; />
    </rule>
    </rules>
    </rewrite>
    </system.webServer>
    </configuration>

  9. Hi Ruslan,

    Thanks for contributing the guide “Using Azure Web Site as a reverse proxy”. I’m enjoy reading your guide for quite a while. Recently I have implemented Azure Website to act as a reverse proxy for our web servers in test environment.

    I believe the xdt transform was successful based on the log file below.

    2014-08-06T10:43:46 sandboxproc.exe C:\DWASFiles\Sites\ARR-BEM\Temp\applicationhost.config
    2014-08-06T10:43:46 env XPROC_TYPENAME=Microsoft.Web.Hosting.Transformers.ApplicationHost.SiteExtensionHelper, Microsoft.Web.Hosting, Version=7.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35
    2014-08-06T10:43:46 env XPROC_METHODNAME=Transform
    2014-08-06T10:43:46 Start ‘site’ site extension tranform
    2014-08-06T10:43:46 StartSection Executing InsertIfMissing (transform line 4, 8)
    2014-08-06T10:43:46 on /configuration/system.webServer/proxy
    2014-08-06T10:43:46 Applying to ‘system.webServer’ element (no source line info)
    2014-08-06T10:43:46 Inserted ‘proxy’ element
    2014-08-06T10:43:46 EndSection Done executing InsertIfMissing
    2014-08-06T10:43:46 Successful ‘D:\home\site\applicationHost.xdt’ site extension tranform
    2014-08-06T10:43:46 sandboxproc.exe complete successfully

    I follow your guide but I received an error.

    “The specified CGI application encountered an error and the server terminated the process.”

    Below are the log error.

    HTTP Error 502.3 – Bad Gateway
    There was a connection error while trying to route the request

    Basically I am trying to do is URL Rewrite http://test.blablab.com to http://www.google.com (just an example)

    Below are my web.config

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
    <system.webServer>
    <rewrite>
    <rules>
    <rule name="ReverseProxyInboundRule1" stopProcessing="true">
    <match url="*" />
    <action type="Rewrite" url="http://www.google.com&quot; />
    </rule>
    </rules>
    </rewrite>
    </system.webServer>
    </configuration>

    Appreciate if you can spare some time to look into the issue that i encountered.

    Thanks in advanced. Hope to see your reply soon!

    Regards,
    Stanley

  10. Thanks for the writeup! I was able to get my site working with this guide.

    If I wanted to add caching ability to my reverse proxy, how would one go about setting that up? E.g., I want the reverse proxy to honor the cache headers of the thing it is proxying and just serve up the content from its cache rather than hitting the underlying site.

  11. Hi.

    Thanks for the writeup. I’m trying to redirect a page on Azure, and I get the following error:

    You do not have permission to view this directory or page.

    My situation is that I have a URL, we’ll call it me.com that is a utility URL. In subdirectories, there are many unique applications. But the home URL has no purpose. I’d like to redirect it to the company web page….let’s call that mycompany.com.

    All I have in the site folder is the .xdt file in your write up.
    All I have in the wwwroot folder is a web.config that is included in your write up.

    Do I need anything else?

    Thanks!

    E

  12. Hi,

    I followed the steps in your tutorial but I’m getting a page not found error for external domain rewriting.

    If I use an internal page it works.
    Could please let us know (we are more having this error, see stackoverflow) if other settings are necessary for external domain rewrite?

    Many thanks!
    Constantin.

  13. I have implemented this as per the instructions, the reverse proxy is working, but i no longer have access to the original request ip address.

    Is it possible to foward the request ip address onto the webapp.

    Just to add im actually running a java web app undeneath using tomcat.

  14. Hi Ruslan,
    I followed all the steps correctly, for testing purpose my target URL is google.com, the redirect is happening but the URL in the browser also is changing to to google.com which I think should not be happening as you also have pointed in the article, please advise what is wrong

  15. Hi,

    Is this documentation still applicable now ? I created a new Webapp and copy the applicationHost.xdt in the dite folder and created a new web.config file with the content listed here and uploaded it in the wwwroot folder but all I get when brownsing to my app URL is the content of the hostingstart.html file. Should I have had other files is that wwwroot folder ?

    Thanks in advance,

  16. I also followed the instructions above and I get a 303 response code.

    You example (http://ruslany.net/proxy/) also returns the same 303

    After several hours of trying different things I could not get it working as a reverse proxy, i.e returning 200 ok with content from http://www.iis.net/

    has Azure changed in some way?

  17. Hi David,

    Thanks for letting me know about that. This is most likely because iis.net site has recently added a rule on their site to enforce HTTPS. For example if you browse directly to http://www.iis.net/ you will see that you get HTTP 303 that redirects to https://www.iis.net/

    Looks like I’ll need to update the article to point my proxy address to some other location that does not enforce https.

  18. Hi Ruslany,
    I am simply trying to Redirect HTTP requests that come in to my website to be sent to the HTTPS version. I am going through an Azure Application Gateway and have tried everything for just a basic website and can’t seem to get this working. I do not have a DNS name for my domain. This is just for testing, so I’m using this in my redirect string under URL Rewrite. https://{HTTP_HOST}{REQUEST_URI}. Any help would be much appreciated.
    Steve

  19. My redirect is working, but the website isn’t coming up.
    If I type in http://server ip (no DNS setup yet), then it gets redirected to https://server ip
    But I’m worried those URL Rewrite codes are not valid for server ip addresses when it says HTTP_HOST. What is my alternative for testing?

  20. About your update (requiring routes.IgnoreRoute(“proxy/{*pathInfo}”); ), I don’t understand why this is required for MVC. Aren’t the web.config server rewrite rules executed before MVC’s routing?

    Any time I want to add a new rewrite rule, will I first have to get a new build released to production that includes this ignore rule?

  21. Man i want to thank you sooo much for this article !!!
    I tried for 2 days to play with Azure application gateway to realize that it does not do URL rewrite.
    With your solution i fixed my issue in 10 minutes.
    Thanks again !

  22. I follow all steps,
    But still, it gives 404 Error.
    My website is on Azure in DNN.

    Plz, let me know what other settings it requires.

    Thanks in advance.

  23. Hi Tom, thanks for reporting this. You are right, the http://www.iis.net has started to enforce https on all its URLs. I’ll need to find some other site to proxy requests too because I cannot use HTTPS with my custom domain ruslany.net as I haven’t renewed my SSL certificate 🙂

  24. After thinking about it some more I realised that it is fine to rewrite to an HTTPS site but you just need to make sure you specify “https” in the URL. The following works fine:

  25. Hi @ruslany,
    After reading your post I started to implement this for bringing a blog site back to company-main-domain/blog, but I got stuck trying to re-compress the content after overwrite all links from the backed site.
    I was able to set the compression in my local environment(IIS 10) following other of your posts but for

  26. Hi there, i’m trying to get this working on my MVC site, followed the steps, but am experiencing some weirdness.

    In my example, i want to rewrite “/advice” to another site (wordpress blog).

    What’s really strange is “/advice/” works (rewrites URL), but “/advice” does a 301 to the correct page.

    So it’s like it’s matching the rule, but redirecting if the root, and re-writing for sub paths. I don’t understand how that’s possible, since i haven’t defined a 301?

    web.config:

    <rule name="Blog – Advice" stopProcessing="true">
    <match url="^advice/?(.*)" />
    <action type="Rewrite" url="https://mysite.wpengine.com/advice/{R:1}" />
    </rule>

    and i’ve ignored the route:
    RouteTable.Routes.IgnoreRoute(“advice/{*pathInfo}”);

    Please help 🙂

  27. It talks about using a Site extension. It implements the reverse proxy and it does the XDT transformation for you. If the above is setup correctly, then there is something wrong with the URL Rewrite rules. I would recommend you to enable Failed Request Tracing and debug this further.

  28. FYI, web.config is case sensitive and posted web.config will result in HTTP 500 due to case sensitivity of words `webServer` and `stopProcessing`. So if you get HTTP 500, make sure you correct casing.

  29. I tried so many stuffs but not working for react web app which returns 404. if anyone managed to get it work for react app, please assist

    Web.config

    Application.xdt
    !–?xml version=”1.0″?–>

    root@c838d043d443:/home/site

  30. I got it working with a change to applicationHost.xdt:

    I guess these days Azure Web Apps include a proxy by default tag, so SetAttributes can be used to reconfigure it.

Leave a Reply

Your email address will not be published. Required fields are marked *