Use Azure Active Directory Domain Services with Linux machines from another Virtual Network

This week I was asked if it was possible to configure RHEL machines in an Amazon VPC to use Azure Active Directory Domain Services (AAD DS).  Whilst I don’t have access to an Amazon VPC I can create multiple Virtual Networks and link them via VPN to replicate the set up.

Just a note on the format of this post – it isn’t a “Walkthrough”, the documentation set for AAD DS is very good – here I am expanding on a specific scenario not called out and supplementing as necessary.

Er what is AAD DS exactly?

So let’s take a quick moment to cover what Azure Active Directory Domain Services is.  AADS enables you to deploy a managed highly available set of domain services to your machines.  The attraction here is that you can provide delegated domain services without the need to manage additional Domain Controllers or cede control of your primary domain.

In this example we will enable CentOs machines in a remote network to join a child domain (cloud.egcomp.co.uk) hosted by AAD DS, users from the primary domain (egcomp.co.uk) will be able to log on to the CentOs boxes.  Only assigned (centrally managed) users gain admin rights over the boxes.

A much better and fuller description is available on the doc center: Azure Active Directory Domain Services Overview

Welcome to Eg Comp

To support my varied tests I have two example organisations I use – egcomp.co.uk for a more traditional “hybrid” set of requirements and egunicorn.co.uk for “cloud native” organisations.  In this example we use Eg Comp which has an on-premises Active Directory sync’d to an Azure Active Directory using AD Connect.  We have for this use case had to enable Password hash sync – this is called out in the overview article mentioned above and makes sense else AAD DS wouldn’t be able to authenticate any users!

If you did not enable password sync on your AD Connect configuration orginally you can enable it following these instructions (I had to) here

My very simplified picture of the set up is below:

So we can see here that I have configured a Classic Virtual Network to host the AAD DS service, and as per the documentation I have created a dedicated subnet of 10.0.0.0/24 to host the servers.

Pre-reqs

You will need to create a Classic Virtual Network (vNet) with a dedicated Subnet to host the AAD DS service, the good news is that this can now be done in the new portal and instructions are here.

