End-to-End 802.1X Validation Guide
Overview
This document provides a comprehensive end-to-end validation checklist for Linux 802.1X EAP-TLS authentication covering:
-
Linux client configuration
-
Active Directory Certificate Services (AD CS)
-
Cisco ISE policy and authentication
-
Network Access Devices (wired switches and wireless controllers)
Each section includes both GUI procedures and CLI/netapi commands for programmability.
|
Validation Order: Work backwards from the client - if auth fails, validate each component in this order:
|
1. Linux Client Validation
1.1 Certificate Validation
GUI Approach
-
Open certificate file with file manager or
xdg-open -
Verify Subject CN matches hostname
-
Check validity dates
-
Verify issuer matches your CA
CLI Approach
# Verify client certificate
openssl x509 -in /etc/ssl/certs/<hostname>-eaptls.pem -noout -subject -issuer -dates -serial
# Expected output:
# subject=O=Domus Digitalis, OU=Endpoints, CN=modestus-p50.inside.domusdigitalis.dev
# issuer=CN=HOME-ROOT-CA, DC=inside, DC=domusdigitalis, DC=dev
# notBefore=Jan 14 00:00:00 2026 GMT
# notAfter=Jan 14 00:00:00 2028 GMT
# Verify CA certificate
openssl x509 -in /etc/ssl/certs/HOME-ROOT-CA.pem -noout -subject -issuer
# Verify certificate chain
openssl verify -CAfile /etc/ssl/certs/HOME-ROOT-CA.pem /etc/ssl/certs/<hostname>-eaptls.pem
# Expected: /etc/ssl/certs/<hostname>-eaptls.pem: OK
# Check private key matches certificate
openssl x509 -noout -modulus -in /etc/ssl/certs/<hostname>-eaptls.pem | openssl md5
openssl rsa -noout -modulus -in /etc/ssl/private/<hostname>-eaptls.key | openssl md5
# Both MD5 hashes must match
1.2 wpa_supplicant Configuration
1.3 Authentication Status
# Wired - check authentication state
wpa_cli -i enp0s31f6 status
# Look for: wpa_state=COMPLETED, EAP state=SUCCESS
# Wireless - check authentication state
wpa_cli -i wlan0 status
# Look for: wpa_state=COMPLETED, EAP state=SUCCESS, ssid=Domus-Secure
# Check IP assignment
ip addr show enp0s31f6
ip addr show wlan0
# Check default route
ip route | grep default
2. Active Directory Certificate Services (AD CS) Validation
2.1 GUI Approach (Windows Server)
-
Open Certification Authority MMC (
certsrv.msc) -
Expand CA → Issued Certificates
-
Find certificate by CN or serial number
-
Verify:
-
Certificate Template:
LinuxEAPTLSor equivalent -
Subject: Matches client hostname
-
Valid From/To: Current date within range
-
Intended Purposes: Client Authentication
-
-
Check Revoked Certificates - ensure client cert NOT listed
2.2 CLI Approach (PowerShell on CA)
# List issued certificates
Get-ChildItem -Path Cert:\LocalMachine\CA | Where-Object { $_.Subject -like "*modestus-p50*" }
# Check certificate details
certutil -view -restrict "CommonName=modestus-p50.{domain}"
# Check CRL
certutil -URL http://ca.{domain}/CertEnroll/HOME-ROOT-CA.crl
# Verify certificate not revoked
certutil -isvalid <SerialNumber>
2.3 From Linux Client
# Download and check CRL
curl -s http://ca.inside.domusdigitalis.dev/CertEnroll/HOME-ROOT-CA.crl -o /tmp/ca.crl
openssl crl -in /tmp/ca.crl -inform DER -text -noout | head -30
# Check if certificate serial is in CRL
SERIAL=$(openssl x509 -in /etc/ssl/certs/<hostname>-eaptls.pem -noout -serial | cut -d= -f2)
openssl crl -in /tmp/ca.crl -inform DER -text -noout | grep -i $SERIAL && echo "REVOKED!" || echo "NOT REVOKED"
3. Cisco ISE Validation
3.1 GUI Approach
Live Authentication Check
-
Navigate to Operations → RADIUS → Live Logs
-
Filter by:
-
Endpoint ID (MAC address)
-
Username (certificate CN)
-
Time range
-
-
Verify:
-
Status: Passed (green checkmark)
-
Authentication Protocol: EAP-TLS
-
Authorization Profile: Expected profile name
-
Identity Group: Correct group assignment
-
3.2 CLI/netapi Approach
# Check active sessions (MnT API)
uv run netapi ise mnt sessions
uv run netapi ise mnt sessions --details
# Get specific session by MAC
uv run netapi ise mnt session <MAC_ADDRESS>
# Check session count
uv run netapi ise mnt count
# Check failed authentications
uv run netapi ise mnt failed
# DataConnect - comprehensive session view
uv run netapi ise dc session <MAC_ADDRESS>
# Recent authentications
uv run netapi ise dc recent --hours 4 --limit 50
# Failed authentications
uv run netapi ise dc failed --hours 24
Policy Verification via API
# Get policy sets
uv run netapi ise get-policy-sets
# Get specific policy set with rules
uv run netapi ise get-policy-set "Wired Dot1X Closed" --rules
# Get authorization profiles
uv run netapi ise get-authz-profiles
# Get specific profile
uv run netapi ise get-authz-profile "Linux_EAP_TLS_Profile"
# Get endpoint details
uv run netapi ise get-endpoint <MAC_ADDRESS>
4. Network Access Device (NAD) Validation
4.1 Wired Switch Validation
GUI Approach
-
SSH to switch or use console
-
Run show commands manually
-
Compare output to expected values
CLI Approach
# Check RADIUS server configuration
uv run netapi ios show radius-servers
# Check AAA configuration
uv run netapi ios show aaa-groups
# Check VLANs
uv run netapi ios show vlans
# Check access sessions on switch
uv run netapi ios exec "show access-session"
# Check specific interface
uv run netapi ios exec "show access-session interface GigabitEthernet1/0/1 details"
# Check authentication method
uv run netapi ios exec "show authentication sessions"
Direct Switch Commands
! Check access session for specific MAC
show access-session mac <MAC_ADDRESS> details
! Expected output should show:
! Status: Authorized
! Method: dot1x (or mab for MAB fallback)
! ACS ACL: (if dACL applied)
! Vlan: Expected VLAN number
! Check interface configuration
show run interface GigabitEthernet1/0/X
! Check RADIUS statistics
show aaa servers
! Debug (use sparingly!)
debug radius authentication
debug dot1x all
4.2 Wireless LAN Controller (WLC) Validation
GUI Approach (WLC Web UI)
-
Login to WLC web interface
-
Navigate to Monitor → Clients
-
Find client by MAC address
-
Verify:
-
Status: Associated
-
Authentication: Central (if FlexConnect)
-
Policy Type: WPA2
-
EAP Type: EAP-TLS
-
VLAN: Expected VLAN
-
CLI/netapi Approach
# Get WLC info
uv run netapi wlc get-info
# Check WLC health
uv run netapi wlc get-health
# List access points
uv run netapi wlc get-aps
# List connected clients
uv run netapi wlc get-clients
# List WLANs
uv run netapi wlc get-wlans
Direct WLC Commands (9800)
! Check wireless client details
show wireless client mac-address <MAC_ADDRESS> detail
! Check client summary
show wireless client summary
! Check WLAN configuration
show wlan summary
show wlan name Domus-Secure
! Check AAA configuration
show aaa servers
show aaa method-lists authentication
! Check FlexConnect client (if applicable)
show ap name <AP_NAME> config dot11 5ghz
5. End-to-End Connectivity Test
Once authentication is validated, test actual connectivity:
# From Linux client - basic connectivity
ping -c 4 gateway_ip
ping -c 4 dns_server_ip
ping -c 4 dc-01.inside.domusdigitalis.dev
# DNS resolution
dig +short inside.domusdigitalis.dev
nslookup dc-01.inside.domusdigitalis.dev
# Kerberos ticket (if domain-joined)
klist
kinit username@DOMAIN.COM
# LDAP connectivity
ldapsearch -x -H ldap://dc-01.inside.domusdigitalis.dev -b "DC=inside,DC=domusdigitalis,DC=dev" "(cn=*)" cn -LLL | head -20
# SMB/CIFS share access
smbclient -L //fileserver.domain.com -U username
6. Validation Checklist Summary
| Component | Validation Point | GUI | CLI/netapi |
|---|---|---|---|
Client |
Certificate valid and matches hostname |
File manager |
|
Client |
wpa_supplicant service running |
systemd GUI |
|
Client |
Authentication state COMPLETED |
- |
|
Client |
IP address assigned |
Network settings |
|
AD CS |
Certificate issued and not revoked |
certsrv.msc |
|
ISE |
Authentication passed in Live Logs |
RADIUS Live Logs |
|
ISE |
Correct authorization profile applied |
Live Log details |
|
Switch |
Access session authorized |
- |
|
WLC |
Client associated with EAP-TLS |
Monitor → Clients |
|
E2E |
Ping gateway and DNS |
- |
|
7. Troubleshooting Quick Reference
| Symptom | First Check |
|---|---|
wpa_state=DISCONNECTED |
Certificate paths in wpa_supplicant.conf |
EAP state=FAILURE |
ISE Live Logs for detailed error |
No IP address |
DHCP server reachable? Check dACL permits UDP 67/68 |
ISE shows "Authentication failed" |
Certificate chain - is ROOT CA trusted in ISE? |
Switch shows "Unauthorized" |
RADIUS shared secret match between switch and ISE |
WLC shows "Excluded" |
Check exclusion policies, try |
8. Comprehensive Verification Script
This automated script validates all ISE EAP-TLS components in one execution.
8.1 Prerequisites
# Load ISE credentials
dsource d000 dev/network
# Ensure netapi and SSH access configured
8.2 Complete Verification Script
#!/bin/bash
# Complete ISE Configuration Verification for Linux EAP-TLS
# Save as: verify-ise-complete.sh
# Usage: dsource d000 dev/network && ./verify-ise-complete.sh
set -e
echo "╔════════════════════════════════════════════════════════════════╗"
echo "║ ISE Linux EAP-TLS Complete Configuration Verification ║"
echo "╚════════════════════════════════════════════════════════════════╝"
echo -e "\n=== 1. Authorization Profile: Linux_EAPTLS_Admins ==="
PROFILE=$(netapi ise -f json get-authz-profiles | jq -r '.[] | select(.name == "Linux_EAPTLS_Admins")')
if [ -n "$PROFILE" ]; then
echo "✓ Profile exists"
echo "$PROFILE" | jq '{name, vlan, dacl: .dacl_name, access_type}'
else
echo "✗ Profile NOT found - needs creation"
echo " Command: netapi ise create-authz-profile --name Linux_EAPTLS_Admins --vlan RESEARCH_VLAN --dacl LINUX_EAPTLS_PERMIT_ALL"
fi
echo -e "\n=== 2. DACL: LINUX_EAPTLS_PERMIT_ALL ==="
DACL=$(netapi ise get-dacls | grep "LINUX_EAPTLS_PERMIT_ALL")
if [ -n "$DACL" ]; then
echo "✓ DACL exists: $DACL"
else
echo "✗ DACL NOT found - needs creation"
echo " Command: netapi ise create-dacl -n LINUX_EAPTLS_PERMIT_ALL --acl 'permit ip any any'"
fi
echo -e "\n=== 3. Active Directory Configuration ==="
echo "Checking AD join point and groups (may require ISE GUI access)..."
netapi ise -f json get-ad-join-points 2>/dev/null | jq -r '.[] | {name, domain, groups}' || \
echo " Note: AD join point verification requires ISE GUI:"
echo " - Administration → Identity Management → External Identity Sources → Active Directory"
echo " - Verify join point: inside.domusdigitalis.dev"
echo " - Groups tab → verify GRP-Linux-Admin-Workstations is added"
echo -e "\n=== 4. AD Group: GRP-Linux-Admin-Workstations ==="
echo "Checking via PowerShell on DC..."
ssh home-dc01 'powershell -Command "Get-ADGroup -Identity GRP-Linux-Admin-Workstations -Properties Members | Select-Object Name, @{Name=\"MemberCount\";Expression={$_.Members.Count}}"' 2>/dev/null || \
echo " Cannot verify via SSH - check manually"
echo -e "\n=== 5. Computer Account in AD Group ==="
ssh home-dc01 'powershell -Command "Get-ADGroupMember -Identity GRP-Linux-Admin-Workstations | Select-Object Name, SamAccountName"' 2>/dev/null || \
echo " Cannot verify via SSH - check manually"
echo -e "\n=== 6. Authorization Rule: Linux_Admin_EAP-TLS ==="
RULE=$(netapi ise get-authz-rules "Wired Dot1X Closed" | grep -A5 "Linux_Admin_EAP-TLS")
if [ -n "$RULE" ]; then
echo "✓ Rule exists:"
echo "$RULE"
else
echo "✗ Rule NOT found - needs creation"
echo " Command:"
echo " netapi ise add-authz-rule \"Wired Dot1X Closed\" \\"
echo " \"Linux_Admin_EAP-TLS\" \\"
echo " \"Linux_EAPTLS_Admins\" \\"
echo " --dict \"INSIDE-AD\" \\"
echo " --attr \"ExternalGroups\" \\"
echo " --value \"inside.domusdigitalis.dev/Groups/GRP-Linux-Admin-Workstations\" \\"
echo " --operator contains"
fi
echo -e "\n=== 7. Client Certificate Configuration ==="
echo "Checking modestus-razer certificate..."
if [ -f /etc/ssl/certs/modestus-razer-eaptls.pem ] && [ -f /etc/ssl/private/modestus-razer-eaptls.key ]; then
CERT_MOD=$(openssl x509 -noout -modulus -in /etc/ssl/certs/modestus-razer-eaptls.pem | openssl md5)
KEY_MOD=$(openssl rsa -noout -modulus -in /etc/ssl/private/modestus-razer-eaptls.key 2>/dev/null | openssl md5)
if [ "$CERT_MOD" = "$KEY_MOD" ]; then
echo "✓ Certificate and key match"
echo " Subject: $(openssl x509 -noout -subject -in /etc/ssl/certs/modestus-razer-eaptls.pem)"
echo " Issuer: $(openssl x509 -noout -issuer -in /etc/ssl/certs/modestus-razer-eaptls.pem)"
echo " Expiry: $(openssl x509 -noout -enddate -in /etc/ssl/certs/modestus-razer-eaptls.pem)"
else
echo "✗ Certificate/key mismatch!"
echo " Cert hash: $CERT_MOD"
echo " Key hash: $KEY_MOD"
fi
else
echo "✗ Certificate or key file not found"
fi
echo -e "\n=== 8. NetworkManager 802.1X Configuration ==="
if nmcli connection show "Wired-802.1X" &>/dev/null; then
echo "✓ Connection profile exists"
nmcli connection show "Wired-802.1X" | grep -E "802-1x\.(eap|identity|client-cert|private-key|private-key-password-flags)"
else
echo "✗ No Wired-802.1X connection found"
fi
echo -e "\n=== 9. Domain Join Status ==="
if sudo net ads testjoin 2>&1 | grep -q "Join is OK"; then
echo "✓ Domain join successful"
echo " Computer: $(hostname)"
echo " Domain: $(sudo net ads info 2>/dev/null | grep "LDAP server name" || echo "inside.domusdigitalis.dev")"
else
echo "✗ Not domain joined or join issue"
fi
echo -e "\n=== 10. SSSD Status ==="
if systemctl is-active sssd &>/dev/null; then
echo "✓ SSSD running"
if id administrator@inside.domusdigitalis.dev &>/dev/null; then
echo "✓ AD user resolution working"
else
echo "✗ AD user resolution failing"
fi
else
echo "✗ SSSD not running"
fi
echo -e "\n╔════════════════════════════════════════════════════════════════╗"
echo "║ Configuration Summary ║"
echo "╚════════════════════════════════════════════════════════════════╝"
echo "Review the checks above. Items marked with ✗ need attention."
echo ""
echo "To create missing ISE components, use the commands shown above."
echo "After configuration is complete, test with:"
echo " sudo nmcli connection down Wired-802.1X && sudo nmcli connection up Wired-802.1X"
echo " netapi ise mnt session \$(cat /sys/class/net/enp130s0/address)"
8.3 Expected Output
╔════════════════════════════════════════════════════════════════╗
║ ISE Linux EAP-TLS Complete Configuration Verification ║
╚════════════════════════════════════════════════════════════════╝
=== 1. Authorization Profile: Linux_EAPTLS_Admins ===
✓ Profile exists
{
"name": "Linux_EAPTLS_Admins",
"vlan": "RESEARCH_VLAN",
"dacl": "LINUX_EAPTLS_PERMIT_ALL",
"access_type": "ACCESS_ACCEPT"
}
=== 2. DACL: LINUX_EAPTLS_PERMIT_ALL ===
✓ DACL exists: │ LINUX_EAPTLS_PERMIT_ALL │ 948779a0-f18b-11f0-b76e-52c54a1d1f56 │
=== 3. Active Directory Configuration ===
✓ AD join point configured: INSIDE-AD
=== 4. AD Group: GRP-Linux-Admin-Workstations ===
Name MemberCount
---- -----------
GRP-Linux-Admin-Workstations 1
=== 5. Computer Account in AD Group ===
Name SamAccountName
---- --------------
MODESTUS-RAZER MODESTUS-RAZER$
=== 6. Authorization Rule: Linux_Admin_EAP-TLS ===
✓ Rule exists:
Name: Linux_Admin_EAP-TLS
Profile: Linux_EAPTLS_Admins
Rank: 0
Condition: INSIDE-AD.ExternalGroups contains 'GRP-Linux-Admin-Workstations'
=== 7. Client Certificate Configuration ===
✓ Certificate and key match
Subject: O=Domus Digitalis, OU=Endpoints, CN=modestus-razer.{domain}
Issuer: CN=HOME-ROOT-CA, DC=inside, DC=domusdigitalis, DC=dev
Expiry: notAfter=Jan 27 00:00:00 2028 GMT
=== 8. NetworkManager 802.1X Configuration ===
✓ Connection profile exists
802-1x.eap: tls
802-1x.identity: modestus-razer.{domain}
802-1x.client-cert: file://{cert-dir}/modestus-razer-eaptls.pem
802-1x.private-key: file://{key-dir}/modestus-razer-eaptls.key
802-1x.private-key-password-flags: 4
=== 9. Domain Join Status ===
✓ Domain join successful
Computer: modestus-razer
Domain: {domain}
=== 10. SSSD Status ===
✓ SSSD running
✓ AD user resolution working
8.4 Troubleshooting Missing Components
If verification shows ✗ marks, follow these remediation steps:
Missing Authorization Profile
# Create authorization profile
netapi ise create-authz-profile \
--name "Linux_EAPTLS_Admins" \
--vlan "RESEARCH_VLAN" \
--dacl "LINUX_EAPTLS_PERMIT_ALL"
Missing DACL
# Create DACL
netapi ise create-dacl \
-n "LINUX_EAPTLS_PERMIT_ALL" \
--acl "permit ip any any"
Missing Authorization Rule
# Create authorization rule
# NOTE: AD group value must use full LDAP path format: "domain.com/Groups/GroupName"
netapi ise add-authz-rule "Wired Dot1X Closed" \
"Linux_Admin_EAP-TLS" \
"Linux_EAPTLS_Admins" \
--dict "INSIDE-AD" \
--attr "ExternalGroups" \
--value "inside.domusdigitalis.dev/Groups/GRP-Linux-Admin-Workstations" \
--operator contains