Replace ADCS with EJBCA Autoenrollment
This is a technical integration guide for EJBCA Microsoft Autoenrollment (MSAE) and how EJBCA can serve as a drop-in autoenrollment replacement for Microsoft Active Directory Certificate Services (ADCS).
Core Concepts and Key Considerations
Service Account(s)
There are two different types ofservice account available in an MSAE integration.
Kerberos Account
Used to map the principal name in the keytab file that holds the kerberos encryption key. This key is when kerberos tickets are issued to the clients requesting a certificate policy from an EJBCA Server.
Configured with a Service Prinicpal Name (SPN) that maps to either a load balancer or a single EJBCA Server.
LDAP Bind Account
Performs LDAP or LDAPS queries using basic authentication.
Retrieves the Certificate Templates in Active Directory
Builds an a requesting user from Active Directory when a certificate request is submitted to EJBCA
GMSA accounts are not supported because EJBCA cannot be a member of Active Directory
In flat domains, a single account can be used to support both functions. In an Active Directory with a Parent and Child domains, the use of single account requires additional modifications to Active Directory for success of both functions,
LDAPS and Kerberos Authentication
MSAE can be integrated in a flat domain or in an Active Directory consisting of a Parent domain and one, or multiple, Child domains. Security requirements are typically applied to the Active Directory service account(s) and keytab file(s) generated during an MSAE integration.
EJBCA MSAE uses LDAP(S) Simple Bind to perform queries on Certificate Templates and build AD Objects while responding to an autoenrollment request. Additionally, Kerberos is to authenticate requesting users and tunnel autoenrollment requests between the requesting user and EJBCA.
EJBCA can be deployed to Active Directory consisting of a Parent and Child domains using one of two approaches.
One Service Account for both LDAPS Bind and Kerberos Account
Child Domain + Child Domain + Forest Domain = 1 LDAPS Bind and CEP/CES Account (1 total)
A separate LDAPS Bind acount in each Child Domain and a Kerberos Account in the Parent Domain
Child Domain + Child Domain + Forest Domain = 2 LDAPS Bind Accounts and 1 CEP/CES Account (3 total)
Active Directory Considerations
Forest-Level LDAPS Lookups
While Certificate Templates can be retrieved over 389/636 using the Parent Domain as the Base Search, the Gobal Catalog ports (3268/3269) must be used to build an AD object of the requesting user. By default, msPKI attribtues are not replicated to the Global Catalog which means changing the port to support building an AD object for the requesting user would fail.
One Service Account in the Forest configured with the SPN(s)
The following attributes must be configured with Replicate this attribtues to the Global Catalog in the Parent domain schema to support Certificate Template retreival.
msPKI-Enrollment-Flag
msPKI-Private-Key-Flag
msPKI-Certificate-Name-Flag
msPKI-Minimal-Key-Size: 2048
msPKI-Template-Schema-Version: 2
msPKI-Template-Minor-Revision: 10
msPKI-Cert-Template-OID
msPKI-Certificate-Application-Policy
revision
The following attributes must be configured with Replicate this attribtues to the Global Catalog in the Parent domain schema to support Building Object from AD.
nETBIOSName
dnsRoot
nCName
Domain-Level LDAPS Lookups
One Service Account in the Parent Domain configured for Kerberos Authenticaiton
One Service account in each Child Domain for LDAPS lookups
Security Requirements and Integration Scope
Security requirements are typically applied to the Active Directory service account and keytab file generated in during an MSAE integration. This guide is scoped with the following to limit the number of these items that must be maintained and align with security requirements.
MSAE Integration with Active Directory Forest with at least one Child domain
Configuration of multiple Certificate Enrollment Policy (CEP) servers
One of the two Service Account methods
One Service Account
Multiple Service Accounts
Prerequisites
This guide was created using the following software version:
EJBCA Enterprise 9.3.3
AWS Cloud v4.3.4
SWAPP 2.8.2
Windows Server Standard 2019
Before starting this how-to guide, ensure the following requirements are met:
EJBCA:
Valid EJBCA Root CA and Issuing CA
Certificate and End Entity Profiles configured to support MSAE CSR and extension requirements.
Refer to Part 3a: EJBCA Configuration for satisfying those.
Microsoft Environment:
An Active Directory Forest Domain is deployed
A minimum of 1 Child Domain
You must have Domain Administrator rights for the Forest and Child Domains
Active Directory Certificate Services Tools installed on Forest Domain DC.
EJBCA Root CA and Issuing CA installed in the local certificate store of the Windows Server server being used for configuration, or distrubuted through Group Policy.
Step 1 - Set Up Active Directory
Install Default Certificate Templates
These steps are required if Certificate Templates or an Enterprise Microsoft CA were not already installed in Active Directory.
Start an elevated PowerShell session and run the following:
CODEcertutil -installdefaulttemplatesPerform an LDAP query from an EJBCA CEP Server using ldapsearcher to confirm templates are available.
CODE# Prompt for password ldapsearch -xLLL -W -H ldap://msae.local:389 \ -D 'CN=ra-service,OU=service-accounts,OU=msae,DC=msae,DC=local' \ -b 'CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=msae,DC=local' # Provide password in the command ldapsearch -xLLL -H ldap://msae.local:389 \ -D 'CN=ra-service,OU=service-accounts,OU=msae,DC=msae,DC=local' -w 'Password!123' \ -b 'CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=msae,DC=local'Verify the ouput includes a list of Certificate Templates.
Create Service Accounts
Refer to https://docs.keyfactor.com/ejbca/latest/part-1-configure-active-directory-domain-services#id-(9.3.3)Part1:ConfigureActiveDirectoryDomainServices-Step2-CreateServiceAccounts for generic information on these accounts.
LDAPS Bind Account
Single Service Account
Create an AD User object in the Parent Domain
Multiple Service Accounts
Create an AD User object in each Child Domain where MSAE needs to be integration
CEP and CES Account
Single Service Account
Use the same account as the LDAPS Bind Account
Multiple Service Accounts
Create an AD User object in the Parent Domain
Set CEP and CES Account (SPN)
Load Balanced CEP URL
Add the Load Balanced CEP SPN
CODEsetspn -s HTTP/loadbalanced-cepserver.ejbca.local ra-service
Individual CEP URLs
Add each CEP SPN
CODEsetspn -s HTTP/cepserver-01.ejbca.local ra-service setspn -s HTTP/cepserver-02.ejbca.local ra-service
Create the Forest Domain Kerberos Files
Set the SPN on the ra-service account:
CODEPS C:\Windows\system32> setspn -s HTTP/cepserver01.ejbca.local ra-service Checking domain DC=msae,DC=local Registering ServicePrincipalNames for CN=ra-service,OU=service-accounts,OU=msae,DC=msae,DC=local HTTP/cepserver01.ejbca.local Updated objectCreate the keytab for the ra-service account:
CODEktpass ` -out "$Home\Desktop\ra-service.keytab" ` -mapuser "ra-service@msae.local" ` -princ "HTTP/cepserver01.ejbca.local@MSAE.LOCAL" ` -pass "Password!123" ` -ptype "KRB5_NT_PRINCIPAL" ` -crypto "AES256-SHA1" ` -kvno 0Create a the Krb5.conf file.
CODE[libdefaults] default_realm = MSAE.LOCAL default_tkt_enctypes = aes256-cts aes256-cts-hmac-sha1-96 default_tgs_enctypes = aes256-cts aes256-cts-hmac-sha1-96 permitted_enctypes = aes256-cts aes256-cts-hmac-sha1-96 [realms] MSAE.LOCAL = { kdc = alpha.msae.local default_domain = msae.local } [domain_realm] .msae.local = MSAE.LOCAL
Create Certificate Template
Create a new security group called computer-autoenroll
Add the current computer to the computer-autoenroll group.
Open the Certificate Templates snap-in.
Right click the Kerberos Authentication template and click duplicate.
Configure the following:
Compatability
Certificate Authority: Windows Server 2016
Certificate recipient: Windows 10 / Windows Server 2016
General
Template display name: EJBCA-KerberosAuthentication
Subject Name
Subject name format: Full distinguished name
Security
Add security group: computer-autoenroll
Read: Allow
Enroll: Allow
Autoenroll: Allow
Click OK to save the new certificate template.
Update Active Directory Schema (Single Service Account Only)
Complete the following steps if configuring a single LDAPS Account in the Forest Domain.
In an elevated PowerShell console on a Forest DC with the FSMO role, run this command:
CODEregsvr32 schmmgmt.dllOpen Run (Win + R), type mmc, and press Enter.
In the MMC console, go to File > Add/Remove Snap-in.
Choose Active Directory Schema, then click Add > OK.
Open and Edit the Schema:
Alternatively, the script below can be copied and pasted into the elevated PowerShell window to edit all attributes at once:
CODE# Load the AD module (if needed) Import-Module ActiveDirectory # Names do not directly match the common names listed in the Requirements section. $attrsToReplicate = @( "NETBIOS-Name", # nETBIOSName "NC-Name", # nCName "Dns-Root", # dnsRoot "revision", "ms-PKI-Certificate-Policy", "ms-PKI-Enrollment-Flag", "ms-PKI-Private-Key-Flag", "ms-PKI-Certificate-Name-Flag", "ms-PKI-Minimal-Key-Size", "ms-PKI-Template-Schema-Version", "ms-PKI-Template-Minor-Revision", "ms-PKI-Cert-Template-OID", "ms-PKI-Certificate-Application-Policy" ) $root = [ADSI] “LDAP://RootDSE” $domainController = [string](Get-ADDomainController -Discover -NextClosestSite).HostName foreach($attr in $attrsToReplicate){ # Get the DN of the attribute $attrDistinguishedName = "CN=$attr,$($root.schemaNamingContext)" $attrReplicateItem = Get-ADReplicationAttributeMetadata -Object $attrDistinguishedName -Server $domainController | Where {$_.AttributeName -eq "isMemberOfPartialAttributeSet"} # Print current value to console if(-not $attrReplicateItem -or $attrReplicateItem.AttributeValue -eq $false){ Set-ADObject -Identity $attrDistinguishedName -Replace @{ isMemberOfPartialAttributeSet = $true } # Verify value was set Get-ADReplicationAttributeMetadata -Object $attrDistinguishedName -Server $domainController | Where {$_.AttributeName -eq "isMemberOfPartialAttributeSet"} | foreach{ if($_.AttributeValue -eq $true){ Write-Host "Updated '$attr' because it is already set." -Foreground Yellow } else { Write-Host "Failed to update '$attr'." -Foreground Red } } } else { Write-Host "Skipping '$attr' because it is already set." -Foreground Gray } }
Summary
This step has configured Active Directory to support LDAPs lookups over the Global Catalog. Procee with creating an MSAE alias(es) in EJBCA that support lookups using the Global Catalog.
Step 2- Configure EJBCA
Configuration steps vary depending on the number of service accounts you are using and/or where they are being created. Complete one of the two MSAE Configuration sections below:
Refer to the Core Concepts and Key Considerations for additional information on which to choose.
Create Single Service Account MSAE Alias(es)
Complete the initial setup of the MSAE alias to verify successful setup of the LDAP Simple Bind.
Multiple aliases are only required when more than one SPN was specified in the CEP and CES Account
Create a Remote Authentication Keybinding and configure Use SSL - Port 636/3263 if LDAP 389/3262 is not open.
Log into EJBCA RA 01 Admin Web
Select System Configuration > System Configuration > Protocol Configuration.
Locate Protocol msae and click Enable under Actions.
Select System Configuration > Autoenrollment Configuration
Click Add.
Populate the following fields:
Name: msae-forest
Forest Root Domain: msae.local
AD Domain Controller: msae.local
Policy Name: MSAE Autoenrollment
Service Principal Name (SPN): HTTP/cepserver01.ejbca.local@MSAE.LOCAL
AD User Login: CN=ra-service,OU=service-accounts,OU=msae,DC=msae,DC=local
AD User Password: Password!123
Click Test Connection and verify the following message is shown at the top.
CODEActive Directory connection test was successful. MS Auto Enrollment Settings are successfully saved.In the Kerberos Keytabs, click Browse and select the ra-service.keytab file generated in a previous step
Click Test Connection to query the EJBCA-KerberosAuthentication template.
In the Available MS Templates, select:
Select a Template: EJBCA-KerberosAuthentication
Select an End Entity Profile: <EJBCA-KerberosAuthentication-EEP>
Select an Certificate Profile: <EJBCA-KerberosAuthentication-CP>
Click Save.
Repeat the Create MSAE Alias(es) steps on each EJBCA CEP Server and for each SPN set on the CEP and CES Account
Create Multiple Service Account MSAE Alias(es)
Complete the initial setup of the MSAE alias to verify successful setup of the LDAP Simple Bind.
Multiple aliases are only required when more than one SPN was specified in the CEP and CES Account
Create a Remote Authentication Keybinding and configure Use SSL if LDAP 389 is not open.
Log into EJBCA RA 01 Admin Web
Select System Configuration, and Autoenrollment Configuration
Click Add.
Populate the following fields:
Name: msae-forest
Forest Root Domain: msae.local
AD Domain Controller: alpha.msae.local
Policy Name: Alpha MSAE Autoenrollment
Service Principal Name (SPN): HTTP/cepserver01.ejbca.local@MSAE.LOCAL
AD User Login: CN=ra-service,OU=service-accounts,OU=alpha,DC=alpha,DC=msae,DC=local
AD User Password: Password!123
Click Test Connection and verify the following message is shown at the top.
CODEActive Directory connection test was successful. MS Auto Enrollment Settings are successfully saved.In the Kerberos Keytabs, click Browse and select the ra-service.keytab file generated in a previous step
Click Test Connection to query the EJBCA-KerberosAuthentication template.
In the Available MS Templates, select:
Select a Template: EJBCA-KerberosAuthentication
Select an End Entity Profile: <EJBCA-KerberosAuthentication-EEP>
Select an Certificate Profile: <EJBCA-KerberosAuthentication-CP>
Click Save.
Repeat the Create MSAE Alias(es) steps on each EJBCA CEP Server and for each SPN set on the CEP and CES Account
Summary
In this step, EJBCA was configured with endpoint listeners which can be contacted by a Windows client requesting a Certificate Enrollment Policy.
Step 3 - Configure CEP Server
An existing powershell module is shipped with version of Windows Server 2019 and later. The following snippets configures a CEP on a single server for testing
In and elevated PowerShell session, update the
Urlparameter and run the following:CODEAdd-CertificateEnrollmentPolicyServer ` -Url https://cepserver01.ejbca.local/ejbca/msae/CEPService?msae-alpha ` -Context Machine ` -AutoEnrollmentEnabledA successful configuration will result in output similiar to the following:
CODEId : -395666580 Url : https://cepserver01.ejbca.local/ejbca/msae/CEPService?msae-alpha AuthType : Kerberos RequireStrongValidation : False AutoEnrollmentEnabled : True IsDefault : False Priority : 1 Context : Machine
Summary
In this step, the Windows server was configured with the EJBCA alias endpoint listeners. Proceed to performed certificate enrollment validation.
Step 4 - Validation
Enrollment through the Microsoft Local Certificate store is the quickest method for testing all components included in an MSAE configuration, which the exception of the Group Policy enforcing autoenrollment. The following steps will determine if the configuration was successful.
In the same powershell session, type certlm and hit enter.
Right-click Person, select All Tasks, and Request New Certificate.
Click Next.
Select the enrollment policy configured in Step 3 - Configure CEP Server.
Select EJBCA-KerberosAuthentication checkbox. If the template is not visible, one of the following may be happening. Confirm the configuration steps before trying again.
It is not properly mapped in the EJBCA MSAE being the selected enrollment policy.
The Issuing CA configured in the alias is not trusted on the Domain.
The current Windows Server does not have autoenrollment permissions on the template.
Click Enroll.
If enrollment is not successful, one of the following may be happening:
Issue with the way the Subject is being constructed in the CSR. (Create Certifiate Template)
Misconfiguration of schema attribute replication to Global Catalog (only when using port 3268/3269). Manually verify Schema Replication.
End Entity Profile or Certificate Authority Policy requrirements not being met. Refer to Part 3a: EJBCA Configuration for the complete setup instructions.
Troubleshooting
Most troubleshooting of the MSAE integration is performed outside of EJBCA generally requires testing kerberos ticket issuance and keytab verification. The purpose of following snippets is to provide a command reference and may not include the complete context around the command’s effectiveness.
Active Directory
List current kvno of the SPN
CODEGet-ADObject -Filter {ServicePrincipalName -like "HTTP/cepserver01.ejbca.local"} -Properties ServicePrincipalName, msDS-KeyVersionNumber | Select-Object Name, ObjectClass, msDS-KeyVersionNumber, ServicePrincipalNameList contents of a keytab
CODEktpass -in $HOME\Desktop\ra-service.keytab
Kerberos
# Dump user kerberos tickets
klist
# Dump machine kerberos tickets
klist -li 0x3e7
# Purge kerberos tickets
klist purge -li 0x3e7
# Dump keytab
ktpass -in <keytab path>
LDAP Bind
The following can be used from an Linux virtual machine with access to Active Directory and the ldapsearch.
Install
Check if
openldap-clientsis already installed.CODE$ sudo dnf list --installed | grep ldap openldap.x86_64 2.4.57-6.amzn2023.0.7 @System openldap-devel.x86_64 2.4.57-6.amzn2023.0.7 @amazonlinuxInstall
openldap-clientsif not already installed.CODE$ sudo dnf install -y openldap-clientsConfigure environment variables
CODE$ sudo dnf install -y openldap-clients
Configure Environment Variables
Set environment variables using the example values below for easier use of the LDAP lookup snippets
# Flat AD
export LDAP_FOREST='dc=msae,dc=local'
export LDAP_FOREST_HOST='msae.local'
export LDAP_FOREST_LDAP="ldap://${LDAP_FOREST_HOST}:389"
export LDAP_FOREST_LDAPS="ldaps://${LDAP_FOREST_HOST}:636"
export LDAP_FOREST_LOGIN="CN=ra-service,OU=service-accounts,OU=msae,${LDAP_FOREST}"
export LDAP_FOREST_PASSWORD='Password!123'
export LDAP_FOREST_COMPUTER='DC01$'
# Parent and Child AD
export LDAP_DOMAIN='DC=alpha,DC=msae,DC=local'
export LDAP_DOMAIN_HOST='alpha.msae.local'
export LDAP_DOMAIN_LDAP="ldap://${LDAP_DOMAIN_HOST}:389"
export LDAP_DOMAIN_LDAPS="ldaps://${LDAP_DOMAIN_HOST}:636"
export LDAP_DOMAIN_LOGIN=CN="alpha-service,OU=service-accounts,OU=alpha,${LDAP_DOMAIN}"
export LDAP_DOMAIN_PASSWORD='Password!123'
export LDAP_DOMAIN_COMPUTER='DC02$'
Lookups
Search for Computer in the Forest domain
CODEldapsearch -x -H ${LDAP_FOREST_LDAP} \ -D ${LDAP_FOREST_LOGIN} \ -w ${LDAP_FOREST_PASSWORD} \ -b ${LDAP_FOREST} "(&(objectclass=computer)(sAMAccountName=${LDAP_FOREST_COMPUTER}))"Search for Computer in Child domain from Forest domain
CODEldapsearch -x -H ${LDAP_FOREST_LDAP} \ -D ${LDAP_FOREST_LOGIN} \ -w ${LDAP_FOREST_PASSWORD} \ -b ${LDAP_DOMAIN} "(&(objectclass=computer)(sAMAccountName=${LDAP_DOMAIN_COMPUTER}))"Search for Computer in the Child domain
CODEldapsearch -x -H ${LDAP_DOMAIN_LDAP} \ -D ${LDAP_DOMAIN_LOGIN} \ -w ${LDAP_DOMAIN_PASSWORD} \ -b ${LDAP_DOMAIN} "(&(objectclass=computer)(sAMAccountName=${LDAP_DOMAIN_COMPUTER}))"Search for Certificate Templates
CODEldapsearch -x -H ${LDAP_FOREST_LDAP} \ -D ${LDAP_DOMAIN_LOGIN} \ -w ${LDAP_DOMAIN_PASSWORD} \ -b "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,${LDAP_FOREST}"
Configuration Samples
# List current kvno of the SPN
Get-ADObject -Filter {ServicePrincipalName -like "*HTTP/cepserver01.ejbca.local*"} -Properties ServicePrincipalName, msDS-KeyVersionNumber |
Select-Object Name, ObjectClass, msDS-KeyVersionNumber, ServicePrincipalName
# List contents of a keytab
ktpass -in $HOME\Desktop\ra-service.keytab
# Set enrollment policy server
Add-CertificateEnrollmentPolicyServer `
-Url https://cepserver01.ejbca.local/ejbca/msae/CEPService?msae-forest `
-Context Machine `
-AutoEnrollmentEnabled
# Search LDAP port for AD User in Child domain
ldapsearch -x -H ldap://msae.local:389 \
-D 'CN=ra-service,OU=service-accounts,OU=msae,DC=msae,DC=local' \
-w 'Password!123' \
-b 'DC=ALPHA,DC=MSAE,DC=LOCAL' '(&(objectclass=computer)(sAMAccountName=DC02))'
# Search GC port for certificate templates
ldapsearch -xLLL -H ldap://msae.local:3268 \
-D 'CN=ra-service,OU=service-accounts,OU=msae,DC=msae,DC=local' \
-w 'Password!123' \
-b 'CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=msae,DC=local'
Next steps
In this tutorial, you learned how to integrate EJBCA MSAE with Active Directory to replicate the full autoenrollment behavior of Microsoft ADCS. You configured MSAE, mapped certificate templates, enabled CEP/CES, and validated successful issuance from EJBCA. With these steps complete, you are ready to support a migration from ADCS to EJBCA, without changing how Windows clients request or renew certificates.
Here is the EJBCA documentation:
https://docs.keyfactor.com/ejbca/latest/microsoft-auto-enrollment-operations
General configurations not included in this guide can be found in the https://docs.keyfactor.com/ejbca/latest/microsoft-auto-enrollment-configuration-guide.
If you are interested in EJBCA Enterprise, read more on Keyfactor EJBCA Enterprise.
If you are interested in EJBCA Community, check out EJBCA Community vs Enterprise or read more on ejbca.org.
If you are an EJBCA Enterprise customer and need support, visit the Keyfactor Support Portal.
Discuss with the EJBCA Community on GitHub Discussions.
Contact us
Request a live demo with one of our experts — whether you want to explore workflows hands-on or discuss your specific needs.