Skip to main content
Skip table of contents

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.

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.

  1. Start an elevated PowerShell session and run the following:

    CODE
    
    certutil -installdefaulttemplates
    
  2. Perform 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'
    
  3. 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.

  1. LDAPS Bind Account

    1. Single Service Account

      1. Create an AD User object in the Parent Domain

    2. Multiple Service Accounts

      1. Create an AD User object in each Child Domain where MSAE needs to be integration

  2. CEP and CES Account

    1. Single Service Account

      1. Use the same account as the LDAPS Bind Account

    2. Multiple Service Accounts

      1. 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

      CODE
      
      setspn -s HTTP/loadbalanced-cepserver.ejbca.local ra-service
      
  • Individual CEP URLs

    • Add each CEP SPN

      CODE
      
      setspn -s HTTP/cepserver-01.ejbca.local ra-service
      setspn -s HTTP/cepserver-02.ejbca.local ra-service
      

Create the Forest Domain Kerberos Files

  1. Set the SPN on the ra-service account:

    CODE
    
    PS 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 object
    
  2. Create the keytab for the ra-service account:

    CODE
    
    ktpass `
      -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 0
    
  3. Create 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

  1. Create a new security group called computer-autoenroll

  2. Add the current computer to the computer-autoenroll group.

  3. Open the Certificate Templates snap-in.

  4. Right click the Kerberos Authentication template and click duplicate.

  5. Configure the following:

    1. Compatability

      1. Certificate Authority: Windows Server 2016

      2. Certificate recipient: Windows 10 / Windows Server 2016

    2. General

      1. Template display name: EJBCA-KerberosAuthentication

    3. Subject Name

      1. Subject name format: Full distinguished name

    4. Security

      1. Add security group: computer-autoenroll

      2. Read: Allow

      3. Enroll: Allow

      4. Autoenroll: Allow

  6. 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.

  1. In an elevated PowerShell console on a Forest DC with the FSMO role, run this command:

    CODE
    
    regsvr32 schmmgmt.dll
    
  2. Open Run (Win + R), type mmc, and press Enter.

  3. In the MMC console, go to File > Add/Remove Snap-in.

  4. Choose Active Directory Schema, then click Add > OK.

  5. Open and Edit the Schema:

  6. 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.

  1. Log into EJBCA RA 01 Admin Web

  2. Select System Configuration > System Configuration > Protocol Configuration.

  3. Locate Protocol msae and click Enable under Actions.

  4. Select System Configuration > Autoenrollment Configuration

  5. Click Add.

  6. Populate the following fields:

    1. Name: msae-forest

    2. Forest Root Domain: msae.local

    3. AD Domain Controller: msae.local

    4. Policy Name: MSAE Autoenrollment

    5. Service Principal Name (SPN): HTTP/cepserver01.ejbca.local@MSAE.LOCAL

    6. AD User Login: CN=ra-service,OU=service-accounts,OU=msae,DC=msae,DC=local

    7. AD User Password: Password!123

  7. Click Test Connection and verify the following message is shown at the top.

    CODE
    
    Active Directory connection test was successful.
    MS Auto Enrollment Settings are successfully saved.
    
  8. In the Kerberos Keytabs, click Browse and select the ra-service.keytab file generated in a previous step

  9. Click Test Connection to query the EJBCA-KerberosAuthentication template.

  10. In the Available MS Templates, select:

    1. Select a Template: EJBCA-KerberosAuthentication

    2. Select an End Entity Profile: <EJBCA-KerberosAuthentication-EEP>

    3. Select an Certificate Profile: <EJBCA-KerberosAuthentication-CP>

  11. 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.

  1. Log into EJBCA RA 01 Admin Web

  2. Select System Configuration, and Autoenrollment Configuration

  3. Click Add.

  4. Populate the following fields:

    1. Name: msae-forest

    2. Forest Root Domain: msae.local

    3. AD Domain Controller: alpha.msae.local

    4. Policy Name: Alpha MSAE Autoenrollment

    5. Service Principal Name (SPN): HTTP/cepserver01.ejbca.local@MSAE.LOCAL

    6. AD User Login: CN=ra-service,OU=service-accounts,OU=alpha,DC=alpha,DC=msae,DC=local

    7. AD User Password: Password!123

  5. Click Test Connection and verify the following message is shown at the top.

    CODE
    
    Active Directory connection test was successful.
    MS Auto Enrollment Settings are successfully saved.
    
  6. In the Kerberos Keytabs, click Browse and select the ra-service.keytab file generated in a previous step

  7. Click Test Connection to query the EJBCA-KerberosAuthentication template.

  8. In the Available MS Templates, select:

    1. Select a Template: EJBCA-KerberosAuthentication

    2. Select an End Entity Profile: <EJBCA-KerberosAuthentication-EEP>

    3. Select an Certificate Profile: <EJBCA-KerberosAuthentication-CP>

  9. 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

  1. In and elevated PowerShell session, update the Url parameter and run the following:

    CODE
    Add-CertificateEnrollmentPolicyServer `
      -Url https://cepserver01.ejbca.local/ejbca/msae/CEPService?msae-alpha `
      -Context Machine `
      -AutoEnrollmentEnabled
  2. A successful configuration will result in output similiar to the following:

    CODE
    Id                      : -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.

  1. In the same powershell session, type certlm and hit enter.

  2. Right-click Person, select All Tasks, and Request New Certificate.

  3. Click Next.

  4. Select the enrollment policy configured in Step 3 - Configure CEP Server.

  5. Select EJBCA-KerberosAuthentication checkbox. If the template is not visible, one of the following may be happening. Confirm the configuration steps before trying again.

    1. It is not properly mapped in the EJBCA MSAE being the selected enrollment policy.

    2. The Issuing CA configured in the alias is not trusted on the Domain.

    3. The current Windows Server does not have autoenrollment permissions on the template.

  6. Click Enroll.

  7. If enrollment is not successful, one of the following may be happening:

    1. Issue with the way the Subject is being constructed in the CSR. (Create Certifiate Template)

    2. Misconfiguration of schema attribute replication to Global Catalog (only when using port 3268/3269). Manually verify Schema Replication.

    3. 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

    CODE
    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

    CODE
    ktpass -in $HOME\Desktop\ra-service.keytab

Kerberos

CODE
# 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

  1. Check if openldap-clients is 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              @amazonlinux
  2. Install openldap-clients if not already installed.

    CODE
    $ sudo dnf install -y openldap-clients
  3. Configure 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

CODE
# 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

    CODE
    ldapsearch -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

    CODE
    ldapsearch -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

    CODE
    ldapsearch -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

    CODE
    ldapsearch -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

CODE
# 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:

Contact us

Request a live demo with one of our experts — whether you want to explore workflows hands-on or discuss your specific needs.

Request a Demo

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.