I am also assuming you are able to set up a Site-to-Site VPN between your classic vNet and your second Network wherever it may be.  Instructions for setting the VPN connection up on the classic side are available here, although it is now possible through the new portal as well (no docs available at the time of writing :().

Configure our administrators

The first step is to create a Security group that will contain the users who will be given administration access on the machines in the AAD DS machine.  Note this is not the same as Domain Admins.

For my scenario where I have an existing Active Directory I created the group AAD DC Administrators in my local Active Directory and placed my assigned users as members:

You will need to wait for the replication to run before the group and its membership appears in your AAD tenant.  As per the docs page the synchronisation occurs every 30 minutes by default, it does include this snippet though:

It could be that you have an urgent change which must be synchronized immediately which is why you need to manually run a cycle. If you need to manually run a cycle, then from PowerShell run Start-ADSyncSyncCycle -PolicyType Delta.

We can see my group has sync’d below:

With its one user:

If you don’t have a hybrid configuration you can create the Security Group in your Azure Active Directory (AAD) tenant as per the instructions here.

Deploy our AAD DS instance

As noted in the pre-reqs I am assuming at this point you already have a pre-provisioned Classic vNet with a dedicated subnet to deploy the AAD DS to.  The steps listed on the documentation page here give an excellent overview of what’s needed and I don’t propose to recreate them here, rather I thought it would be useful to work through the implications.

As noted earlier EG Comp has an existing on-premises Active Directory this is corp.egcomp.co.uk and this is sync’d via AD Connect to an Azure Active Directory tenant.  In this scenario there is a desire for projects to be able to spin up workloads in the cloud, however, as per standards users must be Active Directory owned identities.  There is no particular desire to spin up and manage further Domain Controllers in each target cloud provider which would also add a bottleneck in terms of planning and deployment.  In fact pretty much scenario 1 in the DS scenario outlines here.

In practice for my example this meant the creation of a new domain: cloud.egcomp.co.uk.  Users from corp.egcomp.co.uk can access machines in the machines in cloud.egcomp.co.uk and members of the group AAD DC Administrators can administer all machines joined to cloud.egcomp.co.uk, as well as the slimmed down group policies available and DNS.  If you’re following the documentation listed at the top of this step you’ll note it says you can type in your own domain name which is what I did.  You can see this in the screenshot below as well as the IPs of the servers (we’ll need these later when we look at how to join a machine without DNS).

It takes a little while to deploy the AAD DS infrastructure so start it off and then its time to start provisioning the clients while we wait.

Domains and DNS

So those of you that remember the change from NT4 to Windows 2000 and Active Directory will remember finding out that suddenly DNS was very important.  As part of the deployment guidelines for AAD DS the last step of the Get started section is to update the DNS settings for your virtual network, this makes complete sense when your machines are all in the same virtual network or perhaps same cloud and peered – however, if your domain joined machines are in another cloud or connected via a VPN this is not ideal as it means all your name resolution would be dependent on that VPN link and be affected by the speed of that link.

In this specific scenario the domain joined clients are in a seperate cloud linked by a VPN, we have some options for deployment at this point:

  1. In the remote virtual network only set domain joined VMs to use the AAD DS servers as their name servers
  2. In the remote virtual network set all machines to use the AAD DS servers as their name servers
  3. Create replicas of the AAD DS DNS zones in the remote network (haven’t tested this one) on the existing local DNS servers
  4. Don’t use DNS

In exploring this scenario I have tested items 1 & 4 and have outlined the approaches below.

 

Join the Domain option 1

On the face of it option 1 of only changing the DNS settings for machine that need domain access is attractive because it reduces the number of machines potentially affected.  However, it does of course that you potentially have different machines using different DNS servers which Operationally could be tough.  For getting my PoC up and running and supporting 1 box it was all good, whether this is the right solution for you will depend on your individual context.  That said let’s look at what I had to do.

I used CentOs as my distro for these tests and changing the DNS server is nice and easy a quick edit of the resolv.conf file:

sudo vi /etc/reslov.conf

As you can see from the above screenshot I have set the DNS servers for this box to be the IPs listed on the AAD DS config page.  The good news is that you can now follow the instructions laid out in the excellent How to Join a Linux VM guide.  However, there is a catch 🙂  We need to make one more small change before we reboot the machine, else the start up script will override our DNS servers with those specified in the DHCP scope!  For this on my CentOs box I needed to run:

sudo vi /etc/sysconfig/network-scripts/ifcfg-eth0

As you can see from the above screenshot I set the PEERDNS equal to no this will stop the DHCP client overwriting your changes to resolv.conf

That’s it when you follow the How to your on-premises users can log on so in my case it is user@corp.egcomp.co.uk – not cloud.egcomp.co.uk.  Note your kinit step also uses the @corp.egcomp.co.uk – in my case ompremuser@corp.egcomp.co.uk.  

There is a potential gotcha – if you provisioned your machine to only let you log on via certificate see the SSD section later in this doc to enable your users to log on with their credentials.

Join the Domain option 4 (No DNS)

So as I reflected on the high of getting my CentOs boxed joined to the domain across the VPN I reflected that I really didn’t like having to set all the DNS traffic to go over that link, I spent some time thinking about configuring a DNS replica but I wanted to understand if it was possible to roll out the configuration via files which neatly cuts out the whole messing with the DNS settings piece.

What we have to do here is lay the groundwork so that the instructions in the excellent How to Join a Linux VM will work.  You will need to complete the Install required packages on the Linux virtual machine step then we take a short detour.  Under the hood there is a file called krb5.conf (in my CentOs box) which enables you to define your Kerberos realms.  Where DNS is not working this is where the realm information comes from.  Before we edit krb5.conf we first need to (or at least should) put some entries in the hosts file.  This will enable the client to be able to find the AAD DS servers by a name rather than an IP address.  Is this step strictly needed?  Probably not, but I personally really hate IPs in config files!

So first things first:

sudo vi /etc/hosts

As you can see from the above I have created entries here pointing to the IP addresses shown in the AAD DS config, I have given them nice names of kdc1 and kdc2 (in reality they have more complex ones!), I have also added entries for the domain and its short name.  With those in place I can edit the kerberos file:

sudo vi /etc/krb5.conf

OK here we can see that I have added entries for my AAD DS domain (realm in this context) CLOUD.EGCOMP.CO.UK (I have no idea why its caps, I’m not a Linux chap but I followed the helpful example in the file!).  Once this is in place you should be able to continue following the How to guide Join the Linux virtual machine to the managed domain.

I ran this test a couple of times and once I saw an error around adcli, if you come across this simply run the following command to grab the missing package:

sudo yum install adcli

As noted in the section for Option 1 there are pros and cons, a big con on this method is that if you want machines to be able to find each other both sides of the VPN there is no common DNS so that won’t work without setting up a replica anyway or managing a bunch of hosts entries.  If you don’t have anything on the other side you want to talk to this may be a good solution, again what’s the correct solution will depend on your context.  If I get time I will investigate if you can set up a replica DNS and everything still works.

SSH won’t let me in!

In my case when I deployed my CentOs images I configured them to let me log in via certificate, I was very proud of myself at this point.  However, I found that I couldn’t log in with my AD users as they needed username / password.  It was time to learn about another new config file!

sudo vi /etc/ssh/sshd_config

OK so the config file for the SSH service (Daemon) is pretty lengthy I simply searched (in vi use “/” to search) for PasswordAuth and then in the relevant section enabled it via the following line:

PasswordAuthentication yes

Rounding Up

OK so what we’ve done in this rather lengthy post is look at how we could achieve joining Linux virtual machines to an Azure Active Directory Domain Services managed domain, this was my first play with AAD DS and I must say it was a breeze and the documentation really good.  As you probably spotted through the post I am by no means a Linux person, dusting off my limited vi skills and finding my way through the various config files was fun.  Through these experiments we have proven the capability, the best solution for your organisation will depend on your context.

Ian

 

No Comments

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.