One VM Lab Domain Controller with Active Directory Certificate Services (ADCS)

Here’s how to set up a Windows domain controller with Active Directory Certificate Services (ADCS) using a single VM.

I’m not going to walk through the steps for creating a Server 2019 virtual machine. I recommend setting up a standard Generation 2 VM. I gave my VM 4 cores and set everything else as standard. It’s up to you if you wish to use checkpoints. I normally don’t use them. Use the full desktop experience or you will need to employ a jump server. Some components of this setup will require workarounds not covered in this guide if you decide to use core. This is a PowerShell/cmd heavy guide but all commands presented can be copied and pasted into the VM so it is easy to play along at home if you don’t mind the server names and passwords I use.

The goal of this VM is to stand up a domain controller for a test lab where there is a need for ADCS without requiring a second VM. This can help with authentication via Kerberos, secure LDAP, providing certificates to other entities in the lab, etc. This in no way follows best practice and should not be used in production. It violates many rules around security and ADCS PKI design. If you do decide to put in production you are dumb and are being dumb at your own risk. Don’t be dumb. 🙂

It Bears Repeating, Don’t Be Dumb

There are a lot of security issues with this configuration. I still think it is useful for a quick setup in a lab environment where a domain controller and certificate services are needed and the configuration of the PKI environment isn’t critical but should be stable enough for use.

This setup includes revocation for end entity certificates only. It is not possible to secure the Root CA certificate when it is also issuing certificates to end entities. In a real production environment the Root CA private key belongs on an HSM (Hardware Security Module) or at least a locked down system with strict access controls and a defined key signing ceremony. A good Root CA design only issues revocable certificates to issuing certificate authorities who will in turn issue certificates to end entities or other subordinate CAs.

Preparing the VM.

If you’ve already set up the VM as a domain controller you can possibly skip these steps but beware your customizations may not work with all the steps. What I’m going to do in this section is give you a quick path to set up a domain controller starting from a VM that has just come to life after the initial setup.

In this section we will set the time zone, install updates, rename the vm, and install the modules necessary for Domain Controller setup.

You can set the time zone with the following command. In this example I’m setting to Central Standard Time.

# Set Timezone. Use Get-Timezone -ListAvailable to see a list of available time zones.

Set-Timezone –Id 'Central Standard Time'

You can then use this powershell command to install updates. If there are updates to install it will proceed with the install and then restart the computer. Run this command multiple times until the VM until it completes with no restart and throws an error, which means there’s no more updates to install.

# Repeat this command until the VM no longer restarts. 

Install-WUUpdates -Updates (Start-WUScan -SearchCriteria "Type='Software' AND IsInstalled=0") | %{if($_ -eq $true){restart-computer}}

Let’s rename the computer. You can use any name you like. My examples use my own naming conventions and password for my lab. They’re not sensitive so don’t worry about having them or using them. There is no need to restart after issuing the command. We’re going to do that later.

Rename-Computer -NewName 'OCULABDC1'

Next we are going to set the IP and DNS entries. First we will set the IP to something static. This helps in a lab where you already have a gateway that does DHCP and you don’t want the domain controller to be a DHCP server. If you are using VMWare or Virtualbox be aware that the interface alias may be different.

# Set the IP address. Do not use this line verbatim. Use Get-NetIPInterface to see the available interface aliases. 

New-NetIPAddress -InterfaceAlias 'Ethernet' -IPAddress 192.168.2.200 -PrefixLength 24 -DefaultGateway 192.168.2.2

Set the DNS. In this example I’m using the Cloudflare DNS service. If you are concerned about only one DNS server entry, you can add additional entries seperated with a comma.

# Set the DNS. Pay attention to the interface alias. If you changed it for the previous command, change it here. 

Set-DNSClientServerAddress -InterfaceAlias 'Ethernet' -ServerAddresses 1.1.1.1

