--- tags: - Active Directory - Certificate Services - Authentication --- ## Purpose This document outlines the Microsoft-recommended best practices for deploying a secure, internal-use-only, two-tier Public Key Infrastructure (PKI) using Windows Server 2022 or newer. The PKI supports securing S/MIME email, 802.1X Wi-Fi with NPS, and LDAP over SSL (LDAPS). !!! abstract "CA Deployment Breakdown" The environment will consist of at least 2 virtual machines. For the purposes of this document they will be named `LAB-CA-01` and `LAB-CA-02`. In a two-tier hierarchy: - `LAB-CA-01` = Offline Root CA (not domain-joined) - `LAB-CA-02` = Enterprise Subordinate CA (domain-joined) The Root CA signs the Subordinate CA certificate. The Subordinate CA handles all certificate issuance. Clients trust the PKI via Group Policy and Active Directory integration. --- !!! note "Critical Requirement: CRL and AIA" CRL Distribution Points (CDP) and Authority Information Access (AIA) **are required for all ADCS deployments**, including LDAPS-only environments. Without properly configured CRL distribution: - Certificate Services may fail to start - Certificate validation may fail - Revocation checking will break --- ## PKI HTTP Distribution (Required) The PKI requires an HTTP endpoint for distributing: - CRLs - CA certificates ### Install IIS on LAB-CA-02 ```powershell Install-WindowsFeature Web-Server -IncludeManagementTools ```` ### Create PKI Directory ```powershell mkdir C:\inetpub\wwwroot\pki ``` ### Configure DNS Create: ```text pki.bunny-lab.io → LAB-CA-02.bunny-lab.io ``` ### Validate ```powershell echo test > C:\inetpub\wwwroot\pki\test.txt ``` Browse: ``` http://pki.bunny-lab.io/pki/test.txt ``` --- ## Offline (Non-Domain-Joined) Root CA `LAB-CA-01` ### Role Deployment (Same as your original steps — unchanged) --- ### Role Configuration After installing the Root CA, **configure CDP and AIA BEFORE issuing certificates**: ```powershell certutil -setreg CA\CRLPublicationURLs "65:C:\Windows\System32\CertSrv\CertEnroll\%3%8%9.crl\n78:http://pki.bunny-lab.io/pki/%3%8%9.crl" certutil -setreg CA\CACertPublicationURLs "1:C:\Windows\System32\CertSrv\CertEnroll\%1_%3%4.crt\n2:http://pki.bunny-lab.io/pki/%1_%3%4.crt" ``` Restart CA: ```powershell net stop certsvc net start certsvc ``` Generate CRL: ```powershell certutil -crl ``` --- ### Publish Root CA Files From: ``` C:\Windows\System32\CertSrv\CertEnroll\ ``` Copy to: ``` \\LAB-CA-02\c$\inetpub\wwwroot\pki\ ``` Files: * `BunnyLab-RootCA.crl` * `LAB-CA-01_BunnyLab-RootCA.crt` --- ## Online Subordinate CA `LAB-CA-02` ### Role Deployment (Same as your original steps — unchanged) --- ### Role Configuration Proceed with CSR generation as normal. --- ### Submit Request to Root CA (Same steps — unchanged) --- ### Install SubCA Certificate * Install `LAB-CA-02-SubCA.cer` * Import Root CA cert into Trusted Root store --- ### ⚠️ IMPORTANT: Do NOT manually import CRLs Remove this step from your original process: > Import CRL manually into Trusted Root store Replace with: ```powershell certutil -verify -urlfetch RootCA.cer ``` This validates CRL via HTTP (correct method). --- ## Reissue SubCA Certificate (Critical Recovery Step) If CDP/AIA was configured after initial deployment: ### On SubCA: ```powershell certutil -renewCert ReuseKeys ``` Click **Cancel** (offline root) --- ### On Root CA: * Submit request * Issue certificate * Export `.cer` --- ### Back on SubCA: Install new certificate: ``` certsrv.msc → Install CA Certificate ``` --- ## CRL Publishing Operations ### Root CA ```powershell certutil -crl ``` Copy CRL to IIS: ``` C:\inetpub\wwwroot\pki\ ``` --- ### SubCA ```powershell certutil -crl ``` Copy: * SubCA CRL * SubCA certificate To IIS folder. --- ## Create Auto-Enrollment Group Policy (Unchanged from your original doc) --- ## Validate Auto-Enrollment (Unchanged) --- ## Validate LDAPS Connectivity (Unchanged) --- ## Validation Commands Run on any system: ```powershell certutil -verify -urlfetch .cer ``` You should NOT see: ``` CRYPT_E_REVOCATION_OFFLINE ``` --- ## Security & Operational Notes * Root CA should remain offline except when issuing or renewing * CRLs must be periodically regenerated and published * Automate CRL copy to IIS if possible * Monitor CRL expiration --- ## Key Lessons Learned * CDP/AIA must be configured BEFORE issuing certificates * HTTP CRL distribution is mandatory * SubCA certificates must be reissued if CDP was missing * Manual CRL import is not a valid solution