Karim Elatov

Azure AD as an Identity Source for SecurID Access

Blog Post created by Karim Elatov Employee on Dec 21, 2016

I was playing around with Azure AD and SecurID Access. I was mostly looking over Configure Secure LDAP (LDAPS) for an Azure AD Domain Services managed domain and using the recommendations from that page, I was able to connect to Azure AD from a SecurID Access IDR. Here are the steps I took to use AzureAD as an identity source for SecurID Access.

Create an SSL Certificate for the LDAPS Connection

I ended up using the powershell approach as described in the above page. From the above page here are the requirements for the certficate:

Acquire a valid certificate per the following guidelines, before you enable secure LDAP. You encounter failures if you try to enable secure LDAP for your managed domain with an invalid/incorrect certificate.

  1. Trusted issuer - The certificate must be issued by an authority trusted by computers that need to connect to the domain using secure LDAP. This authority may be your organization's enterprise certification authority or a public certification authority trusted by these computers.
  2. Lifetime - The certificate must be valid for at least the next 3-6 months. Secure LDAP access to your managed domain is disrupted when the certificate expires.
  3. Subject name - The subject name on the certificate must be a wildcard for your managed domain. For instance, if your domain is named 'contoso100.com', the certificate's subject name must be '*.contoso100.com'. Set the DNS name (subject alternate name) to this wildcard name.
  4. Key usage - The certificate must be configured for the following uses - Digital signatures and key encipherment.
  5. Certificate purpose - The certificate must be valid for SSL server authentication.

 

Use Powershell to generate the Self Signed Cert

I followed the instructions and used powershell. On a windows 10 machine, I launched powershell as an administrator and ran the following:

PS C:\WINDOWS\system32> $lifetime=Get-Date
PS C:\WINDOWS\system32> New-SelfSignedCertificate -Subject *.ssotes.onmicrosoft.com -NotAfter $lifetime.AddDays(365) -KeyUsage DigitalSignature, KeyEncipherment -Type SSLServerAuthentication -DnsName *.ssotes.onmicrosoft.com
 
   PSParentPath: Microsoft.PowerShell.Security\Certificate::LocalMachine\MY
Thumbprint                                Subject
----------                                -------
DBFA9C7175D47188565D1F145F29505B202D7855  CN=*.ssotes.onmicrosoft.com

Then I followed the instructions laid out in Configure Secure LDAP (LDAPS) for an Azure AD Domain Services managed domain to export the cert. Here are the contents of the cert as seen with the openssl utility:

<> openssl x509 -text -noout -in wild-ssotes-win.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            59:9d:16:fd:58:83:5b:a9:4a:79:8d:20:7e:b9:52:d5
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=*.ssotes.onmicrosoft.com
        Validity
            Not Before: Dec 14 23:41:58 2016 GMT
            Not After : Dec 14 23:51:55 2017 GMT
        Subject: CN=*.ssotes.onmicrosoft.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Client Authentication, TLS Web Server Authentication
            X509v3 Subject Alternative Name:
                DNS:*.ssotes.onmicrosoft.com
            X509v3 Subject Key Identifier:
                CB:B6:D7:97:B1:2B:60:CB:CE:6F:5C:A6:1B:07:B9:E6:25:9F:20:94
    Signature Algorithm: sha256WithRSAEncryption

Save the pfx file and keep the export password since we will need it when we upload it to the Azure Portal. Just for reference here is openssl command I used to extract the PEM file from the PFX file:

$ openssl pkcs12 -in wild-ssotes-win.pfx -clcerts -nokeys -out wild-ssotes-win.pem
Enter Import Password:
MAC verified OK

Now let's move on to the Azure network configuration.

Create a Virtual Network and Subnet

Most of the networking recommendations are covered in Networking considerations for Azure AD Domain Services, here are the recommendations:

Type of Azure virtual network

  • You can enable Azure AD Domain Services in a classic Azure virtual network.
  • Azure AD Domain Services cannot be enabled in virtual networks created using Azure Resource Manager.

Azure region for the virtual network

  • Your Azure AD Domain Services managed domain is deployed in the same Azure region as the virtual network you choose to enable the service in.
  • Select a virtual network in an Azure region supported by Azure AD Domain Services.
  • See the Azure services by region page to know the Azure regions in which Azure AD Domain Services is available.

Best practices for choosing a subnet

  • Deploy Azure AD Domain Services to a separate dedicated subnet within your Azure virtual network.
  • Do not apply NSGs to the dedicated subnet for your managed domain. If you must apply NSGs to the dedicated subnet, ensure you do not block the ports required to service and manage your domain.
  • Do not overly restrict the number of IP addresses available within the dedicated subnet for your managed domain. This restriction prevents the service from making two domain controllers available for your managed domain.
  • Do not enable Azure AD Domain Services in the gateway subnet of your virtual network.

