There are 3 (relatively) new functions in Azure AD Domain Services. Both in preview at the time of writing but combining all can unlock new functionality.
This post will go over the following items with regards to Azure AD – Domain Services
- What’s new in Azure AD – Domain Services
- Force trust creation with AAD-DS/ADDS to a specific site (/DC’s)
- Client side
- Custom SPN registration
The first one is the one everyone has been waiting for, External trusts. In short, AAD-DS spins up a new forest/domain with a new domain name. It synchronizes the users in AAD to your AAD-DS instance. If your users are only ‘cloud’ users, you can login with these users to AAD-DS and enable applications to support LDAP/Kerberos/NTLM authentications. However, when you synchronize your on-premises users to AAD and then to AAD-DS, the UPN for all your users in AAD-DS will match the UPN in your on-premises AD.
Now, while it might look like the users in all three identity stores are the same, they each are unique objects in their own identity systems. That means, the security identifier and objects ID’s are unique in each system, and in order to provide Kerberos logins between the two (or more) forests, you will need to have a (forest) trust in place.
However, while forestroot.local would be able to setup a trust with aadds.azureinfra.com, the users UPN’s are the same and as a result they will not authenticate over that trust if a user tries to login with their UPN.
a user with UPN firstname.lastname@example.org exists in ADDS (“on-premises” Active Directory Domain Services) and is replicated to AAD and then replicated to AAD-DS
When the user now tries to login to a resource linked to the AAD-DS domain, the domain will try to authenticate the user locally and not over the trust. So, it doesn’t make sense to use a trust in this scenario.
As such, the trust scenario usually only made sense if you had another forest / domain you wanted to provide access to based on a trust rather than synchronizing all those users as well. But what if you did need the AAD-DS for some reason with your users, but do not want to synchronize all your users to the AAD-DS forest (because perhaps it’s managed by another team). I already blogged about partial password replication earlier, but now, preview feature 2 is there as well. You can specify a group of users that need to be synchronized to AAD-DS and filter everyone else out.
But say, you don’t want any users of your local ADDS in Azure AD – Domain Services…
Which is where preview option 3 comes into play. You can now create a “resource” based AAD-DS implementation. It will still spin-up a new AAD-DS service, but the synchronization is limited to “cloud” only accounts. This means your local users synchronized to AAD will not show up in AAD-DS. But your ADDS users can now authenticate over a (forest) trust to resources in the AAD-DS domain:
Hint: after deploying an AAD-DS, reset the password for the AAD-DC Admin account to generate a new password).
And this opens a whole new set of questions: Which domain controller will the AAD-DS trust use? How can we control authentication traffic, what type of architectures are now possible? To start with the last one, it will now be possible to still authenticate your own users on-premises to services hosted in the cloud, but more importantly, you can make those services available to all your users in different domains/forests, without replicating their accounts:
Forcing Trust Creation to a specific ADDS Site / DC’s
Given the option for creating a trust is provided, the question is now, what if I want that trust to only hit a specific region for my ADDS (or in other terms, what if I don’t want to open all firewalls to each DC for this trust to work?). In an earlier post I already talked about creating trusts and forcing them to a specific site. This is no different, except we are restricted in what we can do in AAD-DS:
The AAD-DS forest is setup with a “Default-First-Site-Name” architecture. This means that all computers joined to the AAD-DS domain will also fall in that same site by default. Given the restricted permissions there is no way to change the name and thus, if we want to control the trust, we need to make appropriate measures on the ADDS side.
In order to have the AAD-DS talk to specific domain controllers, we have to use the same site name, and given I always remove the “Default-First-Site-Name” I had to recreate the Default-First-Site-Name and made it an empty site covered by one of my actual sites, which can be done by setting up a separate Site-Link as you can in this Microsoft Blogpost:
(In order to make the new site “active” in DNS, make sure to restart the NETLOGON service on the site covering domain controllers, this will force the registration of the new site (and DC Locator records) in DNS)
As you can see in the image above, the Default-First-Site-Name _LDAP and _kerberos records are pointing to the DCDXBDC01 domain controller, which is actually in site Home, this is automatic Site Coverage at work.
Creating the trust
So, after deploying the Azure AD – Domain Services instance (make sure the forest/domain name is not equal to the on-premises domain name), go to your on-premises ADDS and go to DNS. Our ADDS needs to be able to resolve the AAD-DS domain name and therefore a forwarder needs to be created in the local DNS server. This forwarder can be replicated to all DNS servers in the domain if needed.
Next is the creation of the trust on the ADDS side, open Active Directory Domains & Trusts and create a new incoming trust. Unfortunately, there is only an incoming trust possible where AAD-DS trusts the ADDS domain. So, right click the domain name, select the trusts tab and select New Trust… then type the name of the AAD-DS domain name and click next. Then select a Forest Trust and create a One Way: incoming trust – in this domain only and type a password. Do not confirm the trust as we still need to create the other side as well.
Then in Azure on the AAD-DS page, select Trusts and provide the information required.
After clicking save, Azure will add the 2 DNS servers to the AAD-DS domain as forwarders for the forestroot.local domain and configure an external trust for the domain as well. If all is well, a trust is established. But what happened to our site-specific configuration?
Tracing the trust
When we look at the Wireshark trace on our domain controller in our “home” site, we see the following interesting packets:
As you can see, the initial query is an A query to the DNS server. This is just to confirm that the DNS servers provided in the “Add Trust” window in Azure are actually responding. If they don’t the Trust creation is going to fail.
Next, the AAD-DS server performs a site specific query to:
And, since we pre-created that site, and had it covered by our “home” domain controller(s), it will actually respond with the correct DC:
172.16.5.20 172.16.75.4 DNS 267 Standard query response 0x39ab SRV _ldap._tcp.Default-First-Site-Name._sites.gc._msdcs.forestroot.local SRV 0 100 3268 DCDXBDATADC02.FORESTROOT.local SRV 0 100 3268 DCDXBDC01.FORESTROOT.local A 172.16.5.21 A 172.16.5.20 OPT
Followed by the actual trust being established:
Note that in this case, my PDC (Emulator) is actually not resolvable for the AAD-DS instance, the trust is created solely through a regular Domain Controller in the “Home” site.
Client Perspective on the trust
Connecting from Azure AD-Domain Joined machines to a local ADDS based machine will not incur the trust. It is only one-way and an NTLM challenge will be the result (and you must provide an ADDS username/password). But you can connect with your ADDS machine to an AAD-DS based service with your (on-premises) ADDS account. As your machine is not in the “Default-First-Site-Name” site, it will use the global DC Locator records to determine the DC. Given there are only 2 Domain Controllers provisioned and there is not a very extensive site setup, this doesn’t really matter (at least until the Azure team makes ADD-DS Geo-Redundant; if ever). If you want to make Kerberos work, your clients will need to be able to find and connect to the AAD-DS domain controllers, if they can’t they will revert back to NTLM authentication.
Alternative SPN domain names
By default, the ADDS will be able to resolve the Kerberos Realm (and thus all related SPN’s) to the Azure AD-Domain Services instance and vice versa.
However, the UPN routing suffix for all my other UPN’s (in my ADDS) will not be enabled, and cannot be enabled due to permissions errors. While the SPN’s in FORESTROOT.local do not really matter for this trust (not sure on PAC validation however), the fact that we cannot add UPN sufiixes to the AAD-DS forest has a bigger impact.
As the ability to add UPN’s is blocked there is an impact to the SPN’s we can register in AAD-DS with regards to the systems in there, and the ones that are actually resolvable. Take the following example: I have a webserver in AAD-DS, which if I connect to it using it’s default name (hostname + AAD-DS DNS FQDN) will allow “trusted” users to connect using Kerberos:
However, when I configure an SPN on this account in AAD-DS to match a more friendly name, suddenly the system will revert to NTLM (v2) and not provide any Kerberos authentication as the SPN suffix is not routable over the trust, given the routable suffixes are managed by AAD-DS and we don’t have access to change them. So, Kerberos using custom SPN’s over this external trust will not work:
Use custom SPN’s that match the AAD-DS domain name, and you are good to perform cross-trust Kerberos Authentication (app.mydomain.com doesn’t work, app.aadds.azureinfra.com does work). In a “resource” based AAD the custom domain names aren’t even added to the AADDS instance and therefore even adding a custom domain name in AAD will not solve this problem.
So in short, if you run AAD-DS in “Resource” mode and you want to use Kerberos over the external trust, make sure to keep using your AAD-DS instance FQDN for the SPN’s or use Kerberos Constraint Delegation with Protocol Transition on a proxy server that will allow you to perform NTLM->Kerberos transitions.