Install the necessary windows features. In this case it will be AD-Domain-Services,FS-DFS-Namespace, and FS-DFS-Replication.

Install-WindowsFeature -Name AD-Domain-Services,FS-DFS-Namespace,FS-DFS-Replication

Restart the computer.

Restart-Computer

Domain Controller Setup

Now let’s create the domain (and forest). The following commands will create the domain and then restart.

# Import the ADDS Deployment module. 
Import-Module ADDSDeployment

# Create the domain. 
Install-ADDSForest -CreateDnsDelegation:$false -DomainName 'occurative.net' -DomainNetbiosName 'OCCURATIVE' -InstallDNS:$true -NoRebootOnCompletion:$false -Force:$true –SafeModeAdministratorPassword (ConvertTo-SecureString –String 'OccurativeSafePass1' -AsPlainText –Force)

You will get some warnings during this process. The warnings can be safely ignored.

The system will restart. We now have a functioning domain controller. If you used the command verbatim without any modifications it has the following characteristics.

  • Forest and domain is occurative.net
  • The Netbios name is OCCURATIVE
  • The safe mode administrator password is OccurativeAdminPass1 and this his a horrible password.
  • The DC is also a DNS server but it is not a DHCP server so you will need to configure other VMs or systems with the DC as their DNS server if you wish to join them to the domain.

Install the AD Administrative toolset with the following command in PowerShell. A reboot is not required.

Install-WindowsFeature -Name RSAT-ADDS

AD Certificate Services Setup

Now that we have a functioning domain controller, let’s set it up to be an ADCS Certificate Authority. It will be an issuing authority but will also be its own root. I want to repeat that this is dangerous. You never want your root certificate authority to also be issuing certs to any entity outside of a subordinate CA because if you lose control of the private key you will have no way to revoke it. No, a domain controller isn’t a proper root CA. 🙂

First we need to add a few more roles to the DC. In this case we need to add IIS so that the server can act as a CRL (Certificate Revocation List) Distribution Point or “CDP”. This will also allow the VM to function as an Online Certificate Status Protocol (OCSP) responder or allow for quick enrollment of certificates using CSRs if needed. More on that later.

Install-WindowsFeature -Name Web-Server,Web-Mgmt-Console

Next we’re installing the Active Directory Certificate Services features that we need.

Install-WindowsFeature -Name ADCS-Cert-Authority,ADCS-Online-Cert

Now we need to create our CA’s root certificate. I prefer to use the post-install wizard over powershell for simplicity.

Access through the Server Manager

Click next to use the default credentials.

At role services click Certification Authority and then click Next.

Click Next to accept the Enterprise CA setup type.

Click Next to configure as a Root CA.

Click Next to configure a new private key.

Click Next to continue with the default cryptographic options.

Enter a common name for the CA. In my example I’m using “Occurative Lab Root” for the CN. Click Next

Click Next to accept the default 5 year validity period.

Click Next for the default database location.

We will be presented with a summary of our configuration choices. Click Configure to commit.

Verify successful configuration, then click Close at the bottom of the window.

Click No when asked to configure additional role services. We will configure those later.

Going back to powershell, let’s install the RSAT consoles for ADCS.

Install-WindowsFeature -Name RSAT-ADCS

Use Certutil to Configure the CA

Next we are going to use certutil.exe in order to configure the CA without needing to use the console. The first set of commands specifices publication intervals for the Certificate Revocation Lists.

certutil -setreg CA\CRLPeriodUnits 1
certutil -setreg CA\CRLPeriod "Weeks"
certutil -setreg CA\CRLOverlapUnits 24
certutil -setreg CA\CRLOverlapPeriod "Hours"

These commands create the folder where the CRLs will reside, and will set the CDP and AIA (Authority Information Access) URLs that the CA will reference when issuing and revoking tickets. If you’re following the instructions to the letter and your DC is named OCULABDC1 then these commands can be issued verbatim. If you named the DC something else, replace OCULABDC1 with the name of the DC in the lines below.

