Runbook: ISE 3.5 Deployment

Last Updated

2026-02-11

Owner

EvanusModestus

Frequency

As Needed (Major Upgrade)


Last Updated

2026-02-11

Owner

EvanusModestus

Frequency

As Needed (Major Upgrade)


1. Purpose

Deploy Cisco ISE 3.5 (ise-02) on kvm-02, with:

  • Full Windows Server 2025 AD integration (native support in 3.5)

  • DOMUS PKI certificates (Vault-issued)

  • Linux 802.1X EAP-TLS authentication

  • Resource isolation via KVM CPU pinning

This is a migration deployment. ise-02 remains operational until ise-01 is verified, then decommissioned.

2. Prerequisites

  • ISE 3.5 ISO downloaded (NOT OVA - OVA is VMware only)

  • ise-01 backup completed (pre-ise35-ha on nas-01)

  • DNS A record for ise-01.inside.domusdigitalis.dev

  • IP reservation for ise-01 (10.50.1.20 or allocated)

  • Vault PKI accessible (vault-01)

  • home-dc01 (Windows Server 2025) operational

  • gopass credentials accessible

2.1. Credentials Reference (gopass v3)

All credentials needed for ISE setup:

Purpose gopass Path Usage Phase

ISE-01 Admin (GUI)

v3/domains/d000/identity/ise/ise-01/admin

Phase 3 (Setup Wizard)

ISE-01 CLI

v3/domains/d000/identity/ise/ise-01/cli

Phase 3, 3a (SSH access)

ISE-01 DataConnect

v3/domains/d000/identity/ise/ise-01/dataconnect

Post-install (analytics)

ISE-02 Admin (GUI)

v3/domains/d000/identity/ise/ise-02/admin

Phase 3 (Setup Wizard)

ISE-02 CLI

v3/domains/d000/identity/ise/ise-02/cli

Phase 3, 3a (SSH access)

ISE-02 DataConnect

v3/domains/d000/identity/ise/ise-02/dataconnect

Post-install (analytics)

ISE Backup Key

dsource d000 dev/storage$ISE_BACKUP_KEY

Phase 1 (Backup), Phase 3a (Restore)

AD Administrator

v3/domains/d000/identity/ad/administrator

Phase 5 (AD Join)

WLC Admin

v3/domains/d000/network/wlc/wlc-01

Phase 6 (NADs)

Keycloak Admin

v2/DOMUS/servers/keycloak-01

Phase 5a (SAML SSO)

Quick Access Commands
# ISE admin password (for setup wizard)
gopass show -o v2/DOMUS/servers/ise-01/admin

# AD administrator (for domain join)
gopass show -o v2/DOMUS/ad/administrator

# ISE ERS API password
gopass show -o v2/DOMUS/servers/ise-01/ers

The v2/DOMUS/servers/ise-01 entries are already created:

  • v2/DOMUS/servers/ise-01/admin - Admin GUI password

  • v2/DOMUS/servers/ise-01/cli - SSH CLI password

  • v2/DOMUS/servers/ise-01/ers - ERS API credentials

  • v2/DOMUS/servers/ise-01/dataconnect - DataConnect credentials

2.2. ISE 3.5 Download Options

Download from Cisco Software Center:

File Disk Size Use Case

Cisco-vISE-300-3.5.0.527.ova

300GB

VMware ESXi ONLY

Cisco-vISE-600-3.5.0.527.ova

600GB

VMware ESXi ONLY

Cisco-ISE-3.5.0.527.SPA.x86_64.iso

N/A

KVM/QEMU (required)

OVA files are VMware ESXi format ONLY. They will NOT work on KVM.

For non-VMware hypervisors (KVM, Nutanix AHV, OpenShift), the standard ISO installation method is required.

OVA contains VMware-specific disk formats (VMDK) and drivers (VMXNET3, PVSCSI) that don’t work with KVM’s VirtIO drivers. Converting OVA to qcow2 results in dracut emergency shell - the VM cannot find the root filesystem.

Required for KVM: Download the ISO image: Cisco-ISE-3.5.0.527.SPA.x86_64.iso

2.3. Transfer ISO to KVM Host

2.3.1. Option 1: Download Directly to KVM Host

# SSH to KVM host
ssh kvm-02.inside.domusdigitalis.dev

# Download ISO directly (if browser auth not required)
cd /mnt/nas/isos
curl -O https://software.cisco.com/download/...Cisco-ISE-3.5.0.527.SPA.x86_64.iso

2.3.2. Option 2: Download to Workstation, Transfer to KVM

# On workstation: download ISO via browser to ~/Downloads

# Transfer directly to NAS (user has write access)
rsync -avP ~/Downloads/Cisco-ISE-3.5.0.527.SPA.x86_64.iso kvm-02.inside.domusdigitalis.dev:/mnt/nas/isos/

kvm-02 uses NAS storage at /mnt/nas/isos/ for ISOs and /mnt/nas/vms/ for disk images. User has direct write access (no sudo required for transfer).

Use rsync -avP for large files - it shows progress and can resume interrupted transfers.

Expected Output (rsync ~14GB ISO)
sending incremental file list
Cisco-ISE-3.5.0.527.SPA.x86_64.iso
 14,142,846,976 100%   33.88MB/s    0:06:38

2.4. Current Infrastructure

Component Current Target

ISE Version

3.4 (ise-01)

3.5 (ise-02)

AD Integration

Failed (WS2025 incompatible)

Native support

PKI

DOMUS PKI (Vault)

DOMUS PKI (Vault)

CPU Pinning

ise-02 on CPUs 6-9

ise-01 on CPUs 6-9

3. Phase 1: Backup Current Configuration

Before migration, create a full ISE backup. This captures everything: policies, NADs, certificates, endpoint groups, and all configuration.

3.1. Full ISE Backup (Required)

dsource d000 dev/storage
netapi ise backup --repo nas-01 --name "pre-ise34-migration" --wait
Expected Output
Repository: nas-01 (NFS)
Server: 10.50.1.70:/volume1/ise_backups
Name: pre-ise34-migration

✓ Backup initiated successfully
Waiting for backup to complete...
✓ Backup completed: pre-ise34-migration

This backup is restorable to ise-01 after installation. It includes:

  • All policy sets and authorization rules

  • Network devices (NADs) with RADIUS secrets

  • Endpoint identity groups

  • Authorization profiles

  • System certificates (exportable)

  • Trusted CA certificates

3.2. Optional: Export for Reference

These exports are optional - useful for reference during manual reconfiguration, but the full backup above is what you’d restore from:

# Only if you want JSON exports for documentation
netapi ise get-policy-sets --format json > /tmp/ise-02-policy-sets.json
netapi ise get-network-devices --format json > /tmp/ise-02-network-devices.json

3.3. Screenshot Current Certificates (Optional)

Capture ISE Admin UI screenshots for reference:

  • Administration > System > Certificates > System Certificates

  • Administration > System > Certificates > Trusted Certificates

4. Phase 2: KVM VM Creation with Resource Isolation

Critical: Configure CPU pinning BEFORE booting ISE ISO. ISE installation is CPU-intensive and can starve other VMs (pfSense, WLC) causing network outages.

4.1. Cleanup Failed VM (If Needed)

If a previous VM creation failed, remove it before retrying:

# Remove VM definition only (keep qcow2)
sudo virsh undefine ise-01

# Or remove VM definition AND storage
sudo virsh undefine ise-01 --remove-all-storage

4.2. Create VM with virt-install

Install from ISO - do NOT use --import with converted OVA disks.

CPU Pinning is CRITICAL - ISE is CPU-sensitive. Without pinning, contention causes RADIUS timeouts and authentication failures.

4.2.1. kvm-02 (NAS storage, br-mgmt bridge)

# Create empty disk on NAS
sudo qemu-img create -f qcow2 /mnt/nas/vms/ise-02.qcow2 300G
sudo chown qemu:qemu /mnt/nas/vms/ise-02.qcow2
sudo virt-install \
  --name ise-02 \
  --memory 32768 \
  --vcpus 8,cpuset=4-11 \
  --cpu host-passthrough \
  --machine q35 \
  --cdrom /mnt/nas/isos/Cisco-ISE-3.5.0.527.SPA.x86_64.iso \
  --disk path=/mnt/nas/vms/ise-02.qcow2,format=qcow2,bus=virtio \
  --os-variant rhel8.0 \
  --network bridge=br-mgmt,model=virtio \
  --graphics vnc,listen=0.0.0.0 \
  --video virtio \
  --noautoconsole

4.2.2. kvm-02 (Local SSD, br-mgmt bridge)

Use local SSD when NAS I/O is unreliable. NAS network disruption during VM operation causes disk corruption (I/O errors on vda). Local SSD eliminates this single point of failure.

