Active Directory Bootstrap - Windows Server 2025 Core
Bootstrap a fresh Active Directory forest on Windows Server 2025 Core for ISE 802.1X EAP-TLS authentication.
|
Architecture Change from Legacy
|
1. Prerequisites
| Requirement | Verification | Status |
|---|---|---|
DC promoted and running |
|
[ ] |
Vault PKI operational |
|
[ ] |
ISE trusts DOMUS-ROOT-CA |
|
[ ] |
SSH access to DC |
|
[ ] |
2. Phase 1: Verify DNS SRV Records
AD requires DNS SRV records for domain functionality. These should auto-register after DC promotion.
2.1. 1.1 Check SRV Records
From Linux workstation, verify all three critical SRV records exist:
dig _ldap._tcp.inside.domusdigitalis.dev SRV
;; ANSWER SECTION:
_ldap._tcp.inside.domusdigitalis.dev. 192 IN SRV 0 100 389 home-dc01.inside.domusdigitalis.dev.
dig _kerberos._tcp.inside.domusdigitalis.dev SRV
;; ANSWER SECTION:
_kerberos._tcp.inside.domusdigitalis.dev. 600 IN SRV 0 100 88 home-dc01.inside.domusdigitalis.dev.
dig _gc._tcp.inside.domusdigitalis.dev SRV
;; ANSWER SECTION:
_gc._tcp.inside.domusdigitalis.dev. 600 IN SRV 0 100 3268 home-dc01.inside.domusdigitalis.dev.
|
What these records mean:
If any are missing, SSSD will show "Offline" and domain operations will fail. |
3. Phase 2: Create OU Structure
3.1. 2.1 Design
Enterprise-grade OU structure following Microsoft’s Enterprise Access Model with tiering:
| Tier | Assets | Compromise Impact |
|---|---|---|
Tier 0 |
DCs, PKI, Identity infrastructure |
Full domain compromise |
Tier 1 |
Servers, applications |
Application/data compromise |
Tier 2 |
Workstations, endpoints |
Single user compromise |
Design principles:
-
Tiering - Separate by security impact
-
OS separation - Different GPOs, management tools, compliance baselines
-
User separation - Admins vs standard users vs service accounts
-
Lifecycle - Staging for new objects, Disabled for decommissioned (audit retention)
-
Delegation - OUs enable delegated administration
3.2. 2.2 Create Top-Level OUs
ssh home-dc01
New-ADOrganizationalUnit -Name "Tier 0 - Identity" -Path "DC=inside,DC=domusdigitalis,DC=dev" -ProtectedFromAccidentalDeletion $true
New-ADOrganizationalUnit -Name "Tier 1 - Servers" -Path "DC=inside,DC=domusdigitalis,DC=dev" -ProtectedFromAccidentalDeletion $true
New-ADOrganizationalUnit -Name "Tier 2 - Endpoints" -Path "DC=inside,DC=domusdigitalis,DC=dev" -ProtectedFromAccidentalDeletion $true
New-ADOrganizationalUnit -Name "User Accounts" -Path "DC=inside,DC=domusdigitalis,DC=dev" -ProtectedFromAccidentalDeletion $true
New-ADOrganizationalUnit -Name "Groups" -Path "DC=inside,DC=domusdigitalis,DC=dev" -ProtectedFromAccidentalDeletion $true
New-ADOrganizationalUnit -Name "Staging" -Path "DC=inside,DC=domusdigitalis,DC=dev" -ProtectedFromAccidentalDeletion $true
New-ADOrganizationalUnit -Name "Disabled" -Path "DC=inside,DC=domusdigitalis,DC=dev" -ProtectedFromAccidentalDeletion $true
3.3. 2.3 Create Tier 0 Nested OUs
New-ADOrganizationalUnit -Name "Service Accounts" -Path "OU=Tier 0 - Identity,DC=inside,DC=domusdigitalis,DC=dev" -ProtectedFromAccidentalDeletion $true
3.4. 2.4 Create Tier 1 Nested OUs (Servers)
New-ADOrganizationalUnit -Name "Linux" -Path "OU=Tier 1 - Servers,DC=inside,DC=domusdigitalis,DC=dev" -ProtectedFromAccidentalDeletion $true
New-ADOrganizationalUnit -Name "Windows" -Path "OU=Tier 1 - Servers,DC=inside,DC=domusdigitalis,DC=dev" -ProtectedFromAccidentalDeletion $true
3.5. 2.5 Create Tier 2 Nested OUs (Endpoints)
New-ADOrganizationalUnit -Name "Workstations" -Path "OU=Tier 2 - Endpoints,DC=inside,DC=domusdigitalis,DC=dev" -ProtectedFromAccidentalDeletion $true
New-ADOrganizationalUnit -Name "Linux" -Path "OU=Workstations,OU=Tier 2 - Endpoints,DC=inside,DC=domusdigitalis,DC=dev" -ProtectedFromAccidentalDeletion $true
New-ADOrganizationalUnit -Name "Windows" -Path "OU=Workstations,OU=Tier 2 - Endpoints,DC=inside,DC=domusdigitalis,DC=dev" -ProtectedFromAccidentalDeletion $true
New-ADOrganizationalUnit -Name "Mac" -Path "OU=Workstations,OU=Tier 2 - Endpoints,DC=inside,DC=domusdigitalis,DC=dev" -ProtectedFromAccidentalDeletion $true
New-ADOrganizationalUnit -Name "Mobile" -Path "OU=Tier 2 - Endpoints,DC=inside,DC=domusdigitalis,DC=dev" -ProtectedFromAccidentalDeletion $true
3.6. 2.6 Create User Accounts Nested OUs
|
We use "User Accounts" instead of "Users" to avoid conflict with the default AD container |
New-ADOrganizationalUnit -Name "Admins" -Path "OU=User Accounts,DC=inside,DC=domusdigitalis,DC=dev" -ProtectedFromAccidentalDeletion $true
New-ADOrganizationalUnit -Name "Standard" -Path "OU=User Accounts,DC=inside,DC=domusdigitalis,DC=dev" -ProtectedFromAccidentalDeletion $true
New-ADOrganizationalUnit -Name "Service Accounts" -Path "OU=User Accounts,DC=inside,DC=domusdigitalis,DC=dev" -ProtectedFromAccidentalDeletion $true
3.7. 2.7 Create Groups Nested OUs
New-ADOrganizationalUnit -Name "Security" -Path "OU=Groups,DC=inside,DC=domusdigitalis,DC=dev" -ProtectedFromAccidentalDeletion $true
New-ADOrganizationalUnit -Name "Distribution" -Path "OU=Groups,DC=inside,DC=domusdigitalis,DC=dev" -ProtectedFromAccidentalDeletion $true
3.8. 2.8 Verify OUs
Get-ADOrganizationalUnit -Filter * | Select-Object Name, DistinguishedName | Format-Table -AutoSize
Name DistinguishedName
---- -----------------
Domain Controllers OU=Domain Controllers,DC=inside,DC=domusdigitalis,DC=dev
Tier 0 - Identity OU=Tier 0 - Identity,DC=inside,DC=domusdigitalis,DC=dev
Service Accounts OU=Service Accounts,OU=Tier 0 - Identity,DC=inside,DC=domusdigitalis,DC=dev
Tier 1 - Servers OU=Tier 1 - Servers,DC=inside,DC=domusdigitalis,DC=dev
Linux OU=Linux,OU=Tier 1 - Servers,DC=inside,DC=domusdigitalis,DC=dev
Windows OU=Windows,OU=Tier 1 - Servers,DC=inside,DC=domusdigitalis,DC=dev
Tier 2 - Endpoints OU=Tier 2 - Endpoints,DC=inside,DC=domusdigitalis,DC=dev
Workstations OU=Workstations,OU=Tier 2 - Endpoints,DC=inside,DC=domusdigitalis,DC=dev
Linux OU=Linux,OU=Workstations,OU=Tier 2 - Endpoints,DC=inside,DC=domusdigitalis,DC=dev
Windows OU=Windows,OU=Workstations,OU=Tier 2 - Endpoints,DC=inside,DC=domusdigitalis,DC=dev
Mac OU=Mac,OU=Workstations,OU=Tier 2 - Endpoints,DC=inside,DC=domusdigitalis,DC=dev
Mobile OU=Mobile,OU=Tier 2 - Endpoints,DC=inside,DC=domusdigitalis,DC=dev
User Accounts OU=User Accounts,DC=inside,DC=domusdigitalis,DC=dev
Admins OU=Admins,OU=User Accounts,DC=inside,DC=domusdigitalis,DC=dev
Standard OU=Standard,OU=User Accounts,DC=inside,DC=domusdigitalis,DC=dev
Service Accounts OU=Service Accounts,OU=User Accounts,DC=inside,DC=domusdigitalis,DC=dev
Groups OU=Groups,DC=inside,DC=domusdigitalis,DC=dev
Security OU=Security,OU=Groups,DC=inside,DC=domusdigitalis,DC=dev
Distribution OU=Distribution,OU=Groups,DC=inside,DC=domusdigitalis,DC=dev
Staging OU=Staging,DC=inside,DC=domusdigitalis,DC=dev
Disabled OU=Disabled,DC=inside,DC=domusdigitalis,DC=dev
4. Phase 3: Create Security Groups
Security groups are used by ISE for authorization policies. Groups are organized by object type (Computers, Servers, Users) for clarity.
|
Naming Convention:
|
4.1. 3.1 Create Computer Groups (Workstations)
These groups contain computer objects (e.g., modestus-razer$). ISE checks these for 802.1X machine authentication.
New-ADGroup -Name "GRP-Computers-Linux-Admin" -GroupScope Global -GroupCategory Security -Path "OU=Security,OU=Groups,DC=inside,DC=domusdigitalis,DC=dev" -Description "Linux admin workstations - Tier 2 privileged"
New-ADGroup -Name "GRP-Computers-Linux-Standard" -GroupScope Global -GroupCategory Security -Path "OU=Security,OU=Groups,DC=inside,DC=domusdigitalis,DC=dev" -Description "Linux standard workstations"
New-ADGroup -Name "GRP-Computers-Windows" -GroupScope Global -GroupCategory Security -Path "OU=Security,OU=Groups,DC=inside,DC=domusdigitalis,DC=dev" -Description "Windows workstations"
New-ADGroup -Name "GRP-Computers-Mac" -GroupScope Global -GroupCategory Security -Path "OU=Security,OU=Groups,DC=inside,DC=domusdigitalis,DC=dev" -Description "Mac workstations"
4.2. 3.2 Create Server Groups
New-ADGroup -Name "GRP-Servers-Linux" -GroupScope Global -GroupCategory Security -Path "OU=Security,OU=Groups,DC=inside,DC=domusdigitalis,DC=dev" -Description "Linux servers - network access"
New-ADGroup -Name "GRP-Servers-Windows" -GroupScope Global -GroupCategory Security -Path "OU=Security,OU=Groups,DC=inside,DC=domusdigitalis,DC=dev" -Description "Windows servers - network access"
4.3. 3.3 Create User Groups
These groups contain user objects for user-based authorization policies.
New-ADGroup -Name "GRP-Users-Admins" -GroupScope Global -GroupCategory Security -Path "OU=Security,OU=Groups,DC=inside,DC=domusdigitalis,DC=dev" -Description "Admin users - privileged access"
New-ADGroup -Name "GRP-Users-Standard" -GroupScope Global -GroupCategory Security -Path "OU=Security,OU=Groups,DC=inside,DC=domusdigitalis,DC=dev" -Description "Standard users"
4.4. 3.4 Verify Groups
Get-ADGroup -Filter 'Name -like "GRP-*"' | Select-Object Name, GroupScope, DistinguishedName | Format-Table -AutoSize
Name GroupScope DistinguishedName
---- ---------- -----------------
GRP-Computers-Linux-Admin Global CN=GRP-Computers-Linux-Admin,OU=Security,OU=Groups,DC=inside,DC=domusdigitalis,DC=dev
GRP-Computers-Linux-Standard Global CN=GRP-Computers-Linux-Standard,OU=Security,OU=Groups,DC=inside,DC=domusdigitalis,DC=dev
GRP-Computers-Windows Global CN=GRP-Computers-Windows,OU=Security,OU=Groups,DC=inside,DC=domusdigitalis,DC=dev
GRP-Computers-Mac Global CN=GRP-Computers-Mac,OU=Security,OU=Groups,DC=inside,DC=domusdigitalis,DC=dev
GRP-Servers-Linux Global CN=GRP-Servers-Linux,OU=Security,OU=Groups,DC=inside,DC=domusdigitalis,DC=dev
GRP-Servers-Windows Global CN=GRP-Servers-Windows,OU=Security,OU=Groups,DC=inside,DC=domusdigitalis,DC=dev
GRP-Users-Admins Global CN=GRP-Users-Admins,OU=Security,OU=Groups,DC=inside,DC=domusdigitalis,DC=dev
GRP-Users-Standard Global CN=GRP-Users-Standard,OU=Security,OU=Groups,DC=inside,DC=domusdigitalis,DC=dev
|
ISE Policy Mapping Each group maps to an ISE authorization policy:
|
5. Phase 4: Create User Account
Your admin account goes in OU=Admins,OU=User Accounts (privileged accounts).
5.1. 4.1 Create Admin Account
New-ADUser -Name "Evan Rosado" -GivenName "Evan" -Surname "Rosado" -SamAccountName "evanusmodestus" -UserPrincipalName "evanusmodestus@inside.domusdigitalis.dev" -Path "OU=Admins,OU=User Accounts,DC=inside,DC=domusdigitalis,DC=dev" -AccountPassword (Read-Host -AsSecureString "Password") -Enabled $true -PasswordNeverExpires $true
5.3. 4.3 Verify
Get-ADUser evanusmodestus -Properties MemberOf, DistinguishedName | Select-Object Name, SamAccountName, DistinguishedName
Name SamAccountName DistinguishedName
---- -------------- -----------------
Evan Rosado evanusmodestus CN=Evan Rosado,OU=Admins,OU=User Accounts,DC=inside,DC=domusdigitalis,DC=dev
Get-ADPrincipalGroupMembership evanusmodestus | Select-Object Name
Name
----
Domain Users
Domain Admins
6. Phase 5: Join ISE to Active Directory
6.1. 5.1 Prerequisites on ISE
ISE requires:
-
DNS resolution to DC (via BIND or VyOS forwarding)
-
NTP synchronized with DC (Kerberos requirement)
-
Outbound connectivity to DC ports: 88, 389, 464, 636
6.2. 5.2 Pre-Create ISE Computer Account in AD
Before ISE can join the domain, create a computer account in AD:
New-ADComputer -Name "ISE-02" -SamAccountName "ISE-02$" `
-Path "OU=Linux,OU=Tier 1 - Servers,DC=inside,DC=domusdigitalis,DC=dev" `
-Description "Cisco ISE Secondary PAN"
Verify:
Get-ADComputer ISE-02
DistinguishedName : CN=ISE-02,OU=Linux,OU=Tier 1 - Servers,DC=inside,DC=domusdigitalis,DC=dev
Enabled : True
Name : ISE-02
SamAccountName : ISE-02$
6.3. 5.3 Join Domain via GUI
ISE GUI path:
-
Administration > Identity Management > External Identity Sources > Active Directory
-
Click Add
-
Enter:
-
Join Point Name:
INSIDE-AD -
Active Directory Domain:
inside.domusdigitalis.dev
-
-
Click Submit
-
When prompted, enter credentials:
evanusmodestus@inside.domusdigitalis.dev
6.4. 5.4 Join Domain via netapi (Alternative)
If the join point already exists (e.g., from a previous DC), rejoin via API:
dsource d000 dev/network
netapi ise api-call openapi PUT '/api/v1/active-directory/INSIDE-AD/join' \
--data "{
\"operationType\": \"join\",
\"adminUser\": \"evanusmodestus\",
\"adminPassword\": \"$(gopass show -o ADMINISTRATIO/domus/ad/evanusmodestus)\"
}"
| This command returns no output on success. Verify by searching for AD groups. |
6.5. 5.5 Verify Join via netapi
dsource d000 dev/network
netapi ise ers ad
Join Point: INSIDE-AD
Domain: inside.domusdigitalis.dev
Status: Operational
6.6. 5.6 Add AD Groups to ISE
After joining, import the security groups. First verify ISE can see them:
netapi ise search-ad-groups "INSIDE-AD" "GRP"
Then add the groups:
netapi ise add-ad-groups "INSIDE-AD" "GRP-Computers-Linux-Admin"
netapi ise add-ad-groups "INSIDE-AD" "GRP-Computers-Linux-Standard"
netapi ise add-ad-groups "INSIDE-AD" "GRP-Computers-Windows"
netapi ise add-ad-groups "INSIDE-AD" "GRP-Computers-Mac"
netapi ise add-ad-groups "INSIDE-AD" "GRP-Servers-Linux"
netapi ise add-ad-groups "INSIDE-AD" "GRP-Servers-Windows"
netapi ise add-ad-groups "INSIDE-AD" "GRP-Users-Admins"
netapi ise add-ad-groups "INSIDE-AD" "GRP-Users-Standard"
Verify:
netapi ise get-ad-groups "INSIDE-AD"
Or via GUI:
-
Administration > Identity Management > External Identity Sources > Active Directory
-
Select INSIDE-AD
-
Go to Groups tab
-
Click Add > Select Groups from Directory
-
Search for
GRP-Computers-Linux-Admin -
Select and add
7. Phase 6: Domain Join Linux Workstations
7.1. 6.1 Verify Prerequisites
From Linux workstation:
# DNS resolution
host inside.domusdigitalis.dev
host home-dc01.inside.domusdigitalis.dev
# Kerberos test
kinit evanusmodestus@INSIDE.DOMUSDIGITALIS.DEV
klist
7.2. 6.2 Join Domain
Follow Domain Join Runbook (ise-linux) for full procedure.
Quick reference:
sudo net ads join -U evanusmodestus@INSIDE.DOMUSDIGITALIS.DEV
7.3. 6.3 Add Computer to Security Group
After domain join, add computer to ISE authorization group:
ssh home-dc01 'powershell -Command "Add-ADGroupMember -Identity \"GRP-Linux-Admin-Workstations\" -Members \"modestus-razer$\""'
ssh home-dc01 'powershell -Command "Add-ADGroupMember -Identity \"GRP-Linux-Admin-Workstations\" -Members \"modestus-p50$\""'
ssh home-dc01 'powershell -Command "Add-ADGroupMember -Identity \"GRP-Linux-Admin-Workstations\" -Members \"modestus-aw$\""'
8. Phase 7: ISE Authorization Policy
Create authorization policy using AD group membership.
8.1. 7.1 Create Authorization Profile
netapi ise create-authz-profile "Linux-Admin-VLAN10" \
--vlan 10 \
--description "Linux admin workstations - VLAN 10"
8.2. 7.2 Create Authorization Rule
netapi ise create-authz-rule "Linux-Admin-Workstations-EAP-TLS" \
--policy-set "Domus-Wired-802.1X" \
--condition "AD:ExternalGroups CONTAINS inside.domusdigitalis.dev/Groups/GRP-Linux-Admin-Workstations" \
--profile "Linux-Admin-VLAN10"
Or via GUI:
-
Policy > Policy Sets > Domus-Wired-802.1X
-
Authorization Policy section
-
Add rule:
-
Name:
Linux-Admin-Workstations-EAP-TLS -
Condition:
AD:ExternalGroups CONTAINS inside.domusdigitalis.dev/Groups/GRP-Linux-Admin-Workstations -
Profile:
Linux-Admin-VLAN10
-
9. Phase 8: Verification Checklist
| Item | Command | Status |
|---|---|---|
DNS SRV records |
|
[ ] |
OUs created |
|
[ ] |
Security groups created |
|
[ ] |
User account created |
|
[ ] |
ISE joined to AD |
|
[ ] |
AD groups in ISE |
ISE GUI > AD > Groups tab |
[ ] |
Workstations domain-joined |
|
[ ] |
Computers in AD group |
|
[ ] |
Authorization policy created |
ISE GUI > Policy Sets |
[ ] |
802.1X authentication working |
|
[ ] |
10. PKI Architecture Reference
|
This deployment uses Vault PKI, NOT Windows AD CS.
See Vault PKI Certificate Issuance for certificate procedures. |
11. Appendix A: Automation Scripts
PowerShell scripts for creating and resetting the AD structure. See AD Bootstrap Scripts for full source code with explanations.
|
Reset script is destructive. Use only in lab/test environments. |
11.1. A.1 Script Locations
| Script | Purpose |
|---|---|
|
Delete all OUs, groups, user (with optional recreate) |
|
Create all OUs and groups (idempotent, skips existing) |
11.2. A.2 Usage
Copy scripts to DC:
scp scripts/ad-bootstrap-*.ps1 home-dc01:C:/Users/Administrator/
11.2.1. Create Script
powershell -ExecutionPolicy Bypass -File ad-bootstrap-create.ps1 -WhatIf
powershell -ExecutionPolicy Bypass -File ad-bootstrap-create.ps1
11.2.2. Reset Script
powershell -ExecutionPolicy Bypass -File ad-bootstrap-reset.ps1 -WhatIf
powershell -ExecutionPolicy Bypass -File ad-bootstrap-reset.ps1
powershell -ExecutionPolicy Bypass -File ad-bootstrap-reset.ps1 -Recreate
11.3. A.3 What It Does
-
Phase 1: Removes user account (
evanusmodestus) -
Phase 2: Removes all 8 security groups (
GRP-*) -
Phase 3: Removes all 21 OUs (nested first, then parents)
-
Phase 4: (with
-Recreate) Rebuilds entire structure
|
The |