Setting up a Reverse Proxy for SharePoint with TMG Server

SharePoint is often used to host public-facing websites and we can all agree it’s generally a bad idea to have general purpose SharePoint farm sitting on a publicly accessible interface directly. That’s where reverse-proxies come in rather handy; they’re designed to be the link between the scary outside world and your nice & cosy internal, AD-managed SharePoint farm. In a worst case scenario your reverse-proxy would take the brunt of any attacks leaving your SharePoint farm to happily continue blissfully unaware of the apocalypse unfolding outside the SharePoint network and that’s why people set them up; to take the bullet for the servers we really care about. This article is all about how to set that up using TMG Server as an example but in reality reverse-proxy systems are fairly common in terms of how they work on a practical level so this should be helpful to anyone looking to do the same.

This diagram should explain what we’re trying to achieve:

image

The purple bits are the reverse-proxy and the blue bits are a normal SharePoint farm. The nice thing here is that at no point ever do external users have a TCP connection to SharePoint and our SharePoint farm is nicely protected from any external abuse. This is in short why you’d even have a reverse-proxy.

Environment Setup

For this test we have 3 private, internal networks - 192.168.0.0/24, 192.168.10.0/24, 192.168.20.0/24

TMG machine is not domain-connected so has no inherent trust of the SharePoint farm being used.

TMG Server Setup

First step; let’s prepare the server & install TMG Server. The first thing we need to do is prep it before we can install TMG, just like SharePoint.

clip_image004

Next we need to install TMG Server itself. Part of that involves configuring what’s external and what’s not. Configure internal IP range:

clip_image005

That should be enough for now; install the rest…

clip_image006

Once done you’ll need to set some specific settings up. Start with network settings:

clip_image007

Without wanting to explain each network template, we’re selecting “edge firewall”. In short, nothing comes in or out unless there’s a TMG firewall rule for it.

clip_image008

For some reason you have to define the internal range again + any internal network addresses that’ll be relevant. My SharePoint farm spans multiple subnets so these are included too.

clip_image009 clip_image010

Naming your adaptors beforehand comes in handy here.

clip_image011

This TMG Server we want completely isolated from the domain. It does mean we won’t be able to authenticate against the domain for TMG connections but it’s the safest & easiest to get up & running.

Configure deployment options – there are options for malware protection, web-filtering and automatic updates. Configure as you will; it’s not relevant for this exercise, although if you’re just testing I’d turn most of that off.

Publish a SharePoint Web-Application

So in TMG Server this is relatively simple; what we’re doing is simultaneously opening a port on the incoming connections firewall & also creating a separate “listener” to proxy requests to SharePoint.

clip_image013

Click on “Publishing SharePoint Sites” & give the rule a name (“SP15” for example).

clip_image014

Click “next”; select “use non-secured” for this test.

clip_image015

Now specify the URL of the internal application to be published:

clip_image016

Make sure the TMG Server can resolve the address (i.e. DNS settings are correct for the machine). If for some reasons DNS isn’t available or it’s wrong, enter the IP address too.

Next, we’re going to configure a host-header for the external listener:

clip_image017

Configure TMG Server External Listener

Next we need to configure a listener to forward requests to SharePoint. Create a new one on the next page & give it a name.

clip_image018

For simplicity I’ve got for just standard HTTP but you should probably go for HTTPS if possible.

Next we need to configure where the listener will be listening:

clip_image019

Next, authentication for the listener. Again for simplicity I’ve said “none”; that doesn’t mean users will be able to walk into the application or anything, just that the authentication won’t be done at a proxy-level and also a SharePoint level for connections that authenticate OK at the proxy.

It’s important to note this can be a key protection from denial-of-service (DoS) attacks; TMG will take the brunt of the attacks and only pass connections that have already authenticated meaning that any DoS attacks will only take down the TMG Server(s), leaving SharePoint unaffected and free to serve internal requests too.

clip_image020

That’s pretty much it; your listener is ready for use. Continue configuring the publishing rule.

Finish Publishing Rule

Your listener is now ready to use:

clip_image021

Finally, delegation. This one’s simple; we’re not pre-authorising requests but just sending them directly through to SharePoint so there’s only one setting that makes sense:

clip_image022