Network connection options

  • VNet-to-VNet connections using site-to-site VPN connections: Connecting a virtual network to another virtual network (VNet-to-VNet) is similar to connecting a virtual network to an on-premises site location. Both connectivity types use a VPN gateway to provide a secure tunnel using IPsec/IKE.

In summary I created a virtual network with the following characteristics:

  1. In the US East Region where Azure AD Services are supported

     
  2. Brand new dedicated network (didn't reuse any of the existing networks)
  3. I didn't configure a VPN to the network but it sounds like that's supported (and might be a good approach if the IDRs are on premise)

Here is a step by step page that describes the process: Create or select a virtual network for Azure AD Domain Services. So using an account with a valid Azure Subscription login to the Classic Azure Portal (https://manage.windowsazure.com) and go to the Networks Application, then click the + sign, and choose Quick Create to create a virtual network:

Then give it a name and assign a local address range:

After it's done creating the network you will see the following message:

Create a Network Security Group (NSG) for AD Access

As per Networking considerations for Azure AD Domain Services, it's not recommend to apply NSGs to the Subnet, but I couldn't get it to work without them. Here is a list of Ports they recommend for the Subnet which is used for Azure AD Domain Services :

Ports required for Azure AD Domain Services

The following ports are required for Azure AD Domain Services to service and maintain your managed domain. Ensure that these ports are not blocked for the subnet in which you have enabled your managed domain. 

Port number
Purpose
443Synchronization with your Azure AD tenant
3389Management of your domain
5986Management of your domain
636Secure LDAP (LDAPS) access to your managed domain

 

The new Azure Portal (https://portal.azure.com) allows you to create Network Security Groups through the UI so let's do that. After you've logged in, launch the Network Security Groups (Classic) application:

Then click add and name the Network Security Group:

I didn't create a new Resource Group I just used the Default-Networking Resource Group, which is where my Subnet ended  up in (if you go to Virtual Networks (Classic) -> AzureAD-VirtualNetwork you can see what Resource Group a Virtual Network belongs to) :

After the NSG is created, you will see the following:

If you select the NSG and go to it's Inbound Rules you can see the default rules:

You can then click Add and another pane will show up where you can add the port that you want to allow:

And after it's added you will see it on the list:

Repeat the process for the other ports: 443, 3389, 5986. Next, we need to assign this NSG to our Subnet. So launch the Virtual Networks (classic) application:

Then select the Virtual Network that you created and then select the Subnets Section:

 

Then change the Network Security Group from None to the NSG that we created:

Then click Save and after it's finished you will see the following in the notification section:

 

That should be it for the networking configuration.

Configure the Active Directory Service in Azure

In the classic Azure portal, if you navigate to Active Directory you will see your directories (I created a brand new one for testing purposes, but you will probably have one created). Select your Directory and go to the Configure section:

 

Then scroll down and enable Domain Services:

After you enable it, you can assign it to the dedicated network that you created above:

After it's done enabling Domain Services, you will now see the button to enable Secure LDAP (LDAPS):

Click Configure certificate and you will see the upload dialog:

Then point to the pfx file that you create in the first section and enter the password as well:

After the upload is finished you should see the following under the Certificate Section:

 

And the following under the notifications:

Lastly after the certificate is uploaded you will have an option to enable LDAPS access from a public IP:

So switch the Enable Secure LDAP Access Over the Internet option to YES and click Save:

After it's enabled you should see the Public IP that is assigned to the Azure AD instance:

For good measure I also added IPs from which I knew the IDRs would be connecting to this Azure AD instance. So under the your organization's public ip address ranges section I clicked Add Known IP Address Ranges and specified the IPs:

Create a test Admin User

The Get started with Azure AD Domain Services has section about creating an admin group:

The first task is to create an administrative group in your Azure Active Directory tenant. This special administrative group is called AAD DC Administrators. Members of this group are granted administrative privileges on machines that are domain-joined to the Azure AD Domain Services managed domain. On domain-joined machines, this group is added to the ‘Administrators’ group. Additionally, members of this group can use Remote Desktop to connect remotely to domain-joined machines.

So let's first create an admin so we can use that to bind with. In the Azure Management Console go to Directory Service -> You AD -> Users -> Add User:

Then fill out all the information and assign it the Service Admin Role:

 

Next let's create the suggested group, Directory Service -> You AD -> Groups -> Add Group:

Then you will see the Group listed:

Then select the Group and click on Add Members and add the admin user to the group:

 

Create a test User

Since I was not using Azure AD Connect (to synchronize users to AzureAD), I also created a regular user as well. Same process as the admin except for the role, I selected User:

I also created a test group called ssousers and I selected O365 Preview as the Group Type:

And I made my test user part of that group:

Add a User to Azure AD with the AzureAD Powershell

You can also add a user using Azure AD Powershell. I logged in with the admin@ssotes.onmicrosoft.com user and first I was able to query the existing users:

PS C:\Users\elatov\Desktop> $cred=Get-Credential
cmdlet Get-Credential at command pipeline position 1
Supply values for the following parameters:
Credential
PS C:\Users\elatov\Desktop> Connect-MsolService -Credential $cred
PS C:\Users\elatov\Desktop> Get-MsolUser
UserPrincipalName                                                    DisplayName  isLicensed
-----------------                                                    -----------  ----------
admin@ssotes.onmicrosoft.com                                         Admin User   False
test@ssotes.onmicrosoft.com                                          Test User    False
PS C:\Users\elatov\Desktop> Get-Msoluser -UserPrincipalName test@ssotes.onmicrosoft.com | fl
 
ExtensionData                          : System.Runtime.Serialization.ExtensionDataObject
AlternateEmailAddresses                : {test@ssotes.onmicrosoft.com}
AlternateMobilePhones                  : {}
AlternativeSecurityIds                 : {}
BlockCredential                        : False
City                                   :
CloudExchangeRecipientDisplayType      :
Country                                :
Department                             :
DirSyncProvisioningErrors              : {}
DisplayName                            : Test User
Errors                                 :
Fax                                    :
FirstName                              : Test
ImmutableId                            :
IndirectLicenseErrors                  : {}
IsBlackberryUser                       : False
IsLicensed                             : False
LastDirSyncTime                        :
LastName                               : User
LastPasswordChangeTimestamp            : 12/15/2016 12:13:23 AM
LicenseReconciliationNeeded            : False
Licenses                               : {}
LiveId                                 : 10037FFE9CEDDFA4
MSExchRecipientTypeDetails             :
MobilePhone                            :
ObjectId                               : c56f4960-1f5a-4cc6-8c08-d6f01b20fd59
Office                                 :
OverallProvisioningStatus              : None
PasswordNeverExpires                   : False
PasswordResetNotRequiredDuringActivate :
PhoneNumber                            :
PortalSettings                         :
PostalCode                             :
PreferredLanguage                      :
ProxyAddresses                         : {}
ServiceInformation                     : {}
SignInName                             : test@ssotes.onmicrosoft.com
SoftDeletionTimestamp                  :
State                                  :
StreetAddress                          :
StrongAuthenticationMethods            : {}
StrongAuthenticationPhoneAppDetails    : {}
StrongAuthenticationProofupTime        :
StrongAuthenticationRequirements       : {}
StrongAuthenticationUserDetails        : Microsoft.Online.Administration.StrongAuthenticationUserDetails
StrongPasswordRequired                 : True
StsRefreshTokensValidFrom              : 12/15/2016 12:13:23 AM
Title                                  :
UsageLocation                          :
UserLandingPageIdentifierForO365Shell  :
UserPrincipalName                      : test@ssotes.onmicrosoft.com
UserThemeIdentifierForO365Shell        :
UserType                               : Member
ValidationStatus                       : Healthy
WhenCreated                            : 12/15/2016 12:13:24 AM

To add a new user we can run the following command:

PS C:\Users\elatov\Desktop> New-MsolUser -userprincipalname "test2@ssotes.onmicrosoft.com" -lastname user -firstname azuretest -Displayname "azuretest user" -immutableID 49acbc85-68bb-4c16-a867-f837b7694sdfs
Password UserPrincipalName            DisplayName    isLicensed
-------- -----------------            -----------    ----------
Wudu1766 test2@ssotes.onmicrosoft.com azuretest user False

Confirm Connectivity to Azure AD

After the above is setup, I used a test Linux machine to query the Azure AD services with the ldapsearch command and it worked out:

<> LDAPTLS_REQCERT=never ldapsearch -D "admin@ssotes.onmicrosoft.com" -w Suto7302 -H ldaps://13.92.80.251 -b "dc=ssotes,dc=onmicrosoft,dc=com" -s sub -x "(userPrincipalName=test@ssotes.onmicrosoft.com)" givenName -LLL
dn: CN=Test User,OU=AADDC Users,DC=ssotes,DC=onmicrosoft,DC=com
givenName: Test

Notice that I'm using the Public IP address. If that doesn't work check out the Random Troubleshooting section of the post for some additional troubleshooting steps.

Add AzureAD as an Identity Source in SecurID Access

After I confirmed that the connectivity is okay with ldapsearch, I logged into SecurID Access Administration Console and added a new Identity Source with the following information:

Notice I made the Base DN the following: OU=AADDC Users,DC=ssotes,DC=onmicrosoft,DC=com. When adding a server, I add the following:

I ended up using a connection time out of 30 seconds, since that was recommended by Azure. From LDAP Authentication and Azure Multi-Factor Authentication Server:

Configure the LDAP timeout to 30-60 seconds so that there is time to validate the user’s credentials with the LDAP directory, perform the second-factor authentication, receive their response and then respond to the LDAP access request.

Since we are going through the internet to connect to this Identity Source, that's probably not a bad idea. But connecting to Azure AD using a Tunnel (From the On Premise Network to the Azure Virtual Network) is probably a better approach. Then I enabled SSL for the connection and uploaded the x509 base64 encoded PEM of the certificate that I created with powershell:

Then when I clicked Test Connection, I saw all the attributes:

 

Then going to the attribute section, I refreshed the attributes and it pulled all the attributes:

Then I saved the Identity Source and Published. After that I went to the portal and I was successfully able to login with the test user I created:

Set Up Identity Source Sync

Initially when I ran the sync, the sync worked, but I received warning about missing emails:


I also logged into the o365 portal (https://portal.office.com) which is another way of managing AzureAD users and I saw that since the user is unlicensed we are unable to set the mail attribute:

When a user has a valid O365 license (this is in another tenant) their email is allowed to be configured:

So to use StepUp we need:

  1. A Valid Azure Subscription (to login to the Azure Portal to configure the Azure AD Services)
  2. Valid O365 Licenses (so the mail attribute can be set and/or modified for the users in Azure AD)

From How Azure subscriptions are associated with Azure Active Directory:

Manage the directory for your Office 365 subscription in Azure

Let's say you signed up for Office 365 before you sign up for Azure. Now you want to manage the directory for the Office 365 subscription in the Azure classic portal. There are two ways to do this, depending on whether you have signed up for Azure or you have not. 

I do not have a subscription for Azure

In this case, just sign up for Azure using the same work or school account that you use to sign in to Office 365. Relevant information from the Office 365 account will be prepopulated in the Azure sign-up form. Your account will be assigned to the Service Administrator role of the subscription.

And from Manage the directory for your Office 365 subscription in Azure:

After you complete the Azure subscription, you can sign in to the Azure classic portal and access Azure services. Click the Active Directory extension to manage the same directory that authenticates your Office 365 users.

 

After getting a valid license and setting the email attribute for the users, the sync worked without issues: 

And under User Management you will find the synced users:

The web portal authentications still worked and step-up worked as well. 

Random Troubleshooting

Initially the public IP wasn't working for me, so I deployed a Linux VM in the same subnet as Azure AD and I ran some tests, first I ran an nmap just to make sure the server is listening on port 636:

azureuser@azure-ad-osuse:~> nmap -P0 192.168.0.4
Starting Nmap 6.47 ( http://nmap.org ) at 2016-12-15 19:35 UTC
Nmap scan report for ssotes.onmicrosoft.com (192.168.0.4)
Host is up (0.0012s latency).
Not shown: 980 filtered ports
PORT      STATE SERVICE
53/tcp    open  domain
88/tcp    open  kerberos-sec
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
443/tcp   open  https
445/tcp   open  microsoft-ds
464/tcp   open  kpasswd5
593/tcp   open  http-rpc-epmap
636/tcp   open  ldapssl
1801/tcp  open  msmq
2103/tcp  open  zephyr-clt
2105/tcp  open  eklogin
2107/tcp  open  msmq-mgmt
3268/tcp  open  globalcatLDAP
3269/tcp  open  globalcatLDAPssl
3389/tcp  open  ms-wbt-server
49154/tcp open  unknown
49155/tcp open  unknown
49157/tcp open  unknown
49158/tcp open  unknown
Nmap done: 1 IP address (1 host up) scanned in 4.07 seconds

Next, make sure the cert is presented from the AzureAD Service:

azureuser@azure-ad-osuse:~> openssl s_client -connect ssotes.onmicrosoft.com:636 -servername ssotes.onmicrosoft.com
CONNECTED(00000003)
depth=0 CN = *.ssotes.onmicrosoft.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = *.ssotes.onmicrosoft.com
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
 0 s:/CN=*.ssotes.onmicrosoft.com
   i:/CN=*.ssotes.onmicrosoft.com
---
Server certificate
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
subject=/CN=*.ssotes.onmicrosoft.com
issuer=/CN=*.ssotes.onmicrosoft.com
---
No client certificate CA names sent
---
SSL handshake has read 1411 bytes and written 502 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-SHA384
    Session-ID: BF3300009FEB139B8FF5BA4DC5752D554CD819B414D74818EF21AE7D81F0B4E4
    Session-ID-ctx:
    Master-Key: 66810E1EC2C6C4394F1A9E42BFD7497F1FC9CA977B2EACA9A143A20F7DB8263B
F94896020BF1B59554F3FFA065986D0A
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1481760017
    Timeout   : 300 (sec)
    Verify return code: 21 (unable to verify the first certificate)
---

I was also able to run ldapsearch queries from the test machine against the AzureAD instance:

$ LDAPTLS_REQCERT=never ldapsearch -D "admin@ssotes.onmicrosoft.com -w Suto7302 -H ldaps://192.168.0.4 -b "dc=ssotes,dc=onmicrosoft,dc=com" -s sub -x "(userPrincipalName=test@ssotes.onmicrosoft.com)" -LLL
dn: CN=Test User,OU=AADDC Users,DC=ssotes,DC=onmicrosoft,DC=com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: user
cn: Test User
sn: User
givenName: Test
distinguishedName: CN=Test User,OU=AADDC Users,DC=ssotes,DC=onmicrosoft,DC=com
instanceType: 4
whenCreated: 20161215003608.0Z
whenChanged: 20161215003609.0Z
displayName: Test User
uSNCreated: 30881
memberOf: CN=ssousers,OU=AADDC Users,DC=ssotes,DC=onmicrosoft,DC=com
uSNChanged: 30884
name: Test User
objectGUID:: cBz+hsXVqE6pARpz4Ol0JA==
userAccountControl: 544
badPwdCount: 0
codePage: 0
countryCode: 0
badPasswordTime: 0
lastLogoff: 0
lastLogon: 0
pwdLastSet: 131262357699310735
primaryGroupID: 513
objectSid:: AQUAAAAAAAUVAAAAcrwWyWh9CGaV9xZ6KwoAAA==
accountExpires: 9223372036854775807
logonCount: 0
sAMAccountName: test
sAMAccountType: 805306368
userPrincipalName: test@ssotes.onmicrosoft.com
objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=ssotes,DC=onmicrosoft,DC=com
dSCorePropagationData: 20161215024600.0Z
dSCorePropagationData: 16010101000001.0Z
msDS-AzureADObjectId:: YElvxVofxkyMCNbwGyD9WQ==
msDS-AzureADMailNickname: test

Actually since I was on the same subnet, I could also do a query over 389 (if you add that to your NSG):

azureuser@azure-ad-osuse:~> ldapsearch -H ldap://192.168.0.4:389 -b "DC=ssotes,DC=onmicrosoft,DC=com" -D "admin@ssotes.onmicrosoft.com" -w Suto7302 -s sub "(sAMAccountName=admin)" givenName
# extended LDIF
#
# LDAPv3
# base <DC=ssotes,DC=onmicrosoft,DC=com> with scope subtree
# filter: (sAMAccountName=admin)
# requesting: givenName
#
# Admin User, AADDC Users, ssotes.onmicrosoft.com
dn: CN=Admin User,OU=AADDC Users,DC=ssotes,DC=onmicrosoft,DC=com
givenName: Admin

But we should never expose that to the internet, but it's a good test to make sure AD Services are at least responding. As another test I also made sure I could authenticate as the test user:

azureuser@azure-ad-osuse:~> LDAPTLS_REQCERT=never ldapsearch -D "test@ssotes.onmicrosoft.com" -w Jatu9458 -H ldaps://192.168.0.4 -b "dc=ssotes,dc=onmicrosoft,dc=com" -s sub -x "(userPrincipalName=test@ssotes.onmicrosoft.com)" givenName -LLL
dn: CN=Test User,OU=AADDC Users,DC=ssotes,DC=onmicrosoft,DC=com
givenName: Test

The above commands are using the internal IP and worked out. But it's good to confirm AD is up, SSL is enabled, and we are able to bind. 

It looks like you can't RDP directly to the Azure AD Server even though the port is open. You will get a permission error, what you can do though is deploy a windows machine in Azure that is on the same subnet as the Azure AD server, then join it to the domain and then use Remote Server Administration Tools to administer the Services on the Azure AD box. The process is described in detail in Administer an Azure Active Directory Domain Services managed domain. I didn't end up doing that but I think that could be very helpful. 

Outcomes