# Create empty disk on local SSD
sudo qemu-img create -f qcow2 /mnt/ssd/libvirt/images/ise-02.qcow2 300G
sudo virt-install \
  --name ise-02 \
  --memory 32768 \
  --vcpus 8,cpuset=4-11 \
  --cpu host-passthrough \
  --machine q35 \
  --cdrom /mnt/nas/isos/Cisco-ISE-3.5.0.527.SPA.x86_64.iso \
  --disk path=/mnt/ssd/libvirt/images/ise-02.qcow2,format=qcow2,bus=virtio \
  --os-variant rhel8.0 \
  --network bridge=br-mgmt,model=virtio \
  --graphics vnc,listen=0.0.0.0 \
  --video virtio \
  --noautoconsole

Storage Paths on kvm-02:

  • Local SSD: /mnt/ssd/libvirt/images/ (preferred for critical VMs)

  • NAS: /mnt/nas/vms/ (shared storage, risk of I/O disruption)

  • ISOs: /mnt/nas/isos/ (read-only, NAS acceptable)

4.2.3. kvm-01 (onboard SSD, virbr0 bridge)

sudo virt-install \
  --name ise-01 \
  --memory 16384 \
  --vcpus 4,cpuset=6-9 \
  --cpu host-passthrough \
  --machine q35 \
  --cdrom /var/lib/libvirt/images/Cisco-ISE-3.5.0.527.SPA.x86_64.iso \
  --disk path=/mnt/onboard-ssd/vms/ise-01.qcow2,size=300,format=qcow2,bus=virtio \
  --os-variant rhel8.0 \
  --network bridge=virbr0,model=virtio \
  --graphics vnc,listen=0.0.0.0 \
  --video virtio \
  --noautoconsole

Disk Size Options:

  • size=300 - PSN/pxGrid node

  • size=600 - PAN/MnT (recommended for standalone)

  • size=1200 - Large deployment

The disk is thin-provisioned (qcow2) - actual space used grows with data.

Table 1. Critical Settings (from working ise-02)
Setting Value

Machine type

q35 (NOT i440fx)

CPU mode

host-passthrough

Video

virtio (NOT qxl/cirrus)

Network bridge

virbr0

Disk/Network model

virtio

Install method

--cdrom (NOT --import)

4.3. Fix Boot Order (If "No Bootable Media" Error)

If VM shows "No bootable media found", the CD-ROM isn’t in boot order:

# Check current boot order
sudo virsh dumpxml ise-01 | grep -A5 "<os>"

If only <boot dev='hd'/> exists, add cdrom:

sudo virsh destroy ise-01
sudo virsh dumpxml ise-01 > /tmp/ise-01.xml
sudo sed -i "s|<boot dev='hd'/>|<boot dev='cdrom'/>\n    <boot dev='hd'/>|" /tmp/ise-01.xml
sudo virsh define /tmp/ise-01.xml
sudo virsh start ise-01

If CD-ROM is empty, insert the ISO:

sudo virsh change-media ise-02 sda /mnt/nas/isos/Cisco-ISE-3.5.0.527.SPA.x86_64.iso --insert --config

4.4. Add CPU Pinning (Before First Boot)

Immediately after creation, before booting:

sudo virsh edit ise-01

Add after <vcpu placement='static'>4</vcpu>:

<cputune>
  <vcpupin vcpu='0' cpuset='6'/>
  <vcpupin vcpu='1' cpuset='7'/>
  <vcpupin vcpu='2' cpuset='8'/>
  <vcpupin vcpu='3' cpuset='9'/>
</cputune>

CPU Allocation Map:

VM CPUs Notes

pfSense-FW01

0-3

Critical - network gateway

home-dc01

4-5

Domain controller

ise-01/ise-02

6-9

Only one active at a time

9800-CL-WLC

10-13

Wireless controller

Reserved

14-15

Future use

4.5. Verify Pinning (After VM Starts)

sudo virsh vcpuinfo ise-01

Expected output:

VCPU:           0
CPU:            6
State:          running
CPU Affinity:   ------y---------

VCPU:           1
CPU:            7
State:          running
CPU Affinity:   -------y--------
...

4.6. Memory Note

virsh dominfo shows "Used memory" = allocated, not consumed. This is normal:

# Check actual QEMU process memory
ps aux --sort=-%mem | grep qemu | awk '{print $6/1024/1024 " GB", $NF}'

5. Phase 3: ISE 3.5 Installation

5.1. Boot Menu

When booting from ISO, select from the menu:

Option Description

1

Cisco ISE Installation (Keyboard/Monitor) - Use this

2

Cisco ISE Installation (Serial Console)

3

System Utilities

4

Boot from Hard Drive

Select Option 1 for VNC/console installation.

5.2. Initial Setup Wizard

Connect via VNC console (or Cockpit at 192.168.1.181:9090):

# Get VNC display number
sudo virsh vncdisplay ise-01
# Output: :4  (means port 5904)

# Connect with vncviewer
vncviewer 192.168.1.181:5904
Table 2. Setup Wizard Values
Setting Value

Hostname

ise-01 (or ise-02 for secondary)

IP Address

10.50.1.20 (or 10.50.1.21 for secondary)

Netmask

255.255.255.0

Default Gateway

10.50.1.1

Primary DNS

10.50.1.90 (bind-01)

Secondary DNS

10.50.1.91 (bind-02)

DNS Domain

inside.domusdigitalis.dev

NTP Server

10.50.1.1

Timezone

US/Pacific

SSH Service

Y (enable)

Admin Username

admin

Admin Password

gopass show -o v3/domains/d000/identity/ise/ise-01/admin

Exact Setup Wizard Prompts (ise-02 example)
Enter hostname[]: ise-02
Enter default DNS domain[]: inside.domusdigitalis.dev
Enter IPv4/IPv6 address[]: 10.50.1.21
Enter IP netmask[]: 255.255.255.0
Enter IP default gateway[]: 10.50.1.1
Do you want to configure IPv6 address? Y/N [N]: N
Enter primary nameserver[]: 10.50.1.90
Add secondary nameserver? Y/N [N]: Y
Enter secondary nameserver[]: 10.50.1.91
Add tertiary nameserver? Y/N [N]: N
Enter NTP server[time.nist.gov]: 10.50.1.1
Add another NTP server? Y/N [N]: N
Enter system timezone[UTC]: US/Pacific
Enable SSH service? Y/N [N]: Y
Enter username[admin]: admin
Enter password: <gopass show -o v3/domains/d000/identity/ise/ise-02/admin>
Enter password again: <same>

Copy-paste ready values (ise-01):

Hostname:       ise-01
DNS Domain:     {domain}
IP:             {ise-01-ip}
Netmask:        255.255.255.0
Gateway:        {pfsense-ip}
Primary DNS:    {bind-ip}
Secondary DNS:  {bind-02-ip}
NTP:            {pfsense-ip}
Timezone:       US/Pacific
SSH:            Y
Username:       admin

5.3. Wait for Application Services

ISE installation takes 30-45 minutes. Monitor:

# SSH to ISE CLI
ssh admin@10.50.1.20

# Check application status
show application status ise

Expected when ready:

ISE PROCESS NAME                       STATE            PROCESS ID
-----------------------------------------------------------------
Database Listener                      running          xxxx
Database Server                        running          xxxx
Application Server                     running          xxxx
...

5.4. Verify Web UI

Login with admin credentials.

6. Phase 3a: Restore from Backup (Alternative)

Use this phase instead of Phases 4-7 when restoring from an existing backup. This is the standard approach for fresh ISE installs where you have a working config backup.

6.1. 3a.1 Get Encryption Key (on workstation)

dsource d000 dev/storage
echo $ISE_BACKUP_KEY

Record this key - you’ll need it for the restore command.

6.2. 3a.2 List Available Backups

dsource d000 dev/storage
netapi synology list-files /ise_backups
Available Backups (example)
scheduled-CFG10-260222-1948.tar.gpg      318.6 MB   (most recent)
pre-ise34-migration-CFG10-260209-2251.t  335.8 MB   (pre-3.4 migration)

6.3. 3a.3 SSH to ISE CLI

gopass show -c v3/domains/d000/identity/ise/ise-02/cli
sudo ssh admin@ise-02.{domain}

6.4. 3a.4 Configure NFS Repository

From ISE CLI:

configure terminal
repository nas-01
  url nfs://{nas-ip}:/volume1/ise_backups
exit

6.5. 3a.5 Verify Repository Shows Backups

show repository nas-01
Expected Output
scheduled-CFG10-260222-1948.tar.gpg
pre-ise34-migration-CFG10-260209-2251.tar.gpg
...

