Friday, June 5, 2015

Securing RD Gateway with Web Application Proxy - Part 2

Picking up where we left off...

Welcome to Part 2 of my series "Securing RD Gateway with Web Application Proxy." In Part 1 of the series, we had left off after installing AD Federation Services and Web Application Proxy. In addition to the installation, we also performed basic configuration of both products. In Part 2 of the series, we'll start configuring the pieces needed specifically to get RD Web Access and RD Gateway working behind Web Application Proxy.


Creating the Relying Party Trust in ADFS

Now that ADFS and WAP are both installed, the next step is to create a trust relationship between ADFS and RDS. This is accomplished by creating a Relying Party Trust within the ADFS Management console. Switch to the ADFS server, and from Server Manager, click Tools and select AD FS Management. In the ADFS Management console, expand Trust Relationships, right-click on Relying Party Trusts, and select Add Relying Party Trust from the context menu.

***NOTE*** - I originally tried adding a Non-Claims-Aware trust, but this was unsuccessful. After speaking with an engineer from Microsoft, he explained that RDS actually isn't fully claims-aware, but to create a claims-aware trust anyways to get everything working behind Web Application Proxy.
Adding the Relying Party Trust




The Add Relying Party Trust Wizard will open. Click the Start button to begin.
Adding the Relying Party Trust

Select the bottom option to Enter data about the relying party manually and click Next.
Adding the Relying Party Trust

Enter a name and description for the trust, and click Next.
Adding the Relying Party Trust

Leave the default of AD FS profile and click Next.
Adding the Relying Party Trust
Optionally select a token encryption certificate. We'll be skipping this step for this demo. Click Next.
Adding the Relying Party Trust

Leave the default options, as we'll be relying on the WS-Trust protocol. Click Next.
Adding the Relying Party Trust

For the Relying party trust identifier, enter the external URL that is used to access your RD Web Access and RD Gateway. Only enter the base URL, do not add \RDWeb or any sub-directories. Click the Add button to add the identifier, and then click Next.
Adding the Relying Party Trust

ADFS Multi-factor Authentication is outside the scope of this post, so leave the default option of I do not want to configure multi-factor authentication settings for this relying party trust at this time and click Next.
Adding the Relying Party Trust

Select the default option of Permit all users to access this relying party and click Next.
Adding the Relying Party Trust

Click Next to add the trust.
Adding the Relying Party Trust

Uncheck the box to edit claim rules, and click the Close button to complete the wizard.
Finished with the Relying Party Trust

Back in the ADFS Management console, you should now see your RDS relying party trust listed.
The newly added Relying Party Trust for RDS

Publishing RD Gateway behind Web Application Proxy

OK, so let's recap quickly. We've installed ADFS and configured it with our certificate. We've installed WAP and pointed it at the ADFS server. We've created the Relying Party Trust in ADFS for RDS. The next step is to publish RD Gateway through WAP.

Connect to your WAP server and switch to the Remote Access Managament console. In the left pane, make sure Web Application Proxy is selected, and then in the right pane, click Publish.
Publishing RD Gateway

The Publish New Application Wizard will open. Click Next.
Publishing RD Gateway

For the preauthentication, select Active Directory Federation Services (AD FS) and click Next.
Publishing RD Gateway

Select the Relying Party Trust that we created earlier, and click Next.
Publishing RD Gateway

Choose a name for this published application - this is for internal use only. Enter the external URL that users will use to access your RD Gateway/RD Web Access installations, and then select the certificate used by your RD Gateway. Make sure the backend server URL is the same as the external URL. Click Next.
Publishing RD Gateway

Click Publish.
Publishing RD Gateway

Finally, click Close to finish the wizard.
Publishing RD Gateway... complete!

You should now see your published web application in the Remote Access Management console.
Our brand-new published web app


Next, we need to customize a few of the settings for the published web proxy, which can only be done with PowerShell. We need to modify two settings:

  • DisableHttpOnlyCookieProtection - this is required for RD Gateway to function correctly.
  • InactiveTransactionsTimeoutSec - how often an idle session will reset. The default is 300 seconds, meaning if a user's RemoteApp goes idle, it will reset the connection every five minutes - not something we want to happen.
Open a PowerShell window with elevated credentials (run as administrator) and enter the following command:

Get-WebApplicationProxyApplication -Name "AppName_Here" | Set-WebApplicationProxyApplication -DisableHttpOnlyCookieProtection:$true -InactiveTransactionsTimeoutSec 28800