# Create the CDP folder. 
mkdir c:\cdp

# Modify the lines below if the DC name isn't OCULABDC1.
# Apply the required CDP Extension URLs
certutil -setreg CA\CRLPublicationURLs "1:c:\cdp\%3%8%9.crl\n2:http://OCULABDC1.occurative.net/cdp/%3%8%9.crl\n10:ldap:///CN=%7%8,CN=%2,CN=CDP,CN=Public Key Services,CN=Services,%6%10"

# Apply the required AIA Extension URLs
certutil -setreg CA\CACertPublicationURLs  "1:c:\cdp\%3%8%9.crt\n2:http://OCULABDC1.occurative.net/cdp/%3%8%9.crt\n2:ldap:///CN=%7,CN=AIA,CN=Public Key Services,CN=Services,%6%11\n32:http://OCULABDC1.occurative.net/ocsp"

Finally let’s restart the certificate services.

Restart-Service certsvc

Now that we have the the CA configured let’s publish our first CRL.

certutil -crl

If it worked you will get a notification that the command completed successfully. You can verify the CRL files are in C:\cdp.

We need to copy the root certificate to c:\cdp for AIA to work properly. A copy of the certificate is in the System32 folder under the certsrv\CertEnroll folder. If you used a different name for the root CA certificate and you have a different DC name you will need to modify this command. The name of the file to copy will be “{DC FQDN}_{ROOT CA NAME}.crt” for example “OCULABDC1.occurative.net_Occurative Lab Root.crt” The destination file will simply be “{ROOT CA NAME}.crt” for example “Occurative Lab Root.crt”

# Modify name of the cert files if you are customizing DC and Root cert names. 
cp "C:\Windows\System32\certsrv\CertEnroll\OCULABDC1.occurative.net_Occurative Lab Root.crt" "C:\cdp\Occurative Lab Root.crt"

Setting up the CDP (CRL Distribution Point)

Setting up the CDP is easy since it is just a web site defined in IIS with directory listing enabled.

Open up the IIS manager, drill down to Default Web Site then right click and select Add Virtual Directory…

Enter cdp for the Alias, c:\cdp for the physical path, then click OK.

In the configuration pane for the newly created cdp virtual directory, double-click Directory Browsing

On the right-hand pane click Enable.

Open the web browser on the server and enter the FQDN of the server along with /cdp. This is http only, do not use https. If everything is working up to this point you will see the CRL file and the CRT (for AIA).

Setting Up The OCSP Responder

We’re going to use the role setup wizard again for the OCSP responder.

Access through the Server Manager

Click Next to use the default credentials.

Click Online Responder then click Next.

Click Configure

Verify that configuration succeeded then click Close at the bottom of the window.

In the Tools dropdown in Server Manager, select the Certificate Authority console. The certificate authority console will open.

Expand the CA entry if needed, right click Certificate Templates then click Manage.

The template manager console will open. Locate the OCSP Response Signing template on the list. Right click and select Properties.

Click the Security tab and then click Add.

Click the Object Types button, place a check on Computers, then click OK.

Type in the name of the DC VM (add $), then click OK.

Ensure that the DC is allowed Read and Enroll then click OK.

You can now close the Template Management console.

On the CA console, right-click Certificate Templates. Select New and then Certificate Template to Issue.

Scroll down the list and click OCSP Response Signing to select it. Click OK. This will add the OCSP Response Signing template, which is necessary for the OCSP responder to function.

Now we go back to the Server Manager, to the Tools drop down, and now we will select Online Responder Management.

In the Online Responder Management console, click Revocation Configuration

In the Actions pane to the right, click Add Revocation Configuration.

Click Next at the Getting Started screen.

Give the configuration a meaningful name then click Next.

Click Next for default CA Cert location.

Click Browse to find a published CA cert in AD.

There should only be one entry. Click OK to select it.