6.6. 3a.6 Restore from Backup

restore <backup-filename> repository nas-01 encryption-key plain <YOUR_KEY>

Replace:

  • <backup-filename> - from Step 3a.2 (e.g., scheduled-CFG10-260222-1948.tar.gpg)

  • <YOUR_KEY> - ISE_BACKUP_KEY value from Step 3a.1

Example
restore scheduled-CFG10-260222-1948.tar.gpg repository nas-01 encryption-key plain MySecretKey123

ISE will:

  1. Download backup from NAS

  2. Extract and validate

  3. Restore configuration

  4. Reboot automatically

6.7. 3a.7 Wait for Services (15-20 minutes)

After reboot, SSH back and monitor:

show application status ise

Wait until all services show running:

Expected Output
ISE PROCESS NAME                       STATE            PROCESS ID
--------------------------------------------------------------------
Database Listener                      running          xxxx
Database Server                        running          xxxx
Application Server                     running          xxxx
Profiler Database                      running          xxxx
...

6.8. 3a.8 Verify Restored Configuration

From workstation - verify key data was restored:

dsource d000 dev/network
Check AD Join Status
netapi ise api-call ers GET '/ers/config/activedirectory' --target ise-02 | jq '.SearchResult.total'
Expected Output
1
Check NADs Restored
netapi ise api-call ers GET '/ers/config/networkdevice?size=100' --target ise-02 | jq '.SearchResult.total'
Expected Output (your NAD count)
5
Check Policy Sets Restored
netapi ise get-policy-sets --target ise-02 | head -20
Check dACLs Restored
netapi ise api-call ers GET '/ers/config/downloadableacl?size=100' --target ise-02 | jq '.SearchResult.resources[].name'

If any checks fail, the restore may be incomplete. Check ISE Admin GUI for detailed status.

Skip to Phase 9: Cutover and Verification after restore completes.

After fresh install or restore, apply patches to match source system or get latest fixes.

Patching should be done BEFORE importing certificates. ISE restarts after patching.

7.1. 3b.1 Download Patch from Cisco

Download from software.cisco.com to your workstation.

Example patch file
ise-patchbundle-3.5.0.527-Patch2-26022210.SPA.x86_64.tar.gz

7.2. 3b.2 Upload Patch to NAS

Use rsync instead of scp for Synology NAS. SCP fails with "No such file or directory" even when path exists. This is a known Synology SCP limitation.