***NOTE*** - This command won't work if you didn't install KB2982037 (HttpOnly Update) per the prerequisites - do so now if you haven't already.
Modifying the DisableHttpOnlyCookieProtection and InactiveTransactionsTimeoutSec properties

The last step in publishing a web application through WAP is to ensure the server can forward correctly to the internal URL of the web application. If your internal DNS name resolution is working fine, then you are good, but otherwise the easiest way to ensure the WAP server forwards correctly is to modify the HOSTS file on your WAP server.

Create an entry in the HOSTS file pointing the internal URL to the correct IP address of your RD Gateway server.
Modifying the HOSTS file on the WAP server


Modifying your RDS Collections

At this point, you should be able to access the external URL for your RDS environment, be prompted by the ADFS pre-authentication page, successfully login and get passed onto RD Web Access. However if you try to access a published RemoteApp - it will fail to connect!

We need to modify both the session collections and virtual desktop collections with a custom RDP property so that the RD Gateway knows how to retrieve the ADFS edge token from the browser, in order to get past WAP.

Connect to your RD Connection Broker server, open a PowerShell window and type the following commands:
Import-Module remotedesktop
Set-RDSessionCollectionConfiguration -CollectionName <collection_name_here> -CustomRdpProperty "pre-authentication server address:s:https://<external_URL_here>`nrequire pre-authentication:i:1"
Modifying a test collection with the pre-authentication settings

Notice for the pre-authentication server address property, the URL is the same as the published URL in WAP. You do not need to add /RDWeb at the end of the URL.

You'll need to enter this command for each RDS session collection in your environment. Here's the equivalent command for a virtual desktop collection:
Import-Module remotedesktop
Set-RDVirtualDesktopCollectionConfiguration -CollectionName <collection_name_here> -CustomRdpProperty "pre-authentication server address:s:https://<external_URL_here>/rdweb `nrequire pre-authentication:i:1"
Once you've set the pre-authentication settings on each session collection and virtual desktop collection, you'll be able to successfully launch RemoteApps and connect to VDI collections via RD Web Access.

Modifying Desktops.aspx

In addition to modifying each Session Collection and Virtual Desktop Collection, if you utilize RD Web Access and the "Connect to a remote PC" link to allow users to remotely access their work computers, you'll also need to modify the Desktops.aspx page to add the pre-authentication RDP properties.

Navigate to C:\Windows\Web\RDWeb\Pages\en-US and open Desktops.aspx in the text editor of your choice, and search for the following string:
RDPstr += "getUserNameRdpProperty();
Just BEFORE that line of code, add the following two lines of text:
RDPstr += "pre-authentication server address:s:https://<external_URL_here>\n";
RDPstr += "require pre-authentication:i:1\n";
Modifying Desktops.aspx with preauthentication settings

Just like when modifying your Session Collections, enter the URL without adding /RDWeb at the end.

Save the file. Now when you remote into a machine via RD Web Access, you'll be able to connect successfully.

Conclusion

That's about it. If you've followed the instructions, you should have RD Web Access and RD Gateway working behind Web Application Proxy, with AD Federation Services for preauthentication.

