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:
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.
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.
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.
Next we need to install TMG Server itself. Part of that involves configuring what’s external and what’s not. Configure internal IP range:
That should be enough for now; install the rest…
Once done you’ll need to set some specific settings up. Start with network settings:
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.
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.
Naming your adaptors beforehand comes in handy here.
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.
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.
Click on “Publishing SharePoint Sites” & give the rule a name (“SP15” for example).
Click “next”; select “use non-secured” for this test.
Now specify the URL of the internal application to be published:
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:
Next we need to configure a listener to forward requests to SharePoint. Create a new one on the next page & give it a name.
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:
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.
That’s pretty much it; your listener is ready for use. Continue configuring the publishing rule.
Your listener is now ready to use:
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:
Next, we need to know the alternative access mapping for the external entry point is ready:
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:
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:
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:
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.
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:
Sends us to our “App Management” URL:
…but for our external clients, that doesn’t work even if DNS works because TMG Server wasn’t expecting it:
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 “http://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.
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):
Now, if when you navigate to the app URL and you want transparent logins, this are you options – ADFS or forms-based login.
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 - http://blogs.technet.com/b/speschka/archive/2012/12/07/using-sharepoint-apps-with-saml-and-fba-sites-in-sharepoint-2013.aspx
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.
// Sam Betts