rsync -avP ~/Downloads/ise-patchbundle-3.5.0.527-Patch2-26022210.SPA.x86_64.tar.gz nas-01:/volume1/ise_backups/
Expected Output
sending incremental file list
ise-patchbundle-3.5.0.527-Patch2-26022210.SPA.x86_64.tar.gz
    831,286,426 100%   36.42MB/s    0:00:21 (xfr#1, to-chk=0/1)

7.3. 3b.3 Verify Patch on NAS

ssh nas-01 "ls -lh /volume1/ise_backups/*patch*"

7.4. 3b.4 Verify Repository on ISE

SSH to ISE and check repository:

ssh admin@10.50.1.21
show repository nas-01
Expected: Should list the patch file

If repository not configured:

configure terminal
repository nas-01
  url nfs://10.50.1.70:/volume1/ise_backups
exit

7.5. 3b.5 Apply Patch

patch install ise-patchbundle-3.5.0.527-Patch2-26022210.SPA.x86_64.tar.gz repository nas-01

ISE will:

  1. Download and verify patch

  2. Apply patch components

  3. Restart automatically

7.6. 3b.6 Wait for Services (15-20 minutes)

After restart, verify services:

show application status ise

7.7. 3b.7 Verify Patch Applied

show version

8. Phase 4: Certificate Issuance (DOMUS PKI)

Expected: Should show patch version in output

ISE requires certificates for:

  • Admin UI (HTTPS)

  • EAP Authentication (802.1X)

  • pxGrid (optional)

If Vault is accessible from your workstation (verify with vault-ssh-sign), issue certs directly without SSH to vault-01.

On workstation:

dsource d000 dev/vault
vault write pki_int/issue/domus-server \
  common_name="ise-02.inside.domusdigitalis.dev" \
  ip_sans="10.50.1.21" \
  ttl="8760h" \
  -format=json > /dev/shm/ise-02-cert.json
jq -r '.data.certificate' /dev/shm/ise-02-cert.json > /dev/shm/ise-02.crt
jq -r '.data.private_key' /dev/shm/ise-02-cert.json > /dev/shm/ise-02.key
jq -r '.data.ca_chain[]' /dev/shm/ise-02-cert.json > /dev/shm/ise-02-chain.pem

Verify certificate:

openssl x509 -in /dev/shm/ise-02.crt -noout -subject -issuer -dates
Expected output
subject=CN=ise-02.inside.domusdigitalis.dev
issuer=CN=DOMUS-ISSUING-CA
notBefore=Mar  5 21:57:05 2026 GMT
notAfter=Mar  5 21:57:35 2027 GMT

Split CA chain into individual certificates:

cd /dev/shm
awk '/-----BEGIN CERTIFICATE-----/{n++} n==1' ise-02-chain.pem > DOMUS-ISSUING-CA.pem
awk '/-----BEGIN CERTIFICATE-----/{n++} n==2' ise-02-chain.pem > DOMUS-ROOT-CA.pem

Verify CA extraction:

openssl x509 -in DOMUS-ISSUING-CA.pem -noout -subject
openssl x509 -in DOMUS-ROOT-CA.pem -noout -subject
Expected output
subject=CN=DOMUS-ISSUING-CA
subject=C=US, O=Domus Digitalis, OU=Enterprise PKI, CN=DOMUS-ROOT-CA

Now skip to 4.12 Import Trusted CA Certificates (FIRST) to import into ISE.


8.2. 4.1 Alternative: SSH to vault-01 (Legacy Method)

Use this method if Vault is not accessible from your workstation.

8.2.1. 4.1.1 Get Vault Credentials (on workstation)

dsource d000 dev/vault

This exports the following variables - copy these values, you’ll need them on vault-01:

  • VAULT_UNSEAL_KEY_1

  • VAULT_UNSEAL_KEY_2

  • VAULT_UNSEAL_KEY_3

  • VAULT_ROOT_TOKEN

Threshold is 2 keys (check vault status to confirm). You only need 2 of the 3 unseal keys.

8.3. 4.2 SSH to vault-01

ssh vault-01

8.4. 4.3 Set VAULT_ADDR

export VAULT_ADDR='http://127.0.0.1:8200'

8.5. 4.4 Check if Vault is Sealed

vault status

If Sealed = false, skip to Step 4.6.

8.6. 4.5 Unseal Vault (if sealed)

Run this 2 times, pasting a different unseal key each time when prompted:

vault operator unseal
# Paste VAULT_UNSEAL_KEY_1, press Enter
vault operator unseal
# Paste VAULT_UNSEAL_KEY_2, press Enter

After the second key, Sealed should be false.

8.7. 4.6 Set VAULT_ROOT_TOKEN

export VAULT_TOKEN='<paste-VAULT_ROOT_TOKEN-from-dsec>'
The environment variable is still VAULT_TOKEN - you’re pasting the value from VAULT_ROOT_TOKEN.

8.8. 4.7 Verify PKI is Accessible

vault secrets list | grep pki
Expected output
pki/        pki         ...
pki_int/    pki         ...

8.9. 4.8 Issue Server Certificate

vault write pki_int/issue/domus-server \
  common_name="ise-01.inside.domusdigitalis.dev" \
  ip_sans="10.50.1.20" \
  ttl="8760h" \
  -format=json > /tmp/ise-01-cert.json

The domus-server role has allow_bare_domains: false, so only FQDNs are allowed in CN/SANs. Short hostnames like ise-01 will be rejected.

Allowed domains: inside.domusdigitalis.dev, domusdigitalis.dev (and subdomains)

Verify the certificate was issued:

jq -r '.data.certificate' /tmp/ise-01-cert.json | openssl x509 -noout -subject -issuer
Expected output
subject=CN = ise-01.inside.domusdigitalis.dev
issuer=CN = DOMUS-ISSUING-CA

8.10. 4.9 Extract Certificate Components

Extract the certificate:

jq -r '.data.certificate' /tmp/ise-01-cert.json > /tmp/ise-01.crt

Extract the private key:

jq -r '.data.private_key' /tmp/ise-01-cert.json > /tmp/ise-01.key

Extract the CA chain:

jq -r '.data.ca_chain[]' /tmp/ise-01-cert.json > /tmp/ise-01-chain.pem

Verify files were created:

ls -la /tmp/ise-01*
Expected output
-rw-r--r--. 1 ansible ansible 5765 Feb 10 18:47 /tmp/ise-01-cert.json
-rw-r--r--. 1 ansible ansible 4248 Feb 10 18:47 /tmp/ise-01-chain.pem
-rw-r--r--. 1 ansible ansible 1850 Feb 10 18:47 /tmp/ise-01.crt
-rw-r--r--. 1 ansible ansible 1675 Feb 10 18:47 /tmp/ise-01.key

8.11. 4.10 Verify Certificate Before Transfer

Verify the certificate subject, issuer, and validity before transferring:

openssl x509 -in /tmp/ise-01.crt -noout -subject -issuer -dates
Expected output
subject=CN=ise-01.inside.domusdigitalis.dev
issuer=CN=DOMUS-ISSUING-CA
notBefore=Feb 10 18:41:01 2026 GMT
notAfter=Feb 10 18:41:31 2027 GMT

Verify the CA chain file contains both intermediate and root:

grep -c "BEGIN CERTIFICATE" /tmp/ise-01-chain.pem
Expected output
2

ISE imports certificate and private key separately (NOT PKCS#12).

Do not create .p12 files - ISE’s System Certificate import accepts:

  • Certificate File (.crt or .pem)

  • Private Key File (.key)

  • Password (leave empty for unencrypted key)

8.12. 4.11 Transfer Certificate Files to Workstation

Exit vault-01 and copy files to /dev/shm (RAM-only, never written to disk):

exit
scp vault-01:/tmp/ise-01.crt /dev/shm/
scp vault-01:/tmp/ise-01.key /dev/shm/
scp vault-01:/tmp/ise-01-chain.pem /dev/shm/

Security: /dev/shm is a RAM-based tmpfs. Files are:

  • Never written to disk (no forensic recovery)

  • Automatically cleared on reboot

  • More secure for sensitive key material

After ISE import, shred all certificate files (see Step 4.15).

8.13. 4.12 Import Trusted CA Certificates (FIRST)

Import Trusted CAs BEFORE the System Certificate.

ISE validates the certificate chain during import. If DOMUS-ROOT-CA and DOMUS-ISSUING-CA aren’t in the trusted store, you’ll get:

Certificate path validation failed

8.13.1. Extract Individual CA Certificates from Chain

The ise-01-chain.pem contains both CAs concatenated. Split them into individual files:

cd /dev/shm

Extract DOMUS-ISSUING-CA (first certificate in chain):

awk '/-----BEGIN CERTIFICATE-----/{i++}i==1' ise-01-chain.pem > DOMUS-ISSUING-CA.pem

Extract DOMUS-ROOT-CA (second certificate in chain):

awk '/-----BEGIN CERTIFICATE-----/{i++}i==2' ise-01-chain.pem > DOMUS-ROOT-CA.pem

Verify extraction:

openssl x509 -in /dev/shm/DOMUS-ISSUING-CA.pem -noout -subject
openssl x509 -in /dev/shm/DOMUS-ROOT-CA.pem -noout -subject
Expected output
subject=CN=DOMUS-ISSUING-CA
subject=C=US, O=Domus Digitalis, OU=Enterprise PKI, CN=DOMUS-ROOT-CA

8.13.2. Import to ISE Trusted Store

  1. Open ISE Admin UI: ise-01.inside.domusdigitalis.dev/admin

  2. Navigate to: Administration > System > Certificates > Trusted Certificates

  3. Click Import

  4. Import DOMUS-ROOT-CA:

    • Browse to /dev/shm/DOMUS-ROOT-CA.pem

    • Friendly Name: DOMUS-ROOT-CA

    • Enable:

      • Trust for authentication within ISE

      • Trust for client authentication and Syslog

      • Trust for authentication of Cisco Services

  5. Click Submit

  6. Click Import again

  7. Import DOMUS-ISSUING-CA:

    • Browse to /dev/shm/DOMUS-ISSUING-CA.pem

    • Friendly Name: DOMUS-ISSUING-CA

    • Enable same trust options as above

  8. Click Submit

8.14. 4.13 Import System Certificate to ISE

  1. Navigate to: Administration > System > Certificates > System Certificates

  2. Click Import

  3. Fill in:

    • Certificate File: Browse to /dev/shm/ise-01.crt

    • Private Key File: Browse to /dev/shm/ise-01.key

    • Password: (leave empty - key is unencrypted)

    • Friendly Name: DOMUS_ISE_ADMIN_EAP

  4. Enable for:

    • Admin

    • EAP Authentication

  5. Click Submit

ISE Certificate Strategy:

Friendly Name Services PKI Source

DOMUS_ISE_ADMIN_EAP

Admin UI, EAP Authentication

Vault (DOMUS-ISSUING-CA)

DOMUS_ISE_PXGRID

pxGrid Controller/Client

Vault (DOMUS-ISSUING-CA)

LETSENCRYPT_ISE_PORTAL

Guest/Sponsor Portal

Let’s Encrypt (ACME/certbot)

pxGrid and Portal certificates are issued separately - do NOT enable those usages on this certificate.

ISE will restart Admin services after importing. Wait 2-3 minutes before proceeding.

8.15. 4.14 Issue pxGrid Certificate (While ISE Restarts)

While waiting for ISE to restart, issue the pxGrid certificate from Vault.

8.15.1. SSH to vault-01

ssh vault-01

8.15.2. Set Vault Environment

export VAULT_ADDR='http://127.0.0.1:8200'
export VAULT_TOKEN='<paste-VAULT_ROOT_TOKEN>'

8.15.3. Issue pxGrid Certificate

vault write pki_int/issue/domus-server \
  common_name="ise-01.inside.domusdigitalis.dev" \
  ip_sans="10.50.1.20" \
  ttl="8760h" \
  -format=json > /tmp/ise-01-pxgrid.json

8.15.4. Extract Certificate Components

jq -r '.data.certificate' /tmp/ise-01-pxgrid.json > /tmp/ise-01-pxgrid.crt
jq -r '.data.private_key' /tmp/ise-01-pxgrid.json > /tmp/ise-01-pxgrid.key

8.15.5. Verify and Transfer

openssl x509 -in /tmp/ise-01-pxgrid.crt -noout -subject -issuer
exit
scp vault-01:/tmp/ise-01-pxgrid.crt /dev/shm/
scp vault-01:/tmp/ise-01-pxgrid.key /dev/shm/

8.16. 4.15 Import pxGrid Certificate to ISE

Once ISE is back online:

  1. Navigate to: Administration > System > Certificates > System Certificates

  2. Click Import

  3. Fill in:

    • Certificate File: Browse to /dev/shm/ise-01-pxgrid.crt

    • Private Key File: Browse to /dev/shm/ise-01-pxgrid.key

    • Password: (leave empty - key is unencrypted)

    • Friendly Name: DOMUS_ISE_PXGRID

  4. Enable for:

    • pxGrid

  5. Click Submit

pxGrid certificate is separate from Admin/EAP. This allows independent rotation and follows least-privilege principle.

8.17. 4.16 Verify Certificate Installation

8.17.1. Quick Subject/Issuer Check

echo | openssl s_client -connect ise-01.inside.domusdigitalis.dev:443 2>/dev/null | openssl x509 -noout -subject -issuer
Expected output
subject=CN = ise-01.inside.domusdigitalis.dev
issuer=CN = DOMUS-ISSUING-CA

8.17.2. Full Certificate Chain Display

Shows the complete trust chain from end-entity to root:

openssl s_client -connect ise-01.inside.domusdigitalis.dev:443 -showcerts </dev/null 2>/dev/null | grep -E "^(depth|Certificate chain| [0-9]+ s:)"
Expected output
Certificate chain
 0 s:CN=ise-01.inside.domusdigitalis.dev
 1 s:CN=DOMUS-ISSUING-CA
 2 s:C=US, O=Domus Digitalis, OU=Enterprise PKI, CN=DOMUS-ROOT-CA

8.17.3. Detailed Chain with Validity Dates

openssl s_client -connect ise-01.inside.domusdigitalis.dev:443 </dev/null 2>/dev/null | grep -A2 "Certificate chain"

Or for full detail including key sizes and validity:

echo | openssl s_client -connect ise-01.inside.domusdigitalis.dev:443 2>&1 | grep -E "(depth=|s:|i:|v:NotBefore|Verification)"
Expected output
depth=2 C=US, O=Domus Digitalis, OU=Enterprise PKI, CN=DOMUS-ROOT-CA
depth=1 CN=DOMUS-ISSUING-CA
depth=0 CN=ise-01.inside.domusdigitalis.dev
Verification: OK

8.17.4. Check Certificate Expiration

echo | openssl s_client -connect ise-01.inside.domusdigitalis.dev:443 2>/dev/null | openssl x509 -noout -dates
Expected output
notBefore=Feb 10 18:41:01 2026 GMT
notAfter=Feb 10 18:41:31 2027 GMT

8.17.5. Download Server Certificate to File

Save the end-entity certificate for archival or comparison:

echo | openssl s_client -connect ise-01.inside.domusdigitalis.dev:443 2>/dev/null | openssl x509 > /tmp/ise-01-retrieved.crt

Verify downloaded cert:

openssl x509 -in /tmp/ise-01-retrieved.crt -noout -subject -issuer -dates -fingerprint

8.17.6. Download Full Chain

Save all certificates in the chain:

openssl s_client -connect ise-01.inside.domusdigitalis.dev:443 -showcerts </dev/null 2>/dev/null | awk '/BEGIN CERTIFICATE/,/END CERTIFICATE/{print}' > /tmp/ise-01-fullchain.pem

Count certificates in chain (should be 3):

grep -c "BEGIN CERTIFICATE" /tmp/ise-01-fullchain.pem

8.17.7. Verify Chain Against Local CA

If you have DOMUS-ROOT-CA locally, verify the full chain:

openssl s_client -connect ise-01.inside.domusdigitalis.dev:443 -CAfile /etc/ssl/certs/DOMUS-ROOT-CA.pem </dev/null 2>&1 | grep "Verify return code"
Expected output
Verify return code: 0 (ok)

Troubleshooting Certificate Issues:

  • Verify return code: 0 (ok) - Chain is valid

  • Verify return code: 2 (unable to get issuer certificate) - Missing intermediate CA

  • Verify return code: 19 (self-signed certificate in chain) - Root CA not trusted

  • Verify return code: 10 (certificate has expired) - Cert needs renewal

8.18. 4.17 Secure Cleanup

After successful ISE import and verification, shred all certificate files.

8.18.1. On Workstation

shred -vfz -n 3 /dev/shm/ise-01*.crt /dev/shm/ise-01*.key /dev/shm/ise-01-chain.pem /dev/shm/DOMUS-*.pem
rm -f /dev/shm/ise-01*.crt /dev/shm/ise-01*.key /dev/shm/ise-01-chain.pem /dev/shm/DOMUS-*.pem

8.18.2. On vault-01

ssh vault-01
shred -vfz -n 3 /tmp/ise-01*
rm -f /tmp/ise-01*
exit

shred options:

  • -v - verbose, show progress

  • -f - force, change permissions if needed

  • -z - add final overwrite with zeros to hide shredding

  • -n 3 - overwrite 3 times (DoD standard)

Files in /dev/shm are RAM-only but shredding ensures no process can recover them before reboot. The private key (ise-01.key) is the most sensitive file - ensure it’s destroyed.

8.19. 4.18 Seal Vault (CRITICAL)

Always seal Vault after certificate operations. An unsealed Vault is a security risk - anyone with network access to vault-01 can issue certificates.

ssh vault-01
export VAULT_ADDR='http://127.0.0.1:8200'
vault operator seal
Expected Output
Success! Vault is sealed.
exit

See Vault PKI Certificate Issuance for detailed certificate procedures.

9. Phase 5: Active Directory Integration

Windows Server 2025 Native Support in ISE 3.5

Per the ISE 3.5 AD Compatibility Matrix, Windows Server 2025 is now natively supported. No hot patch required.

For ISE 3.4 and earlier, Windows Server 2025 support required:

  1. TAC-provided hot patch - Contact Cisco TAC to obtain

  2. DC registry modification - SamRpcChangesPasswordMethods=1

  3. DC reboot - Required for registry change to take effect

This is documented in Field Notice FN74321.

9.1. 5.0 Windows Server 2025 Workaround (ISE 3.4 Legacy)

If using ISE 3.4 with Windows Server 2025 (upgrade to 3.5 recommended):

9.1.1. Step 1: Open Cisco TAC Case

Contact Cisco TAC requesting:

  • Issue: ISE fails to join AD on Windows Server 2025

  • Reference: Field Notice FN74321

  • Request: Hot patch for ISE 3.5 (if needed)

Provide TAC with:

  • ISE Version: 3.5.0.527 (or your patch level)

  • Domain Controller OS: Windows Server 2025

  • Error messages from ISE join attempt

9.1.2. Step 2: Apply DC Registry Workaround

On the Windows Server 2025 DC (home-dc01):

Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SAM" -Name "SamRpcChangesPasswordMethods" -Value 1 -Type DWord -Force

Verify:

Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SAM" -Name "SamRpcChangesPasswordMethods"

9.1.3. Step 3: Reboot Domain Controller

Restart-Computer -Force

This registry change reduces security by enabling legacy SAM RPC password change methods. Only apply after consulting with your security team.

9.1.4. Step 4: Apply TAC Hot Patch to ISE

Follow TAC instructions to apply the hot patch before attempting AD join.


Alternative: Deploy Windows Server 2022 DC which is fully supported without workarounds.

9.2. 5.1 AD OU Structure Reference

AD OU Structure
Figure 1. Active Directory OU Structure
ISE computer objects go in OU=ISE,OU=Tier 1 - Servers. Service account svc-ise-adjoin goes in OU=Service Accounts,OU=Tier 0 - Identity.

View existing OUs:

Get-ADOrganizationalUnit -Filter * | Select-Object Name, DistinguishedName

9.3. 5.2 Create ISE OU (on home-dc01)

Create OU for ISE computer objects:

New-ADOrganizationalUnit -Name "ISE" -Path "OU=Tier 1 - Servers,DC=inside,DC=domusdigitalis,DC=dev"

9.4. 5.3 Create ISE AD Join Service Account

Do not use Domain Administrator for ISE AD join. Create a dedicated service account with delegated permissions.

Create the service account:

New-ADUser -Name "svc-ise-adjoin" -SamAccountName "svc-ise-adjoin" -UserPrincipalName "svc-ise-adjoin@inside.domusdigitalis.dev" -Path "OU=Service Accounts,OU=Tier 0 - Identity,DC=inside,DC=domusdigitalis,DC=dev" -AccountPassword (Read-Host -AsSecureString "Password") -Enabled $true -PasswordNeverExpires $true -Description "ISE AD join service account"

9.5. 5.4 Delegate Permissions on ISE OU

Grant the service account permission to join computers:

$ou = "OU=ISE,OU=Tier 1 - Servers,DC=inside,DC=domusdigitalis,DC=dev"
dsacls $ou /G "INSIDE\svc-ise-adjoin:CC;computer"
dsacls $ou /G "INSIDE\svc-ise-adjoin:WP;servicePrincipalName;computer"
dsacls $ou /G "INSIDE\svc-ise-adjoin:WP;userAccountControl;computer"

9.6. 5.5 Store Credentials in gopass

gopass generate v2/DOMUS/ad/svc-ise-adjoin 32
gopass edit v2/DOMUS/ad/svc-ise-adjoin

Add metadata:

<generated-password>
username: svc-ise-adjoin
upn: svc-ise-adjoin@inside.domusdigitalis.dev
description: ISE AD join service account - delegated permissions to join computers to ISE OU
ou: OU=Service Accounts,OU=Tier 0 - Identity,DC=inside,DC=domusdigitalis,DC=dev
created: 2026-02-10

9.7. 5.6 Create AD Join Point in ISE

In ISE Admin UI:

  1. Navigate to: Administration > Identity Management > External Identity Sources > Active Directory

  2. Click Add

  3. Configure:

    Setting Value

    Join Point Name

    DOMUS_AD

    Active Directory Domain

    inside.domusdigitalis.dev

    Description

    DOMUS Active Directory integration for 802.1X authentication and authorization

  4. Click Submit

9.8. 5.7 Join Domain

  1. Select the join point and click Join

  2. Enter credentials:

    gopass show -o v2/DOMUS/ad/svc-ise-adjoin
    • Username: svc-ise-adjoin

    • Password: (from gopass above)

  3. Organizational Unit:

    OU=ISE,OU=Tier 1 - Servers,DC=inside,DC=domusdigitalis,DC=dev
  4. Click OK

OU DN Format: Read right-to-left. Child OU first, then parent OUs, then domain components.

Example: OU=ISE,OU=Tier 1 - Servers places the ISE computer account at: inside.domusdigitalis.dev > Tier 1 - Servers > ISE > ise-01

9.9. 5.8 Verify AD Join

# From ISE CLI
ssh admin@ise-01.inside.domusdigitalis.dev
show run | include active-directory

Or via API:

netapi ise get-ad-join-points

9.10. 5.9 Add AD Groups

Add groups for policy conditions:

# Using netapi (after updating credentials for ise-01)
netapi ise add-ad-groups "inside.domusdigitalis.dev" "GRP-Computers-Linux-Workstations"
netapi ise add-ad-groups "inside.domusdigitalis.dev" "GRP-Computers-Linux-Servers"
netapi ise add-ad-groups "inside.domusdigitalis.dev" "GRP-Users-802.1X-Wired"
netapi ise add-ad-groups "inside.domusdigitalis.dev" "GRP-Users-802.1X-Wireless"

Or via GUI: Administration > Identity Management > External Identity Sources > Active Directory > Groups

10. Phase 5a: SAML Admin Portal SSO (Keycloak)

This phase reconfigures SAML SSO for the ISE Admin Portal. The old ise-02 SAML configuration will not transfer - ISE generates a new Entity ID for each deployment.

10.1. Known Issue: Firefox HSTS Certificate Block

If you previously accessed ise-02 with an untrusted certificate, Firefox may cache HSTS and block access:

Did Not Connect: Potential Security Issue
Firefox detected a potential security threat and did not continue to ise-02.inside.domusdigitalis.dev:8443

Resolution: ise-01 will have a new DOMUS PKI certificate. Import the CA into Firefox.

10.2. Import DOMUS-ROOT-CA into Firefox

Firefox uses its own certificate store (ignores system trust store):

  1. Settings → Privacy & Security → View Certificates

  2. Authorities tab → Import

  3. Select /etc/ssl/certs/DOMUS-ROOT-CA.pem

  4. Check "Trust this CA to identify websites"

10.3. Configure SAML IdP in ISE

SAML IdP configuration is GUI-only (no API).

Navigate to: Administration → Identity Management → External Identity Sources → SAML Id Providers

10.3.1. Import Keycloak Metadata

# Download Keycloak SAML metadata
curl -k https://keycloak-01.inside.domusdigitalis.dev:8443/realms/domusdigitalis/protocol/saml/descriptor \
  -o /tmp/keycloak-metadata.xml

In ISE:

  1. Click Add

  2. IdP Name: keycloak_01

  3. Select Import metadata from file

  4. Upload /tmp/keycloak-metadata.xml

  5. Click Import

10.3.2. Export ISE SP Metadata (Critical)

ISE generates a unique Entity ID. This must match the Keycloak client ID.

  1. Click Export Service Provider Info

  2. Save the XML file

  3. Note the Entity ID:

    entityID="http://CiscoISE/a486c6ef-6c77-4bc1-bf6d-4e479b3aeae8"

10.3.3. Update Keycloak Client ID

In Keycloak Admin Console:

  1. Navigate to: Clients → (ISE client)

  2. Update Client ID to match ISE Entity ID exactly

  3. Update Valid redirect URIs:

    https://ise-01.inside.domusdigitalis.dev:8443/*

    The :8443 port is required. Without it, SAML redirect will fail with "Invalid redirect uri".

10.3.4. Configure Group Mappings

Navigate to ISE SAML IdP → Groups tab:

Name in Assertion (Keycloak) Name in ISE

ise-super-admin

Super Admin

ise-read-only

Read Only Admin

ise-helpdesk

Helpdesk Admin

ise-ers-admin

ERS Admin

ISE Admin Group names are case-sensitive. Use exact case: Super Admin, not super admin.

10.3.5. Enable SAML for Admin Portal

  1. Navigate to: Administration → Admin Access → Authentication → Authentication Method

  2. Select Password Based or Client Certificate Based or SAML Based

  3. Select IdP: keycloak_01

  4. Click Save

10.4. Test SAML Authentication

  1. Open: ise-01.inside.domusdigitalis.dev/admin

  2. Select Log In With: keycloak_01

  3. Authenticate with Keycloak credentials

  4. Verify ISE admin access

10.5. Fallback Access

Always maintain local admin access for emergencies:

https://ise-01.inside.domusdigitalis.dev/admin/LoginAction.do?local=true

10.6. Troubleshooting SAML

Monitor SAML logs on ISE:

ssh admin@ise-01.inside.domusdigitalis.dev
show logging application ise-psc.log tail | include SAML

Common issues:

Error Resolution

"Invalid Request"

Entity ID mismatch - export ISE SP metadata, update Keycloak client ID

"Invalid redirect uri"

Add :8443 to Keycloak Valid Redirect URIs

"Access denied" after login

Group mapping missing or case mismatch

Signature validation failed

Re-import Keycloak metadata to ISE

If SAML issues persist after following this guide, open a Cisco TAC case for ISE SAML troubleshooting support.

11. Phase 6: Network Access Devices (NADs)

11.1. Add pfSense (RADIUS)

netapi ise create-network-device \
  --name "pfSense-FW01" \
  --ip "10.50.1.1" \
  --radius-secret "$(gopass show -o d000/radius/pfsense)" \
  --device-type "Firewall" \
  --location "Home Enterprise"

11.2. Add Cisco 9800-CL WLC

netapi ise create-network-device \
  --name "9800-CL-WLC" \
  --ip "10.50.1.40" \
  --radius-secret "$(gopass show -o d000/radius/wlc)" \
  --device-type "Wireless LAN Controller#Cisco#C9800-CL" \
  --location "Home Enterprise"

11.3. Add Cisco 9300 Switch (Optional)

netapi ise create-network-device \
  --name "SWITCH_9300" \
  --ip "10.50.1.11" \
  --radius-secret "$(gopass show -o d000/radius/switch)" \
  --device-type "Switch#Cisco#Catalyst 9300" \
  --location "Home Enterprise"

SWITCH_9300 is typically powered off to reduce power consumption. Only add if actively used.

12. Phase 7: Policy Configuration

12.1. Create Endpoint Identity Groups

  1. Navigate to: Work Centers > Network Access > Identity Groups > Endpoint Identity Groups

  2. Create groups:

    • Linux-Workstations - Linux desktop/laptop machines

    • Linux-Servers - Linux server infrastructure

    • Windows-Workstations - Windows desktop/laptop machines

12.2. Create Authorization Profiles

Navigate to: Policy > Policy Elements > Results > Authorization > Authorization Profiles

12.2.1. PERMIT-FULL-ACCESS

Setting Value

Name

PERMIT-FULL-ACCESS

Access Type

ACCESS_ACCEPT

DACL Name

(none - full access)

VLAN

(use NAD default)

12.2.2. PERMIT-LIMITED-ACCESS

Setting Value

Name

PERMIT-LIMITED-ACCESS

Access Type

ACCESS_ACCEPT

DACL Name

DACL-LIMITED-ACCESS

12.2.3. DENY-ACCESS

Setting Value

Name

DENY-ACCESS

Access Type

ACCESS_REJECT

12.3. Create Policy Sets

Navigate to: Policy > Policy Sets

12.3.1. Wired 802.1X EAP-TLS

  1. Create new Policy Set: Wired-802.1X-EAP-TLS

  2. Conditions: Wired_802.1X AND EAP-TLS

  3. Authentication Policy:

    • Identity Source: Certificate Authentication Profile

    • If authentication fails: REJECT

  4. Authorization Policy Rules:

    Rule Condition Profile

    Linux-Workstation-Full

    EndpointIdentityGroup EQUALS Linux-Workstations

    PERMIT-FULL-ACCESS

    Linux-Server-Full

    EndpointIdentityGroup EQUALS Linux-Servers

    PERMIT-FULL-ACCESS

    Default

    (none)

    DENY-ACCESS

12.3.2. Wireless 802.1X EAP-TLS

Similar structure for wireless with SSID-specific conditions.

Create conditions that check AD group membership:

  1. Navigate to: Policy > Policy Elements > Conditions > Authorization > Compound Conditions

  2. Create: AD-Linux-Workstation

    • DOMUS_DC01:ExternalGroups CONTAINS GRP-Computers-Linux-Workstations

13. Phase 8: Linux Client Configuration

13.1. Update wpa_supplicant

If clients currently point to ise-02, update to ise-01 or use DNS alias:

# /etc/wpa_supplicant/wpa_supplicant-wired.conf
network={
    key_mgmt=IEEE8021X
    eap=TLS
    identity="modestus-razer.inside.domusdigitalis.dev"
    ca_cert="/etc/ssl/certs/DOMUS-CA-CHAIN.pem"
    client_cert="/etc/ssl/certs/modestus-razer-eaptls.pem"
    private_key="/etc/ssl/private/modestus-razer-eaptls.key"
    eapol_flags=0
}

See wpa_supplicant Configuration (ise-linux) for detailed client setup.

13.2. Verify CA Trust

# Check DOMUS CA chain is present
openssl verify -CAfile /etc/ssl/certs/DOMUS-CA-CHAIN.pem \
  /etc/ssl/certs/$(hostname)-eaptls.pem

Expected: OK

14. Phase 9: Cutover and Verification

14.1. Pre-Cutover Checklist

  • ise-01 certificates installed and bound

  • AD join successful

  • AD groups added

  • NADs configured with RADIUS secrets

  • Policy sets created

  • Test authentication successful (see below)

14.2. Test Authentication

Before full cutover, test with one client:

# On a Linux workstation
sudo systemctl restart wpa_supplicant@eth0

# Check authentication
journalctl -u wpa_supplicant@eth0 -f

14.3. Verify in ISE

# Update environment for ise-01
export ISE_PAN_FQDN=ise-01.inside.domusdigitalis.dev

# Check live sessions
netapi ise mnt sessions

# Check authentication log
netapi ise dc query "SELECT USERNAME, POLICY_SET_NAME, PASSED, FAILURE_REASON
  FROM RADIUS_AUTHENTICATIONS
  WHERE TIMESTAMP_TIMEZONE > SYSDATE - INTERVAL '1' HOUR
  ORDER BY TIMESTAMP_TIMEZONE DESC
  FETCH FIRST 20 ROWS ONLY"

14.4. Cutover Steps

  1. Update DNS (if using ise.inside.domusdigitalis.dev alias):

    # On home-dc01
    Remove-DnsServerResourceRecord -ZoneName "inside.domusdigitalis.dev" -Name "ise" -RRType A
    Add-DnsServerResourceRecordA -ZoneName "inside.domusdigitalis.dev" -Name "ise" -IPv4Address "10.50.1.20"
  2. Shut down ise-02:

    sudo virsh shutdown ise-02
  3. Verify all clients authenticate to ise-01

14.5. Post-Cutover Verification

# Check active sessions
netapi ise mnt sessions

# Verify EAP-TLS authentications
netapi ise dc query "SELECT USERNAME, AUTHENTICATION_PROTOCOL, POLICY_SET_NAME, PASSED
  FROM RADIUS_AUTHENTICATIONS
  WHERE AUTHENTICATION_PROTOCOL = 'EAP-TLS'
    AND TIMESTAMP_TIMEZONE > SYSDATE - INTERVAL '1' HOUR
  ORDER BY TIMESTAMP_TIMEZONE DESC
  FETCH FIRST 10 ROWS ONLY"

15. Phase 10: Post-Deployment

15.1. Update gopass Credentials

If any credentials changed:

gopass edit d000/ise/admin
gopass edit d000/ise/api-token

15.2. Update dsec Environment

# Update ISE_PAN_FQDN in dsec env file
vim ~/.secrets/env/d000/dev/network.env

Change:

ISE_PAN_FQDN=ise-01.inside.domusdigitalis.dev

15.3. Decommission ise-02

After verification period (1-2 weeks):

# Ensure ise-02 is stopped
sudo virsh destroy ise-02

# Remove from libvirt
sudo virsh undefine ise-02 --remove-all-storage

# Or keep storage for rollback
sudo virsh undefine ise-02

15.4. Document Final State

Update CLAUDE.md and related documentation with:

  • ise-01 IP and hostname

  • Policy set names

  • AD group mappings

  • Any configuration changes

16. Troubleshooting

16.1. Dracut Emergency Shell (OVA Conversion Issue)

Symptom: VM boots to dracut:# prompt instead of ISE setup wizard

Cause: Attempted to use converted OVA disk on KVM. OVA files contain VMware-specific drivers (VMXNET3, PVSCSI) that don’t work with KVM’s VirtIO drivers.

Resolution: Use ISO installation, not OVA conversion:

# Remove the broken VM
sudo virsh destroy ise-02
sudo virsh undefine ise-02 --remove-all-storage

# Download ISE ISO (not OVA) to kvm-02
rsync -avP ~/Downloads/Cisco-ISE-3.5.0.527.SPA.x86_64.iso kvm-02:/mnt/nas/isos/

# Create VM with ISO installation (see Phase 2)

Per Cisco documentation: OVA templates are for VMware ESXi only. KVM, Nutanix AHV, and OpenShift require ISO installation.

16.2. Resource Contention During Install

Symptom: Network outage, pfSense or WLC unresponsive during ISE install

Cause: ISE installation spikes CPU usage, starving other VMs

Resolution: Always configure CPU pinning before booting ISE ISO

# Verify pinning
sudo virsh vcpuinfo ise-01

# Apply live if missed
sudo virsh vcpupin ise-01 0 6
sudo virsh vcpupin ise-01 1 7
sudo virsh vcpupin ise-01 2 8
sudo virsh vcpupin ise-01 3 9

16.3. AD Join Access Denied (Windows Server 2025)

Symptom: "Access is denied" or "LDAP_CONSTRAINT_VIOLATION" when joining domain

Cause: Windows Server 2025 was NOT officially supported by ISE 3.4. ISE 3.5 has native WS2025 support.

Resolution:

Option A: ISE 3.5 (Recommended)

ISE 3.5 has native Windows Server 2025 support. No hot patch required.

Option B: Cisco TAC Hot Patch (ISE 3.4 only)

  1. Open TAC case referencing Field Notice FN74321

  2. Request hot patch for ISE 3.4 + WS2025 compatibility

  3. Apply DC registry workaround:

    Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SAM" -Name "SamRpcChangesPasswordMethods" -Value 1 -Type DWord -Force
    Restart-Computer -Force
  4. Apply TAC-provided hot patch to ISE

  5. Retry AD join

Option B: Deploy Windows Server 2022 DC

Deploy a Windows Server 2022 domain controller, which is fully supported without workarounds.

Additional Checks (WS2022 or after applying hot patch):

  1. Verify DNS resolution to DC

  2. Check time sync (Kerberos requires <5 min skew)

  3. Verify OU path format (child first, then parent: OU=ISE,OU=Tier 1 - Servers,DC=…​)

  4. Verify service account has delegated permissions on target OU

16.4. Certificate Verify Failed

Symptom: SSL: CERTIFICATE_VERIFY_FAILED - unable to get local issuer certificate

Cause: CA chain incomplete (missing intermediate)

Resolution: Use full chain with both root and intermediate:

# Verify chain has 2 certificates
grep -c "BEGIN CERTIFICATE" /etc/ssl/certs/DOMUS-CA-CHAIN.pem
# Should return: 2

# If only 1, concatenate:
cat DOMUS-ROOT-CA.pem DOMUS-ISSUING-CA.pem > DOMUS-CA-CHAIN.pem

16.5. EAP-TLS Authentication Fails

Symptom: Client authentication rejected

Cause: Various - check ISE live logs

Resolution:

  1. Check ISE Operations > RADIUS > Live Logs

  2. Common issues:

    • Certificate not trusted - import CA to ISE trusted store

    • Certificate expired - reissue from Vault

    • Wrong identity source - check authentication policy

    • Client not in endpoint group - verify group assignment

# Quick check for recent failures
netapi ise dc query "SELECT USERNAME, FAILURE_REASON
  FROM RADIUS_AUTHENTICATIONS
  WHERE PASSED = 0
    AND TIMESTAMP_TIMEZONE > SYSDATE - INTERVAL '1' HOUR
  ORDER BY TIMESTAMP_TIMEZONE DESC
  FETCH FIRST 10 ROWS ONLY"

17. Phase 11: API Validation

After migration, validate all ISE API surfaces are operational against ise-01.

17.1. 11.1 Update Secrets Configuration (dsec)

Update d000 dev/network to point active targets to ise-01:

dsec edit d000 dev/network

Key changes:

# Change active target from ISE_HQ_01 to ISE_HQ_02
ISE_DEPLOYMENT_TYPE={{ISE_HQ_02_DEPLOYMENT}}
ISE_PAN_FQDN={{ISE_HQ_02_HOST}}
ISE_PAN_IP={{ISE_HQ_02_IP}}
ISE_PORT={{ISE_HQ_02_PORT}}

# DataConnect must use FQDN (not IP) for SSL hostname verification
ISE_DATACONNECT_HOST={{ISE_PAN_FQDN}}

Reload environment:

dsource d000 dev/network

17.2. 11.2 ERS API Test

netapi ise get-cert-profiles
Expected output
ISE_preloaded_Cisco_Certificate_Profile_For_RA
ISE_BYOD_Certificate_Profile

17.3. 11.3 OpenAPI Test

netapi ise api-call openapi GET '/api/v1/deployment/node' | jq -r '.response[] | "\(.hostname) (\(.fqdn))"'
Expected output
ise-01 (ise-01.inside.domusdigitalis.dev)

17.4. 11.4 MnT API Test

netapi ise mnt count
Expected output
Total Active Sessions: 3

17.5. 11.5 DataConnect Test

netapi ise dc test
Expected output
✓ Connected successfully!
Host: ise-01.inside.domusdigitalis.dev
Port: 2484
Service: cpm10
User: dataconnect

DataConnect Troubleshooting:

  • DPY-6006 hostname mismatch: Change ISE_DATACONNECT_HOST from IP to FQDN

  • ORA-01017 invalid credentials: Verify password matches ISE DataConnect setting

  • ORA-28000 account locked: Toggle DataConnect off/on in ISE GUI to unlock

  • SSL verification failed: Ensure ISE_DATACONNECT_CA points to valid CA chain

DataConnect password requirements: 12-30 chars, A-Z, a-z, 0-9, and one of #$%&*+,-.:;=?^_~

17.6. 11.6 pxGrid Test

netapi ise pxgrid test
Expected output
✓ pxGrid connection successful
Host: ise-01.inside.domusdigitalis.dev:8910
Client: netapi-pxgrid

17.7. 11.7 802.1X Authentication Validation

Connect a client via 802.1X:

sudo nmcli connection up "Wired-802.1X-Vault"

Verify ISE processed the authentication:

netapi ise dc query "SELECT USERNAME, ISE_NODE, POLICY_SET_NAME, AUTHORIZATION_RULE, PASSED
FROM RADIUS_AUTHENTICATIONS
WHERE AUTHENTICATION_PROTOCOL = 'EAP-TLS'
  AND TIMESTAMP_TIMEZONE > SYSDATE - INTERVAL '1' HOUR
ORDER BY TIMESTAMP_TIMEZONE DESC
FETCH FIRST 5 ROWS ONLY"
Expected output
USERNAME                                 ISE_NODE  POLICY_SET_NAME      AUTHORIZATION_RULE      PASSED
modestus-razer.inside.domusdigitalis.dev ise-01    Domus-Wired 802.1X   Linux_EAP-TLS_Permit    Pass

Critical Validation:

  • ISE_NODE shows ise-01 (not ise-02) - confirms new server is handling requests

  • PASSED shows Pass - confirms successful authentication

  • POLICY_SET_NAME and AUTHORIZATION_RULE are correct - confirms policy is applied

17.8. DataConnect Queries for Ongoing Monitoring

Recent Successful Authentications
netapi ise dc query "SELECT USERNAME, ISE_NODE, NAS_IP_ADDRESS, FRAMED_IP_ADDRESS, PASSED
FROM RADIUS_AUTHENTICATIONS
WHERE PASSED = 1 AND TIMESTAMP_TIMEZONE > SYSDATE - 1
ORDER BY TIMESTAMP_TIMEZONE DESC
FETCH FIRST 20 ROWS ONLY"
Authentication Failures
netapi ise dc query "SELECT USERNAME, ISE_NODE, FAILURE_REASON, TIMESTAMP_TIMEZONE
FROM RADIUS_AUTHENTICATIONS
WHERE PASSED = 0 AND TIMESTAMP_TIMEZONE > SYSDATE - 1
ORDER BY TIMESTAMP_TIMEZONE DESC
FETCH FIRST 20 ROWS ONLY"
EAP-TLS Authentications by Policy Set
netapi ise dc query "SELECT POLICY_SET_NAME, COUNT(*) AS AUTH_COUNT
FROM RADIUS_AUTHENTICATIONS
WHERE AUTHENTICATION_PROTOCOL = 'EAP-TLS'
  AND TIMESTAMP_TIMEZONE > SYSDATE - 1
GROUP BY POLICY_SET_NAME
ORDER BY AUTH_COUNT DESC"

18. Rollback

If ise-01 deployment fails and rollback is needed:

# Stop ise-01
sudo virsh shutdown ise-01

# Start ise-02
sudo virsh start ise-02

# Revert DNS if changed
# On home-dc01:
Remove-DnsServerResourceRecord -ZoneName "{domain}" -Name "ise" -RRType A
Add-DnsServerResourceRecordA -ZoneName "{domain}" -Name "ise" -IPv4Address "{ise-01-ip}"

# Update dsec environment back to ise-02

Restore from backup if needed:

netapi ise list-backups --repo nas-01
# Find: pre-ise35-ha
netapi ise restore --repo nas-01 --name pre-ise35-ha

19. Troubleshooting

19.1. VM Disk Corruption (NFS Storage)

Symptom: ISE VM boots to emergency mode with I/O errors:

blk_update_request: I/O error, dev vda, sector 93521729 op 0x0:(READ)
EXT4-fs (vda3): error loading journal
mount: /sysroot: can't read superblock on /dev/vda3

Root Cause: NAS became unreachable during VM operation (e.g., switch port VLAN misconfiguration, 802.1X blocking infrastructure port). NFS disconnect corrupts VM filesystem.

Recovery:

# Check disk integrity (container may be OK even if filesystem corrupt)
sudo qemu-img check /mnt/nas/vms/ise-02.qcow2

If filesystem corrupt (journal/superblock errors), redeploy:

# Delete corrupted VM
sudo virsh destroy ise-02
sudo virsh undefine ise-02 --remove-all-storage

# Redeploy from ISO (see Phase 2)

Prevention:

  • NEVER put 802.1X on infrastructure ports (NAS, KVM hosts, switches)

  • Add infrastructure ports to switch config checklist

  • Consider local SSD for critical VMs instead of NFS

19.2. ISO Not Attached After virt-install

Symptom: VM shows "No bootable media" or ZTP (Zero Touch Provisioning) at boot.

Diagnosis:

sudo virsh domblklist ise-02

If sda shows -, ISO is not attached:

 Target   Source
-------------------------------------
 vda      /mnt/nas/vms/ise-02.qcow2
 sda      -

Fix:

# Attach ISO
sudo virsh change-media ise-02 sda /mnt/nas/isos/Cisco-ISE-3.5.0.527.SPA.x86_64.iso --insert --config

# Must destroy/start for --config to take effect
sudo virsh destroy ise-02
sudo virsh start ise-02

Verify:

sudo virsh domblklist ise-02

Should show:

 Target   Source
------------------------------------------------------------
 vda      /mnt/nas/vms/ise-02.qcow2
 sda      /mnt/nas/isos/Cisco-ISE-3.5.0.527.SPA.x86_64.iso

19.3. Boot Order Issues

Symptom: VM boots from disk instead of CD-ROM.

Fix:

sudo virt-xml ise-02 --edit --boot cdrom,hd
sudo virsh destroy ise-02
sudo virsh start ise-02

19.4. ZTP Auto-Install Halts (Boot Menu Selection Required)

Symptom: ISE boots from ISO but shows:

***** Auto install configured
***** The ZTP configuration image is missing or improper. Automatic installation flow exited.
***** Power off and attach the proper ZTP configuration image or choose manual boot to proceed.
[   44.710453] reboot: System halted

Root Cause: ISE ISO defaults to ZTP (Zero Touch Provisioning) mode. Without a ZTP config image, it halts.

Fix: You MUST select Option 1 from the graphical boot menu:

Option Description

1

Cisco ISE Installation (Keyboard/Monitor) ← SELECT THIS

2

Cisco ISE Installation (Serial Console)

3

System Utilities

4

Boot from Hard Drive

Access via Cockpit:

  1. Open Cockpit: <kvm-host>:9090

  2. Navigate to Virtual Machines → ise-02 → Console

  3. Before VM boots past BIOS, click in console window

  4. Select Option 1 when boot menu appears

  5. Installation wizard will start

The boot menu only appears briefly (~10 seconds). If you miss it, the VM defaults to ZTP mode and halts. Destroy and restart the VM to try again:

sudo virsh destroy ise-02
sudo virsh start ise-02

19.5. Synology NAS: SCP Fails but rsync Works

Symptom: SCP returns "No such file or directory" even though path exists.

Fix: Use rsync instead of scp for Synology NAS:

# WRONG - fails on Synology
scp file.tar.gz nas-01:/volume1/ise_backups/

# CORRECT - works on Synology
rsync -avP file.tar.gz nas-01:/volume1/ise_backups/

21. Notes

  • ISE 3.5 installation takes 30-45 minutes

  • Always backup before major changes

  • CPU pinning prevents resource contention

  • ISE 3.5 has native WS2025 AD support (no workaround needed)

  • DataConnect requires FQDN (not IP) for SSL hostname verification

  • DataConnect password must contain special char from: #$%&*+,-.:;=?^_~

  • Keep ise-02 available for 1-2 weeks post-migration

  • Validated 2026-02-11: All 5 API surfaces (ERS, OpenAPI, MnT, DataConnect, pxGrid) operational on ise-01