48 comments:

  1. Tom, does this allow you to use a RDP file externally with the RDP geatway settings saved in it? or do you have to login to RDweb and then use the Connect to a remote PC feature?

    ReplyDelete
    Replies
    1. Hi Adam, following this guide will explicitly PREVENT using a saved RDP file. The reason is because of using the ADFS preauthentication. Basically WAP won't pass the connection to the backend server unless you have authenticated against ADFS first. When you authenticate, WAP issues a cookie to your browser (also called an edge token) that allows the traffic to flow past WAP and onto the backend server. When using a saved RDP file, you won't have access to the edge token, and WAP will block the traffic.

      That being said, the real use case for setting up RD Gateway behind WAP in this manner is if you want to force your users to login using RDWeb. In my case, we have a third party two-factor authentication product that integrates with the RDWeb login page. Users were saving RDP files and using mstsc.exe to skip RDWeb and connect directly to RD Gateway, essentially bypassing our 2FA. By setting up WAP with ADFS preauthentication, we are preventing this backdoor access and forcing users to user RDWeb and 2FA.

      Delete
    2. Thanks for the response, I am trying to design a solution for external contractors to get in to our network and have put this option on the table.
      Thanks

      Delete
  2. Hi Tom, great post, thanks. Couple of questions. Where does your RDS Gateway/Web server sit in your network, the DMZ or WAN? What if any ports did you have to open to it from the WAN or does it flow through the Web proxy? Also, any recommendations on 2FA solution?

    ReplyDelete
    Replies
    1. Hi Joshua, you'll want the WAP server in the DMZ network, as that is what users will be directly connecting through. ADFS and RD Gateway/RD Web Access can actually be in your internal network. You'll only need ports 80/443 open on the external firewall to the WAP server. The internal firewall is a little trickier, you'll need 80/443 open between the WAP server and the RD Gateway/RD Web Access server, but you'll also need to open 443 between the WAP and ADFS servers. In my testing, I could only get this working properly if the WAP server was a member of the internal domain, so you'll need to open standard ports for AD/DNS/Kerberos, etc.

      Delete
  3. Hi Tom,

    Thank you for the great post, does this auto sign you in to the RDWEB page and also are you prompted for credentials when launching a RemoteApp?

    ReplyDelete
    Replies
    1. Hi Dan,

      Unfortunately the user will NOT automatically be signed into the RDWeb page - that sort of integration between WAP and RDWeb just isn't there yet - though when I spoke with Microsoft, they did make mention of that functionality possibly being included with the next version of WAP in Windows Server 2016.

      The good news, however, is that RDWeb SSO continues to function when launching RemoteApps as expected. So as long as you have the proper certificates and SSO is working before WAP, it will continue to function after WAP.

      Delete
  4. Hi Tom,

    Thanks for your excellent article.

    However, prior to seeing this article, i had published RDWeb (& Gateway) using Non-Claim aware application template. I was able to access RDWeb and SSO was also working fine. While launching any remote applicaition, i was being prompted for credentials and even though i was providing correct credentials, i was not able to login.

    Now, after reading this article, i have changed that to claim aware application. Although, i am able to login and launch application but i am being prompted for credentials three time. First is form based authentication from WAP/ADFS, second from RDWeb and then third one from while launching the Remote App.

    Can you please suggest if it is possible to achieve SSO?

    Regards
    Shubham

    ReplyDelete
    Replies
    1. Hi Shubham,

      Does SSO work when accessing RDWeb/RD Gateway directly, without WAP/ADFS in the picture? Typically if SSO is not working, it's a problem with your certificates. I would suggest looking down that route.

      Delete
    2. SSO between RDWeb and RDGateway is also not working internally. I have asked my RDS administrator to have a look into that. Will get back

      Delete
  5. Hello Tom!
    In your scenario, is RDWEB still uses FBA after ADFS authentication?

    ReplyDelete
    Replies
    1. Yes. You'll still need to login to RDWeb using the standard method, WAP in Server 2012 R2 does not support any kind of SSO pass through to RDWeb. That feature might be available in WAP 2.0 with Server 2016.

      Delete
    2. But strange thing which I have tested is, If we publish backend RDS as non claim aware application, SSO between WAP to RDWeb works but when we try to launch any application, it prompts for credentials once again and does not accept even if we use same credentials.

      Delete
  6. Hi Tom,

    Thanks for the very helpful guide. I've published RDWeb using WAP with ADFS pre auth and integrated multi-factor auth. This works well however I now have the problem in that I can't use the "connect to a remote PC" function in RDWeb because of the pre-auth requirement I assume. My users have to connect to the RD Session Host and from there RDP to their PC. Do you know of a workaround to this problem?

    Also, has anyone been able to get SSO working on RDWeb to avoid the double sign in? I know you said it's not supported but hoping someone might have a solution.

    thanks.

    ReplyDelete
    Replies
    1. Hi John - check out the section above "Modifying Desktops.aspx" - that has instructions for modifying the "Connect to a remote PC" page to work with the pre-authentication.

      For your SSO question, Microsoft finally released their official guide for setting up RDG behind WAP - https://technet.microsoft.com/en-us/library/Dn765486.aspx - here is their explanation for SSO not working:

      "Authentication to the RD Web Access server will still use the RD Web Access form logon. This provides the least number of user authentication prompts as the RD Web Access logon form creates a client-side credential store that can then be used by Remote Desktop Connection client (mstsc.exe) for any subsequent Remote App launch."

      Delete
    2. oops I completely missed that section. Thanks!

      Delete
  7. No, at now - SSO from RDWEB to RDP Session - not supported, actually ActiveX component get UserName and Password in plain text for authorisation on RDWEB logon page :) Waiting Windows 10, Server 10 and update in RDWeb :(

    ReplyDelete
  8. Thank you for writing this article. It has cleared up alot of confusions! I have to say Citrix Netscaler seemed to have had all this figured out a long long time ago (in there own way of course).. but due to budget constraints this worked perfectly for our needs.

    ReplyDelete
    Replies
    1. Thanks, I'm glad others are finding this useful. :)

      Delete
  9. Excellent article thank you! I am about to setup RDGateway in the DMZ using WAP and ADFS just as you have demonstrated. The only concern is that the existing WAP cluster servers are in a workgroup. I hope I can still publish the RDGateway using the ADFS relay party. If you have any new info on how to accomplish this, please share.

    ReplyDelete
    Replies
    1. I didn't try with the WAP servers in a workgroup. I know it did not work when the WAP servers were in a different untrusted domain though, so maybe you'll have better luck in a workgroup scenario.

      Delete
    2. Hi. Our WAP servers are also in DMZ. I have tried to get this work but RemoteApps do not start. Looks like ADFS authentication works and i can also logon to RD Web Access but when trying to start RemoteApp, Remote Desktop cannot connect to remotemachine. Reasons are your user account is not contained in RDG user list or remote machines computer name is in NetBIOS format. Is this expected behaviour when WAP-machines are not domain connected?

      Delete
  10. Thanks for this beautifully written article.
    We've managed to get this working now but only through IE. I understand the point of this is to explicitly prevent using saved RDP files. Using other browsers like Chrome and Firefox downloads the RDP file which obviously doesn't run. Does this mean that we are limited to using only browsers that support ActiveX (i.e. Internet Explorer)? Or have I missed something?

    ReplyDelete
    Replies
    1. You are correct in that only Internet Explorer will support this method. The RDP ActiveX control within IE handles passing the authentication cookie between the browser and mstsc.exe. Other browsers don't support ActiveX, and thus won't work. It'd be nice in the future if Microsoft would remove the requirement of ActiveX and instead find a way to replicate this functionality using HTML5 for cross-browser support.

      Delete
  11. Hi Tom,

    Thanks for the rare find regarding this info. It seems like ADFS 3.0 and WAP are not that often written about - I have come across more ADFS 2 and ADFS 4 preview articles than ADFS 3. I am struggling with making my way through ADFS and WAP with regard to publishing a simple internal hello world website. Are you aware of any other resources for publishing a non-claims-aware site? It seems the only examples I can find are sharepoint and OWA, but those are so Microsoft-richly-integrated that I dont know that the concepts are even the same for non-claims-aware relying party trust.

    Thanks,

    Brian

    ReplyDelete
  12. This posting was a great life saver. I really appreciate you taking the time to provide your documentation. I have a question regarding ADFS to RDWeb though. Is it possible to "Auto-fill" the username and/or password fields after authenticating from ADFS? I know that the end user is required to ALSO authenticate the RDWeb page, but is it possible to make it easier by auto populating the required fields?

    ReplyDelete
    Replies
    1. Not that I know of, but that would be convenient. Supposedly in Server 2016, there will be further integration between WAP and RDWeb that will allow single-sign on between the two.

      Delete
  13. Thanks Tom for that great post!

    In our scenario, RDWeb and RDGateway are hosted on different servers with different host names. How would the WAP and ADFS configuration need to be adjusted to cope with that setup?

    In the post you noted to "Enter the external URL that users will use to access your RD Gateway/RD Web Access installations" and to use the same name for the backend URL. That's working, when RD Gateway and RD Web Access are sitting on the same internal host. How to do this if they are on separate servers?

    ReplyDelete
  14. Hi Tom,
    I was wondering about the Hotfix KB2982037. This site is not available anymore. Is it still required or is this fix included in never updates?

    ReplyDelete
    Replies
    1. Hi Peter. I'm not having issues getting to the KB article for 2982037. It appears Microsoft has included that hotfix with the 2975719 hotfix rollup - https://support.microsoft.com/en-us/kb/2975719

      Delete
  15. Thank you very much Tom. I will continue my configuration. Your post is awesome.

    ReplyDelete
  16. Thank you very much for this great post.
    Just adding that it works very well too if you select "Pass-through" under "Specify the preauthentication method" TAB. This way ADFS login page can be skipped and you can directly access RD Web login page.

    Only backdoor that I see is it allows direct connections to back-end resources when specifying GW settings in MSTSC but that can also be managed by limiting "RD Gateway-managed group members" in Resource Authorization Policies to RDSCB and RDSH servers for which access can be further controlled by applying server level restrictions.

    Cheers,

    ReplyDelete
  17. I'm confused, should this work in Chrome/Firefox/etc? Because in those browsers it just downloads a .rdp file. And i'm not sure how opening that would "retrieve the ADFS edge token from the browser".

    ReplyDelete
    Replies
    1. Saw the other comment, disregard this.

      Delete
  18. I have followed this guide step by step but am still encountering an issue. I can pre-auth to rdweb then login to rdweb and launch an application but the application says failed login in every time and i cant get passed it. i dont think it is passing the cookie correctly to the gateway for auth. No matter what creds i enter they are never accepted. Any ideas?

    ReplyDelete
  19. Hi Tom,
    Great Article much appreciated, I have tried this a couple of times now and just cant get this working. Could I ask for some of your experience.

    Internally the RDS works fine.
    Externally the WAP server constantly attempts to service the RDS session.

    To explain further..
    - I browse to https://rdp.service.com
    - I get PreAuth'd by the ADFS portal
    - I login to RDWeb
    - Select my App, the popup is showing the SSL certificate is the 3rdParty SAN cert in my RDS server
    - I then get another RDP popup showing the selfsigned certificate of my WAP server.

    If you have any suggestions I would be very greatful, as I've been banging my head against this for a week!

    Many Thanks

    ReplyDelete
  20. Hi Tom,

    Followed your guide, got everything working sweet... except: the clipboard redirection ONLY works when the client is able to 'Bypass RD Gateway for local address'.

    The only deviation from your guide is that my WAPs are in a DMZ AD forest and my ADFS and RD* servers in an internal AD forest. There is a one way trust between the forests.

    You mentioned that you could only get things working properly when all the servers are in the same AD domain. Was one of the things that failed to work correctly the clipboard redirection?

    I can't for the life of me find any relevant info on the internet.

    Trautie

    ReplyDelete
    Replies
    1. My implementation had clipboard redirection explicitly disabled for security reasons, so I'm unable to comment.

      Delete
  21. Hello,

    I don't like the setup where you will authenticate ADFS, then WEB and then RDP GW. I create non-claim aware party trust, set KCD to SPN for the server hosting RDWEB and Gateway, reconfigure IIS from form authentication to windows integrated auth.

    Result:
    WAP -> adfs -> SSO to RDWEB: working great. THen you need to enter credentials when running rdp file.

    In my setup I am using everything HA. I reconfigure RDWEB to be running under service account (IIS app pool - instead of AppPoolIdentity, set permissions for the service account, policy for the account [logon as batch, ...]). Of course - update SPN to the service accoutn.

    problem:
    - internal NW: all working fine
    - external NW: error 401

    2nd try:
    update with service account as well RPC / RPC with cert
    - internal NW: all working fine
    - external NW: too many redirects

    on the WAP server are just some unclear errors in Event log.

    Did you or someone try to setup RDWEB / GW under service account behind WAP?

    ReplyDelete
    Replies
    1. No I don't believe I tried this configuration

      Delete
    2. Hi, yes we have. Since we need high available rdweb we setup non-claims trust, and we also tried to make the rdweb application pool run as a user and put the SPN on the user. But havent got it working.. Seems no one has done it with nonclaims and loadbalancing rdweb...

      Delete
    3. Did anyone manage to get this working when the Gateway servers are load balanced? I have built a lab in Azure with an Azure internal Load balancer for the gateway. Seems hit and miss the logins

      Delete
  22. Does anyone knows if there were any improvements in RDS 2016 and WAP?

    ReplyDelete
  23. Hi,

    Thanks for this guide it's brilliant. Question though I have users that use the rd client for iPad and iPhone and when I setup are rd remote app with adfs the client stops working. Do you know if the client supports this? Or is there extra config needed.

    Mark

    ReplyDelete
    Replies
    1. I do not believe this configuration will support iOS devices. WAP sends the token to RD Gateway via an ActiveX control, which isn't going to work w/ iOS.

      Delete
  24. Hi,

    Is there anyone here who has overcome the credentials popup when launching a remote app or a remote desktop on the RDWeb page?
    I also have SSO to RDWeb through ADFS without the use of WAP.

    Arnaud

    ReplyDelete
  25. This is truly a decent and useful, containing all data furthermore greatly affects the new innovation. A debt of gratitude is in order for sharing it  VPN to Unblock British TV

    ReplyDelete
  26. The blog is sensationally wonderful. Simply cherish the way how all the written work has been put.
    wordpress website

    ReplyDelete