Next, we need to know the alternative access mapping for the external entry point is ready:

clip_image023

Yes, it’s already configured – SharePoint would never directly receive requests on this address because no DNS records for “sp15external” point to SharePoint but instead to the reverse-proxy. You’re just preparing SharePoint for the fact it’ll receive requests with that value in the HTTP header but it’ll be via another connection method; the same applied for SSL too. Here’s my AAM list:

clip_image024

Troubleshooting TMG

If TMG doesn’t seem to apply any configuration changes for some reason and you’re tearing your hair out – make sure this is green:

clip_image026

This tool simply creates/updates “a configuration” but it’s down to TMG core/firewall to actually update itself from the configuration store – this shows the last time that happened. If it’s not synced and green then you have a TMG problem you’ll need to fix before anything will or could work – review alerts for why this might be but in short, the TMG Manager publishes the configuration you set – the core service needs to apply the config and this status above shows you if it has or not.

In addition to this you need to keep an eye on system alerts; if a listener had problems binding to any necessary ports then then whole thing will fail but TMG will at least let you know something serious went wrong in the alerts. Make sure there’s no critical errors.

Also check for firewall logs if nothing connects because it’ll tell you why, assuming it was the firewall that killed it:

clip_image028

Testing External Access

Now when we access TMG server via the external address (which again, points to TMG not SharePoint) we should see the page loaded as if we’ve gone directly to the farm. Tada! Your reverse-proxy is working. If not, check the DNS name resolves to the TMG Server.

SharePoint Hosted SharePoint Apps

A complication that can arise with reverse-proxying SharePoint 2013 is the new “SharePoint hosted” application model. In short, the URL used changes dynamically per application so this link:

clip_image030

Sends us to our “App Management” URL:

clip_image032

…but for our external clients, that doesn’t work even if DNS works because TMG Server wasn’t expecting it:

clip_image034

Configure TMG for SharePoint App URLs

The problem here is that TMG Server normally needs a concrete header to work with but the URL is auto-generated to some extent. In SharePoint you specify the beginning and end but the middle is auto-generated. So the full URL for our application is “https://app-127b4bda5b56ac.spapps/” – the underlined part is what we configure.

This creates a small problem in that our firewall rule created earlier uses a host-header and in this case our host-headers are dynamic so we need to remove it and just forward requests unconditionally to SharePoint. This creates a small risk of course but at the time of writing it’s the only way.

The Problem of Double-Authentication

You may notice that on being redirected to the apps domain, you’re prompted for credentials again which surprises some as it’s the same application/farm effectively. The thing is though, to the web-browser the original SharePoint domain and the application domain are completely separate by design so therefore requires re-authentication. If that re-authentication is done with NTLM/Kerberos and the app domain isn’t an intranet URL (which in short, it can’t be), then the IE at least will prompt for credentials.

If SharePoint authentication is done with forms-based authentication or an external claims provider like ADFS then the user will be sent there to authenticate, which depending on how its setup will either authenticate the user transparently and redirect back to the app domain. If the user can’t be auto-authenticated then the user logs in with either Windows auth or forms manually and then returns once everything is cleared.

A picture paints a thousand words, so here’s what happens for each time the browser needs to re-authenticate with SharePoint (or ADFS for that matter):

image

Now, if when you navigate to the app URL and you want transparent logins, this are you options – ADFS or forms-based login.

image

ADFS is probably the preferred route because you authenticate against a separate domain just for ADFS. This means if both your SharePoint and app domain use ADFS, the “remember me” will be remembered for both as ADFS will use a 3rd domain on its own for the two application domains.

To setup ADFS for an apps domain, see this article - https://blogs.technet.com/b/speschka/archive/2012/12/07/using-sharepoint-apps-with-saml-and-fba-sites-in-sharepoint-2013.aspx

Wrapping Up

This guide hopefully has shed some light on the value of setting up a reverse-proxy and how to do it, broadly speaking. There are lots you can do that aren’t explored here; have TMG server form-based authenticate for delegating to an NTLM/Kerberos enabled SharePoint application, and other such tricks. There’s also a new component in Windows Server 2012 R2 called “Web-application Proxy” which does similar but with ADFS too; I’ll be posting about how to integrate that when I can.

Cheers!

// Sam Betts