Background:
Privileged Access Management (PAM) is relatively new feature of Microsoft Identity Manager 2016 and is becoming more and more popular. Intention of this Blog series is to provide step by step instructions how to deploy PAM right way and how to evaluate its features.
In this series I will use Azure VMs to simulate real world environment. You can opt for different setup (Hyper-V, VMWare or even physical servers).
Scenario
Contoso is company which has existing AD infrastructure with Forest prod.contoso.com running Windows 2012 R2 Domain Controllers in Windows 2012 R2 Domain and Forest Functional Level. They want to implement Just in Time access control for users of their two critical applications: TestApp and ClaimApp. They also want to restrict access to their DomainAdmins using JIT and MFA authentication.
After the research, they want to evaluate MIM PAM as a solution for those requirements.
series:
- Part 1 – Preparing test environment
- Part 2 – PAM prerequisites
- Part 3 – Installing PAM Server
- Part 4 – Installing PAM Example portal
- Part 5 – MFA configuration
- Part 6 – Evaluation
Test Environment description:
To evaluate PAM, we need two AD forests – production and privileged forest. In my test environment I will set-up only one Domain Controller per AD forest, but in the production, you should have at least two. In addition to Domain Controllers we will need in the production forest Exchange Server and Client machine. In privileged forest we will need MIM server and, optionally, additional client machine.
My setup lab contains following:
prod.contoso.com Forest
PROD-DC running Windows 2012 R2 - Standard DS1 v2 (1 vcpus, 3.5 GB memory)
(I’ve selected Windows 2012R2 to simulate most common situation in the field)
- Active Directory
- Certificate Services
- ADFS services
- MFA server
PROD-EX running Windows 2016 - Standard E2s v3 (2 vcpus, 16 GB memory)
- Exchange 2016
- Windows Authentication sample application
- Claims Authentication sample application
PROD-CL running Windows 10 - Standard DS1 v2 (1 vcpus, 3.5 GB memory)
priv.contoso.com Forest
PRIV-DC running Windows 2016 - Standard DS1 v2 (1 vcpus, 3.5 GB memory)
(even we can use Windows 2012R2, Windows 2016 provides many advantages)
- Active Directory
PRIV-PAM running Windows 2016 - Standard B8ms (8 vcpus, 32 GB memory)
- SQL server 2016
- SharePoint Server 2016
- MIM Service and Portal
- PAM
PRIV-CL running Windows 10 - Standard DS1 v2 (1 vcpus, 3.5 GB memory)
PROD and PRIV forests are installed in different Azure Resource Groups and between them is configured routing.
Preparing Test Environment:
-
- Install OS on all machines (see above for OS version);
- Promote Domain Controllers:
- PROD
Log on to PROD-DC as an Administrator
In Admin PowerShell run following commands:
Install-WindowsFeature AD-Domain-Services -IncludeAllSubFeature –IncludeManagementTools
Import-Module ADDSDeployment
Install-ADDSForest -CreateDnsDelegation:$false -DatabasePath "C:WindowsNTDS" -DomainMode "Win2012R2" -DomainName "prod.contoso.com" -DomainNetbiosName "PROD" -ForestMode "Win2012R2" -InstallDns:$true -LogPath "C:WindowsNTDS" -NoRebootOnCompletion:$false -SysvolPath "C:WindowsSYSVOL" -Force:$true
-
-
- PRIV
-
Log on to PRIV-DC as an Administrator
On PRIV-DC in Admin PowerShell run following commands:
Install-WindowsFeature AD-Domain-Services -IncludeAllSubFeature –IncludeManagementTools
Import-Module ADDSDeployment
Install-ADDSForest -CreateDnsDelegation:$false -DatabasePath "C:WindowsNTDS" -DomainMode "WinThreshold" -DomainName "priv.contoso.com" -DomainNetbiosName "PRIV" -ForestMode "WinThreshold" -InstallDns:$true -LogPath "C:WindowsNTDS" -NoRebootOnCompletion:$false -SysvolPath "C:WindowsSYSVOL" -Force:$true
-
-
- Configure Dns
-
Log on to PROD-DC as an Administrator
-
-
- On PROD-DC create top Dns zone (contoso.com)
-
Open Powershell as Admin and run following command
Add-DnsServerPrimaryZone -Name "contoso.com" -ReplicationScope "Forest" -PassThru -DynamicUpdate None
-
-
- Allow zone transfer to priv-dc:
-
Set-DnsServerPrimaryZone -Name "contoso.com" -SecureSecondaries TransferToSecureServers -SecondaryServers "<priv-dc-ip>"
-
-
- Create A records in created top zone for applications
-
Record | IP | Description |
---|---|---|
sts.contoso.com | Prod DC IP | ADFS service |
claimapp.contoso.com | Prod Exchange IP | Application with Claim based authentication |
testapp.contoso.com | Prod Exchange IP | Application with Windows Integrated authentication |
mail.contoso.com | Prod Exchange IP | Mail server CAS |
mfasdk.contoso.com | Prod DC IP | MFA SDK service |
pam.contoso.com | Priv MIM IP | PAM user portal |
pamapi.contoso.com | Priv MIM IP | PAM API |
pamportal.contoso.com | Priv MIM IP | PAM Administrative portal |
pamsvc.contoso.com | Priv MIM IP | PAM Web Service endpoint |
Add-DnsServerResourceRecordA -Name "sts" -ZoneName "contoso.com" -IPv4Address "<prod-dc-ip>"
Add-DnsServerResourceRecordA -Name "claimapp" -ZoneName "contoso.com" -IPv4Address "<prod-ex-ip>"
Add-DnsServerResourceRecordA -Name "testapp" -ZoneName "contoso.com" -IPv4Address "<prod-ex-ip>"
Add-DnsServerResourceRecordA -Name "mail" -ZoneName "contoso.com" -IPv4Address "<prod-ex-ip>"
Add-DnsServerResourceRecordA -Name "mfasdk" -ZoneName "contoso.com" -IPv4Address "<prod-dc-ip>"
Add-DnsServerResourceRecordA -Name "pam" -ZoneName "contoso.com" -IPv4Address "<priv-mim-ip>"
Add-DnsServerResourceRecordA -Name "pamapi" -ZoneName "contoso.com" -IPv4Address "<priv-mim-ip>"
Add-DnsServerResourceRecordA -Name "pamportal" -ZoneName "contoso.com" -IPv4Address "<priv-mim-ip>"
Add-DnsServerResourceRecordA -Name "pamsvc" -ZoneName "contoso.com" -IPv4Address "<priv-mim-ip>"
-
-
- Create Prod DNS Zone Delegation on Prod-DC
-
Add-DnsServerZoneDelegation -Name "contoso.com" -ChildZoneName "prod" -NameServer "prod-dc.contoso.com" -IPAddress "<prod-dc-ip>" -PassThru
-
-
- Create priv DNS Zone Delegation on Prod-DC
-
Add-DnsServerZoneDelegation -Name "contoso.com" -ChildZoneName "priv" -NameServer "priv-dc.contoso.com" -IPAddress "<priv-dc-ip>" -PassThru
Log on to PRIV-DC as an Administrator
-
-
- On PRIV-DC create copy of top domain:
-
Add-DnsServerSecondaryZone -Name "contoso.com" -MasterServers "<prod-dc-ip>" -ZoneFile "contoso.com.dns" -PassThru
-
-
- Join all member servers and clients to domains
- Join PRIV-PAM and PRIV-CL To PRIV Domain
- Join PROD-EX and PROD-CL To PROD Domain
- On PROD domain create TestAppUsers Global Security Group, TestAppUser and add TestAppUser to TestAppUsers Group
-
Log on to PROD-DC as an Administrator
Open Powershell as Admin and run following commands
-
-
- Execute following PowerShell commands to create OUs:
-
New-ADOrganizationalUnit -Name Corp -Path "DC=prod,DC=contoso,DC=com" -ProtectedFromAccidentalDeletion $true
New-ADOrganizationalUnit -Name Application -Path "OU=Corp,DC=prod,DC=contoso,DC=com" -ProtectedFromAccidentalDeletion $true
New-ADOrganizationalUnit -Name Administration -Path "OU=Corp,DC=prod,DC=contoso,DC=com" -ProtectedFromAccidentalDeletion $true
New-ADOrganizationalUnit -Name SystemAccounts -Path "DC=prod,DC=contoso,DC=com" -ProtectedFromAccidentalDeletion $true
-
-
- Create Group:
-
New-ADGroup -Name TestAppUsers -GroupCategory Security -GroupScope Global -Path "OU=Application,OU=Corp,DC=prod,DC=contoso,DC=com"
-
-
- Create User:
-
$secPwd = ConvertTo-SecureString 'P@$$w0rd' -asplaintext –force
New-ADUser -Name TestAppUser -DisplayName "Test Application User" -Enabled $true -Path "OU=Application,OU=Corp,DC=prod,DC=contoso,DC=com" -SamAccountName TestAppUser -AccountPassword $secPwd
-
-
- Add user to group
-
Add-ADGroupMember -Identity "CN=TestAppUsers,OU=Application,OU=Corp,DC=prod,DC=contoso,DC=com" -Members TestAppUser
-
-
- On Prod-Dc server install Certificate Services
- From PowerShell As an Admin execute following commands:
-
Add-WindowsFeature ADCS-Cert-Authority -IncludeManagementTools
Install-AdcsCertificationAuthority -CAType EnterpriseRootCA –Force
-
-
- On Prod Server configure http CRL distribution point:
- Install and configure IIS for CRL distribution
-
From PowerShell run
Add-WindowsFeature Web-WebServer –IncludeManagementTools
New-WebVirtualDirectory -Site "Default Web Site" -Name CertEnroll –PhysicalPath C:WindowsSystem32CertSrvCertEnroll
-
-
- Configure and publish Certificate Authority Templates
-
This operation requires much more complex scripting so we will do it using GUI
Open Certificate Authority tool, expand CA server, right click on Certificate Templates container and select "Manage"
Find and select "Code Signing" template, right click and select "Duplicate Template"
In "Properties of New Template" window select General Tab and enter Template Display Name "Code Signing V2"
On the Tab "Superseded Templates" add old "Code Signing" template
Click "OK"
Select, and right click "Web Server" template and select "Duplicate Template"
In "Properties of New Template" window select General Tab and enter Template Display Name "Web Server V2"
On the "Request Handling" tab check "Allow private key to be exported"
On the Tab "Superseded Templates" add old "Web Server" template
On the "Security" Tab add Read and Enroll permissions to "Domain Computers" and "Domain Controllers" groups.
Click "OK"
Close Certificate Templates Console.
In Certificate Authority tool select "Certificate Templates" container
Right click on the empty space in the central pane and select "Certificate Template to issue"
Select (using Ctrl key) both new templates (Web Server V2 and Code Signing V2) and press OK
Close Certificate Authority Tool
-
-
- Add CA certificate to "Trusted root Certificate Authorities" in PRIV forest
- Export CA root certificate
- Add CA certificate to "Trusted root Certificate Authorities" in PRIV forest
-
On command prompt on PROD-DC position in the folder where you want to save certificate and run following command
certutil -ca.cert PROD-DC.cer
-
-
-
- Distribute PROD CA root certificate to Client machines using GPO
-
-
Log on to PRIV-DC as an Administrator
on PRIV-DC open Group Policy Management Console, find Default Domain Policy and open it for edit
open Computer ConfigurationPoliciesWindows SettingsSecurity SettingsPublic Key Policies, right-click Trusted Root Certification Authorities, and then click Import. Select file created in previous step (PROD-DC.cer) and follow the wizard (accept all default).
-
-
-
- On PROD-EX install Exchange Server 2016.
-
I won’t spend much time explaining how to install Exchange 2016, but since we are installing it on Windows 2016 server you should use latest binaries. I was using binaries found on https://www.microsoft.com/en-us/download/details.aspx?id=57068
-
- Configure Exchange Server OWA and PowerShell for SSL
Log on to PROD-EX as a PRODAdministrator
-
-
- Re-apply Group Policies
-
gpupdate /force
-
-
- Request Certificate
-
On PROD-EX run from PowerShell (Admin) following command:
$sslCertificate = Get-Certificate -Template WebServerV2 -SubjectName "CN=Prod-Ex.prod.contoso.com, OU=Blog,O=Contoso,L=Dubai,S=Dubai,C=AE" -DnsName mail.contoso.com -CertStoreLocation cert:LocalMachineMy
-
-
- Reconfigure SSL
-
Run following commands in admin PowerShell on PROD-EX server:
$cert = $sslCertificate.Certificate.Thumbprint
$guid = [guid]::NewGuid().ToString("B")
netsh http add sslcert hostnameport="mail.contoso.com:443" certhash=$cert certstorename=MY appid="$guid"
New-WebBinding -name "Default Web Site" -Protocol https -HostHeader "mail.contoso.com" -Port 443 -SslFlags 1
-
-
- Install ADFS
-
Log on to PROD-DC as an Administrator
-
-
- Initialize gMSA
-
On PROD-DC run PowerShell (Admin) command
Add-KdsRootKey –EffectiveTime ((get-date).addhours(-10))
New-ADGroup -Name 'Grp-gMSA' -GroupScope Global -Description 'This Group contains Principals allowed to retrieve Managed Password'
-
-
- Create Service Account
-
New-ADServiceAccount -name adm-ADFSService -DNSHostName 'prod-dc.prod. contoso.com ' -PrincipalsAllowedToRetrieveManagedPassword 'Grp-gMSA' -Description 'Account Running ADFS service'
-
-
- Install
-
On PROD-DC run PowerShell (Admin) command
Install-WindowsFeature ADFS-Federation –IncludeManagementTools
-
-
- Create ADFS SSL certificate
-
On PROD-DC run from PowerShell (Admin) following command:
$adfsCert = Get-Certificate -Template WebServerV2 -SubjectName "CN=sts.contoso.com, OU=Blog,O=Contoso,L=Dubai,S=Dubai,C=AE" -CertStoreLocation cert:LocalMachineMy
-
-
- Setup ADFS
-
On PROD-DC run from PowerShell (Admin) following commands:
$cert = $adfsCert.Certificate.Thumbprint
Install-AdfsFarm -CertificateThumbprint $cert -FederationServiceName sts.contoso.com -FederationServiceDisplayName "Contoso Corporation" -GroupServiceAccountIdentifier PRODadm-ADFSService$ -OverwriteConfiguration
-
-
- Install sample Applications
- Download sample Windows Authentication Application from https://github.com/gmihelcic/TestWindowsAuthenticationApp/raw/master/TestWindowsAuthentication.zip
- Create new folder C:ApplicationsWindowsAuth on PROD-EX and extract downloaded ZIP to that folder
- Download sample Claim Authentication Application from https://github.com/gmihelcic/TestWindowsAuthenticationApp/raw/master/ClaimApp.zip
- Create new folder C:ApplicationsClaimsAuth on PROD-EX and extract downloaded ZIP to that folder
-
Log on to PROD-EX as a PRODAdministrator
-
-
- Create Application Pools:
-
Import-Module WebAdministration
New-Item –Path IIS:AppPoolsWindowsAuthApp
$AppPool = Get-Item IIS:AppPoolsWindowsAuthApp
$AppPool.processModel.identityType = "NetworkService"
$AppPool| set-item
New-Item –Path IIS:AppPoolsClaimsAuthApp
$AppPool = Get-Item IIS:AppPoolsClaimsAuthApp
$AppPool.processModel.identityType = "NetworkService"
$AppPool| set-item
-
-
- Create Web Applications
-
$sslCert = Get-Certificate -Template WebServerV2 -SubjectName "CN=testapp.contoso.com, OU=Blog,O=Contoso,L=Dubai,S=Dubai,C=AE" -CertStoreLocation cert:LocalMachineMy
$cert = $sslCert.Certificate.Thumbprint
$guid = [guid]::NewGuid().ToString("B")
netsh http add sslcert hostnameport="testapp.contoso.com:443" certhash=$cert certstorename=MY appid="$guid"
New-WebSite -Name "testapp.contoso.com" -Ssl -Port 443 -HostHeader "testapp.contoso.com" -PhysicalPath "C:ApplicationsWindowsAuth" -ApplicationPool "WindowsAuthApp" -SslFlags 1
$sslCert = Get-Certificate -Template WebServerV2 -SubjectName "CN=claimapp.contoso.com, OU=Blog,O=Contoso,L=Dubai,S=Dubai,C=AE" -CertStoreLocation cert:LocalMachineMy
$cert = $sslCert.Certificate.Thumbprint
$guid = [guid]::NewGuid().ToString("B")
netsh http add sslcert hostnameport="claimapp.contoso.com:443" certhash=$cert certstorename=MY appid="$guid"
New-WebSite -Name "claimapp.contoso.com" -Ssl -Port 443 -HostHeader "claimapp.contoso.com" -PhysicalPath "C:ApplicationsClaimsAuth" -ApplicationPool "WindowsAuthApp" -SslFlags 1
-
-
- Configure Windows Authentication for testapp.contoso.com:
-
Set-WebConfigurationProperty -filter /system.WebServer/security/authentication/AnonymousAuthentication -name enabled -value false -location testapp.contoso.com
Set-WebConfigurationProperty -filter /system.WebServer/security/authentication/windowsAuthentication -name enabled -value true -location testapp.contoso.com
setspn -S http/testapp.contoso.com PROD-EX
IISRESET
-
-
- Register application in ADFS
-
Log on to PROD-DC as an Administrator
Run following PowerShell commands with Administrative privileges:
-
-
- Add ADFS Relying Party Trust for ClaimApp
-
Add-AdfsRelyingPartyTrust -Name "Test Application" -WSFedEndpoint 'https://claimapp.contoso.com' -Identifier 'https://claimapp.contoso.com' -Enabled $true
-
-
- Configure Relying Party Claim Issuance Rules
-
$rules = @'
@RuleName = "Roles"
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid"]
=> issue(Type = "http://schemas.microsoft.com/ws/2008/06/identity/claims/role", Issuer = c.Issuer, OriginalIssuer = c.OriginalIssuer, Value = c.Value, ValueType = c.ValueType);
@RuleName = "User Name"
c:[Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == "AD AUTHORITY"]
=> issue(store = "Active Directory", types = ("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"), query = ";userPrincipalName;{0}", param = c.Value);
'@
Set-ADFSRelyingPartyTrust –TargetName "Test Application" -IssuanceTransformRules $rules
-
-
- Configure Relying Party Authorization Rule
-
$authRules = '=> issue(Type = "http://schemas.microsoft.com/authorization/claims/permit", Value = "true");'
$rSet = New-ADFSClaimRuleSet –ClaimRule $authRules
Set-ADFSRelyingPartyTrust –TargetName "Test Application" –IssuanceAuthorizationRules $rSet.ClaimRulesString
-
-
- Configure Local Intranet Internet Zone
- Open Group Policy Management tool
- Expand Forest/Domains/prod.contoso.com/Group Policy Objects and right click on "Default Domain Policy". Select Edit
-
-
-
- Expand Computer Configuration/Policies/Administrative Templates/Windows Components/Internet Explorer/Internet Control Panel/Security Page and double click on "Site To Zone Assignment List" policy
-
-
-
- Click on Enable and button Show
-
Configure and
-
-
-
- https://sts.contoso.com,
- https://testapp.contoso.com,
- https://claimapp.contoso.com,
- https://mfasdk.contoso.com and
- https://pamapi.contoso.com
-
-
for "Local Intranet" Zone (1):
Click OK, OK and close GPMC tool
-
-
- Repeat above steps (a – d) for priv.contoso.com domain.
-
Log on to PROD-CL as a PRODAdministrator
-
-
- Open Administrative Command Prompt and execute
-
Gpupdate /force
-
-
- Open System tool from Control Panel and configure Domain Users for Remote access
-
-
-
- Test Applications
-
Log on to PROD-CL as a PRODTestAppUser with password P@$$w0rd
-
-
- Open Internet Explorer and go to page https://testapp.contoso.com
-
You should get
You should get following:
Conclusion of Part 1
Now we are ready for the Part 2 - PAM prerequisites setup.
In this exercise we have set up environment with several components. This environment will be good basis for next exercises.
In this exercise I didn’t spend much time on PRIV Forest hardening, what I leave to you for the future.
In the Part 2 we will set up bunch of accounts and Groups, harden PAM server, setup SQL and SharePoint 2016 for PAM. Until then
Have a great week.
Disclaimer – All scripts and reports are provided ‘AS IS’
This sample script is not supported under any Microsoft standard support program or service. This sample script is provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of this sample script and documentation remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation, production, or delivery of this script be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use this sample script or documentation, even if Microsoft has been advised of the possibility of such damages.