ARR to Delegate Between IIS and Apache [Answered]RSS

17 replies

Last post Jun 26, 2010 03:05 AM by bbar

  • ARR to Delegate Between IIS and Apache

    Jun 17, 2010 04:17 AM|bbar|LINK

    I have a website that runs mostly on one web server (IIS), but at times will need to use another (Apache). The first box is running Windows Server 2008 with IIS7. The other box is running Fedora 13 with the most recent version of Apache (I think it’s 2.2.15).

    And this is what I would like to do:

    www.mysite.com/section-1, served by IIS
    www.mysite.com/section-2, served by Apache

    Or, rather, everything is directed to the box running IIS except those requests with a pattern of www.mysite.com/section-2* (which will be directed to the Linux/Apache box).

    How do I setup the routing rules/URL rewrite rules for a situation like that? Also, do I need a dedicated box just to run ARR, or can I run it on the Windows Server 2008 machine?

    Thanks!

    Brent

  • Re: ARR to Delegate Between IIS and Apache

    Jun 17, 2010 05:50 AM|Mark S. Rasmussen|LINK

    You don't need a dedicated ARR machine, you can install ARR on the machine hosting the IIS based website. There are multiple ways to do it, this is the simplest I believe.

    Make sure you have a website with a * binding so it matches all requests. Make sure the IIS website hosting www.mysite.com/section-1 listens to a hostname other than www.mysite.com, iisinternal.mysite.com for example.

    Now create an ARR rule with a wildcard pattern of "/section-1*" and set it to a rewrite action with an action URL of http://iisinternal.mysite.com{R:0}. This will ensure all incoming requests to www.mysite.com/section-1* are rewritten to the IIS website listening for internal.mysite.com.

    Create an ARR farm called Apache with a single server - apacheinternal.mysite.com (ensure apacheinternal.mysite.com resolves to the LAN IP of your Apache server). Now create a second ARR rule with a wildcard pattern of "/section-2*" and set its action to rewrite to the Apache farm with a path of {R:0}.

    The above setup will internally rewrite the www.mysite.com/section-1* requests to the iisinternal.mysite.com site on the same IIS box. Any requests for www.mysite.com/section-2* will be routed to the Apache server through the Apache farm.

    - Mark

  • Re: ARR to Delegate Between IIS and Apache

    Jun 17, 2010 03:10 PM|bbar|LINK

    Thanks a lot for the reply -- it's starting to make more sense to me.

    My website has multiple sections. For example, www.mysite.com/section-1, www.mysite.com/section-2, www.mysite.com/section-3, etc... If I wanted all sections to go to IIS (except for /section-2*), can I just add one rule with a wildcard pattern of "/section-2*" and then rewrite to the Apache farm with a path of {R:0}? Or do I need to specify rules for each section?

    Thanks!

    Brent

  • Re: ARR to Delegate Between IIS and Apache

    Jun 17, 2010 03:53 PM|Mark S. Rasmussen|LINK

    In that case I'd keep the Apache rule as a wildcard pattern of /section-2* and change the IIS rule to a regex one with a pattern of:
    /section-([13456789]|\d{2,})

    That'll match any section exception section-2.

    - Mark

  • Re: ARR to Delegate Between IIS and Apache

    Jun 17, 2010 05:32 PM|bbar|LINK

    For some reason, it's not working. Maybe if I explain what I've tried so far, you (or someone else) can spot my mistake.

    In IIS7 my site name is mysite.com. The site bindings are as follows:

    Type: http
    Host Name: iisinternal.mysite.com
    Port: 80
    IP Address: *
    Binding Information:

    (The site also has net.tcp, net.pipe, net.msmq and msmq.formatname protocol types. Let me know if you'd like to take a look at that information as well.)

    I've created a server farm (named "Apache") with only one server in it (it's a lonely farm). The server address is apacheinternal.mysite.com. I've also added this line to the host file (windows/system32/drivers/etc/hosts):

    192.168.1.99     apacheinternal.mysite.com     # apache/linux server

    So when I type http://apacheinternal.mysite.com into a browser on the Windows Server 2008 machine, it resolves to the apache server.

    I've also created two URL Rewrite inbound rules:

    Rule 1: Matches the pattern "/about*" using wildcards. It rewrites to "http://iisinternal.mysite.com{R:0}"

    Rule 2: Matches the pattern "/articles*" using wildcards. It routes to server farm "Apache" using path "/{R:0}".

    Of the sections in mysite.com (/about, /articles, /tools, /research, etc...), I only want /articles to be directed to the Apache server.

    Thanks again for all of your help with this.

    Brent

  • Re: ARR to Delegate Between IIS and Apache

    Jun 17, 2010 05:44 PM|Mark S. Rasmussen|LINK

    Can you elaborate on how it's not working? Not working at all or is it just one of the sites not working? 

    If you access apacheinternal.mysite.com/articles from your ARR machine in a browser, does it show up as it should? It's important that the apache machine is also setup to listen to that hostname.

    The tcp/pipe/msmql protocols shouldn't matter.

    Regarding the rules, I'd put Rule #2 as the first rule (ordering wise, top) and make sure it's set to stop processing of subsequent rules. Make sure it matches a wildcard pattern of /articles*. For the second rule, just set it up as a wildcard rule with a pattern of "*". Thus the first rule should match the /articles* URL's and send it to the Apache farm while the second rule will match anything and rewrite it to the local IIS site - it won't match /articles* requests though as the first rule will take precedence.

    - Mark

  • Re: ARR to Delegate Between IIS and Apache

    Jun 17, 2010 06:58 PM|bbar|LINK

    duplicate post
  • Re: ARR to Delegate Between IIS and Apache

    Jun 17, 2010 07:30 PM|bbar|LINK

    The apache server is just runing the MediaWiki software, and the only thing that works right now is the test page. From the ARR machine, if I type "apacheinternal.mysite.com/wiki" into a browser, then I get the wiki welcome page. If I try to go to "apacheinternal.mysite.com/articles", I'll get a 404 error because I haven't created a directory for articles yet. Also, Apache isn't listening for the "apacheinternal.mysite.com" host name. I'll do that tonight when I get home.

    I did switch the rules around. That makes perfect sense.

    As far as routing everything else to IIS, though, I've changed the second rule to match the pettern "*" using wildcards, like you've suggested. It's routing everything to "iisinternal.mysite.com{R:0}". When I open a browser and type http://www.mysite.com, I get a 404 - file or directry not found error.

    Also, I'm not sure if it complicates things, but I have two sites listed in IIS7: 1) mysite.com, and 2) www.mysite.com. mysite.com has a 301 redirect to www.mysite.com to keep a canonical url.

  • Re: ARR to Delegate Between IIS and Apache

    Jun 18, 2010 03:19 AM|bbar|LINK

    It seems like I've made a little more progress on this (if that's what you want to call it). Just for fun, I removed all the URL Rewrite rules and added a new one (at the server level; not the site level). I told it to match the url pattern of "*" using wildcards and then redirect it to the Apache farm (which has only one server listed and has an address of "apacheinternal.mysite.com") with a path of "/wiki". If I understand it correctly, that should redirect all traffic coming into IIS to "apacheinternal.mysite.com/wiki". If I just open a browser on the ARR machine and type "apacheinternal.mysite.com/wiki", I get a correctly rendered page from Apache. However, when I go to www.mysite.com, I get the follwoing error:

    "The virtual path 'null' maps to another application, which is not allowed."

    I've read on learn.iis.net, as well as on your blog, that it's a bug with IIS7 on Windows Server 2008 (I'm not on R2). Is there a fix for this, or am I just completely missing something? If upgrading to R2 will fix it, I don't mind doing it, but didn't want to do anything too crazy before I got an answer.

    Thanks again for your help.

    Brent

  • Re: ARR to Delegate Between IIS and Apache

    Jun 18, 2010 03:34 AM|Mark S. Rasmussen|LINK

    Sorry about that, I should've mentioned that the rules need to be made at the server level for the easiest setup. Where did you have the rules before, on the default site bound to "*" or on your iisinternal.mysite.com site?

    To work around the bug, you should be able to move the rules to the default website bound to "*" since it only occurs if you have rules at the serverlevel and you have custom HttpModules at the sitelevel (which may be the cause if you're rewriting the request - can't say for sure though as I don't know the internals of the bug). I can however confirm that the bug is no longer an issue on our servers after we upgraded to 2008R2, though it is a lot of work just to work around that single bug.

    As long as the iisinternal.mysite.com doesn't do a 301 redirect, then having mysite.com redirect to www.mysite.com shouldn't matter. You might want to add an {HTTP_HOST} condition to your rewrite rule so it only listens for requests for the www.mysite.com hostname, that'll ensure the rule doesn't get in the way of your normal 301 redirecting website.

    If it still doesn't work, please post your <webFarms> and <rewrite> sections of applicationHost.config file as well as the <rewrite> section in the web.config file in case you've setup the rules at site level - I'm starting to loose track of where exactly we're at regarding the setup :)

    - Mark

  • Re: ARR to Delegate Between IIS and Apache

    Jun 18, 2010 04:23 AM|bbar|LINK

    Well, by adding that {HTTP_HOST} condition you've managed to fix my redirect problem. Thank you! But, I'm still getting the 404 error for every page in the site. All URL Rewrite rules have been at the server level, except for the 301 Redirect. That rule was done at the site level (mysite.com). Here are the parts of the config files you asked for. I don't see the harm in leaving the actual site name in there so I guess you can go to the site and see the error for yourself.

    applicationHost.config

    <webFarms>
         <webFarm name="Apache" enabled="true">
              <server address="apacheinternal.amberrhythm.com" enabled="true" />
         </webFarm>
         <applicationRequestRouting>
              <hostAffinityProviderList>
                   <add name="Microsoft.Web.Arr.HostNameRoundRobin" />
                   <add name="Microsoft.Web.Arr.HostNameMemory" />
              </hostAffinityProviderList>
         </applicationRequestRouting>
    </webFarms>

    <rewrite>
         <globalRules>
              <rule name="route-to-apache" patternSyntax="Wildcard" stopProcessing="true">
                   <match url="/articles*" />
                        <action type="Rewrite" url="http://Apache/{R:0}" />
              </rule>
              <rule name="route-to-iis" patternSyntax="Wildcard">
                   <match url="*" />
                        <action type="Rewrite" url="http://iisinternal.amberrhythm.com{R:0}" />
                             <conditions>
                                  <add input="{HTTP_HOST}" pattern="www.amberrhythm.com*" />
                             </conditions>
              </rule>
         </globalRules>
    </rewrite>

    Web.config on mysite.com (amberrhythm.com). This is the 301 redirect and is the only site on the server with a URL Rewrite rule (at the site level).

           <rewrite>
              <rules>
                <rule name="Redirect to WWW" stopProcessing="true">
                  <match url=".*" />
                  <conditions>
                    <add input="{HTTP_HOST}" pattern="^amberrhythm.com$" />
                  </conditions>
                  <action type="Redirect" url="http://www.amberrhythm.com/{R:0}" redirectType="Permanent" />
                </rule>
              </rules>
            </rewrite>

     

    Thanks Mark,
    Brent

  • Re: ARR to Delegate Between IIS and Apache

    Jun 18, 2010 05:30 AM|Mark S. Rasmussen|LINK

    So far so good, it all seems solid from here. Can you try and enable FREB and get a FREB log for the 404 error you get when making a request, both for the Apache directory as well as the root? Posting the FREB log should detail exactly which URL is requested and routed to. If you'd rather not post the log in public, you may also send it to my email at mark@improve.dk.

    Have you setup the Apache server directories so it responds with the correct content if you make a manual request for http://apacheinternal.amberrhythm.com/articles/*?

    If you go to http://iisinternal.amberrhythm.com/* in a browser on the local machine, do you get the correct content?

    - Mark

  • Re: ARR to Delegate Between IIS and Apache

    Jun 18, 2010 04:24 PM|bbar|LINK

    This seems a little odd. I enabled FREB and told it to log errors between 401.3-999 for WWW Server (Rewrite property only). If I type www.amberrhythm.com into any browser, I get the 404 error, but when I check the log (inetpub\logs\FailedReqLogFiles), there's nothing.

    If I open a browser on the ARR/IIS machine, and type "internaliis.amberrhythm.com" I get nothing (or, exactly what you would get if you tryped it into your browser). So I added a line in the hosts file pointing "internaliis.amberrhythm.com" to the ip address of my IIS machine. I can now get to "internaliis.amberrhythm.com" from the local browser and the homepage is displayed correctly. Also, when I do this, a log file is created. It's the /favicon.ico 404 error, but I emailed you the log just in case you want to look at it.

    If I go to http://apacheinternal.amberrhythm.com I get the Apache test page (because everything coming in over port 80 on the Linux/Apache machine is directed to localhost). If I go to http://apacheinternal.amberrhythm.com I get the wiki welcome page. Remember, I added a line in my hosts file that points http://apacheinternal.amberrhythm.com to my Linux/Apache server.

    Any ideas?

    Brent

  • Re: ARR to Delegate Between IIS and Apache

    Jun 19, 2010 01:42 PM|bbar|LINK

    I'm not sure exactly why, but sometimes when I post it needs approval, and other times it goes right through. (As soon as I post this, they'll probably approve my post from yesterday morning.) Anyway, if you see two very similar looking posts, that's what's going on.

    Okay, so I enabled FREB on the site www.amberrhythm.com. I guess the easiest way to show you how it's configured is by showing you the applicationHost and web.config files:

    applicationHost.config

    <site name="www.amberrhythm.com" id="3" serverAutoStart="true">
      <application path="/" applicationPool="ASP.NET v4.0">
        <virtualDirectory path="/" physicalPath="C:\WebSites\amberrhythm" />
      </application>
      <bindings>
        <binding protocol="http" bindingInformation="*:80:iisinternal.amberrhythm.com" />
      </bindings>
      <traceFailedRequestsLogging enabled="true" />
    </site>

    <traceFailedRequestsLogging directory="%SystemDrive%\inetpub\logs\FailedReqLogFiles" />

    web.config from site name "www.amberrhythm.com"

    <traceFailedRequests>
      <add path="*">
        <traceAreas>
          <add provider="WWW Server" areas="Rewrite,RequestRouting" verbosity="Verbose" />
        </traceAreas>
        <failureDefinitions timeTaken="00:00:00" statusCodes="401.3-999" />
      </add>
    </traceFailedRequests>

    I can request the page as much as I want, but I get no logs. Any ideas?

    I have only partially setup the Apache server. If I request http://apacheinternal.amberrhythm.com/articles/* I'll get nothing back because there's no /articles directory (yet). But, if I request http://apacheinternal.amberrhythm.com, I get the correct default page to load correctly. Also, if I request http://apacheinternal.amberrhythm.com/wiki, I get the correct welcome wiki page. (All these requests are made from the IIS/ARR machine, by the way.)

    I also added a line in the hosts file to point "iisinternal.amberrhythm.com" to the ARR/IIS machine. So I can type http://www.iisinternal.amberrhythm.com/* and the entire website is displayed correctly.

    Thanks Mark,
    Brent

  • Re: ARR to Delegate Between IIS and Apache

    Jun 20, 2010 06:48 PM|Mark S. Rasmussen|LINK

    Not sure about the moderation/approval process either, I get the same result here. I hope I'll some day be trusted enough to be auto approved :)

    I seem to have been complicating things a lot - actually there's a much simpler way of setting this up. I just made a test setup myself to make sure how to do this right, and blogged about it here: http://improve.dk/blog/2010/06/21/routing-requests-for-a-subdirectory-to-another-server-using-iis-application-request-routing

    Basically you should just setup the IIS website as it is normally, using the normal host header. Create the Apache server farm and setup a single global rule that matches the "articles(/.*)?" pattern and sends the requests to the farm. That should be all that's necessary. Though I haven't used your specific urls and hostnames in my blog entry, it should be pretty simple to follow.

    Let me know if you get it up working, and sorry for leading you down the wrong path :)

    - Mark

  • Re: ARR to Delegate Between IIS and Apache

    Jun 21, 2010 02:55 AM|bbar|LINK

    First off, Mark, I love you. Thanks so much for helping me with that.

    It looks like it "wants" to work, but it's throwing the "The virtual path 'null' maps to another application, which is not allowed" error. Is the only fix to upgrade to Server 2008 R2 and IIS 7.5?

  • Re: ARR to Delegate Between IIS and Apache

    Jun 21, 2010 04:03 AM|Mark S. Rasmussen|LINK

    Do you have any custom HttpModules running at the global level? I'm not completely sure what triggers that bug, but I know I had it when I ran an HttpModule at the global level. Moving the module to a specific site solved the problem, as will upgrading to 2008R2.

    - Mark

  • Re: ARR to Delegate Between IIS and Apache

    Jun 26, 2010 03:05 AM|bbar|LINK

    I can't thank you enough for all of your help. I upgraded to Windows Server 2008 R2, followed your blog and everything is working like it should. Now I just need to configure Apache and learn how to use MediaWiki! Thanks again.

    Brent