Click Next to proceed with the selected certificate.

Click Next to automatically select a signing certificate. This is the reason we published the OCSP Response Signing template earlier.

Click Finish to accept the default revocation provider.

The Revocation Configuration Status should show “Working” for the configuration you just defined.

Verifying ADCS Configuration

We can use a few built in utilities to verify the configuration.

Using PKIView.msc To Verify Extension Locations and CA Cert Availability

PKIView will give us a single window view of all configured locations as well as the CA certificate. This will indicate if there are any problems with the locations we have defined for AIA/CDP/OCSP.

pkiview.msc

All entries should show OK. If the OCSP Location #1 entry shows status of error then you most likely started this step too soon after configuring the online responder. Wait a few minutes and then press F5 to refresh. Its status will eventually change to OK.

NOTE: If you recheck PKIView later there may be a warning about CRL expiration. This is normal and can be ignored. In our configuration the CA will publish a new CRL before the current CRL expires.

Using the URL Retrieval Tool to Verify CDP/AIA/OCSP in Issued Certificates

First let’s go back to the Certificate Authority Console. If you go to Issued Certificates you can see at least three entries listed. The first is a Domain Controller certificate automatically enrolled by the DC. The second is the OCSP Signing Certificate issued to the OCSP Responder. It is used to sign OCSP verification responses. The third is a CA Exchange certificate. The CA Exchange certificate is used for request encryption by clients requesting certificates from the CA.

We can use the Domain Controller certificate to do some testing. Double-click the Domain Controller certificate. The certificate properties window will open. Click Details and then click the Copy to File button.

Click Next at the welcome page for the export wizard.

Click Next to accept the default file format.

Click Browse (this is a standard Save As) dialogue. The default location is the documents folder. Type DC in the file name and click Save.

Click Next to proceed with the export.

Click Finish then click OK.

We can now use certutil.exe to verify that certificate revocation checking with CDP/OCSP/AIA work as specified in issued certificates.

certutil -url $Env:USERPROFILE\Documents\DC.cer

The URL Retrieval Tool will open.

Select Certs (from AIA) and click Retrieve. All entries show verified.

Next, select CRLs (from CDP) and click Retrieve. All entries show verified.

Finally, select OCSP (from AIA) and click Retrieve. The OCSP responder should state verified.

Wrapping Up

You now have a single domain controller that is also an ADCS Certificate Authority suitable for use in an isolated lab. In its current configuration there are default templates that can be used for issuing certificates to different entities from lab computer VMs to test users.

In future articles I plan on going over setting up the Web Enrollment service for requesting certs via certificate signing requests. There are also group policy configurations to allow specific certificate handling functionality with clients in the domain. There could be other topics should I decide to continue with this configuration, but I will be publishing an article on the Web Enrollment service and Group Policy in the future. For now there are lots of articles via the web on how to request certificates from the certificate management console as well as more advanced configurations.

!!! BEWARE !!!

If you have reached this far then you have set this up in a lab right? You’re not using this in production because you read through my warnings before about security problems with this approach. Here’s the security problems that you will now face if you put this in production.

  • The domain as configured is weak.
  • If your domain gets owned so does your entire internal PKI security world. The attacker can conduct man-in-the-middle attacks on all your infrastructure as long as the certificate is valid.
  • Because there is no easy way to revoke the same key that is issuing certificates to entities any client that trusts the key will trust whatever an attacker issues with little recourse from you.
  • Microsoft best practice precludes the use of a single server for more than one type of role. In fact within ADCS the roles are best split amongst a set of servers and not combined into one.
  • IIS on a Domain Controller increases its attack surface, by a lot. You now have unauthenticated HTTP connections to your DC allowing viewing of a directory.
  • The configuration of the default templates are weak or outdated.

Thank you so much for using this guide! Please let me know via my contact information or through the comments feature below if you have any questions.

IT, ADHD, infosec, and random junk.