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. Client certificates and wpa_supplicant

  2. NAD RADIUS configuration

  3. ISE policy and authentication

  4. AD CS certificate chain


1. Linux Client Validation

1.1 Certificate Validation

GUI Approach

  1. Open certificate file with file manager or xdg-open

  2. Verify Subject CN matches hostname

  3. Check validity dates

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

Wired (enp0s31f6 or similar)

# Check config exists
cat /etc/wpa_supplicant/wpa_supplicant-wired-enp0s31f6.conf

# Verify service enabled
systemctl is-enabled wpa_supplicant-wired@enp0s31f6

# Check service status
systemctl status wpa_supplicant-wired@enp0s31f6

Wireless (wlan0)

# Check config exists
cat /etc/wpa_supplicant/wpa_supplicant-wlan0.conf

# Verify service enabled
systemctl is-enabled wpa_supplicant-wifi@wlan0

# Check service status
systemctl status wpa_supplicant-wifi@wlan0

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

1.4 DHCP Validation

# Check dhcpcd status
systemctl status dhcpcd

# Check DHCP leases
cat /var/lib/dhcpcd/dhcpcd-enp0s31f6.lease 2>/dev/null
cat /var/lib/dhcpcd/dhcpcd-wlan0.lease 2>/dev/null

# Force DHCP renewal
sudo dhcpcd -n enp0s31f6
sudo dhcpcd -n wlan0

1.5 PAM/SSSD Validation (Domain-Joined)

# Check SSSD status
systemctl status sssd

# Verify domain join
realm list

# Check user resolution
id username@domain.com

# Test SSSD authentication directly
sudo sssctl user-checks username@domain.com -a auth

# Test su login
su - username@domain.com

2. Active Directory Certificate Services (AD CS) Validation

2.1 GUI Approach (Windows Server)

  1. Open Certification Authority MMC (certsrv.msc)

  2. Expand CA → Issued Certificates

  3. Find certificate by CN or serial number

  4. Verify:

    • Certificate Template: LinuxEAPTLS or equivalent

    • Subject: Matches client hostname

    • Valid From/To: Current date within range

    • Intended Purposes: Client Authentication

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

  1. Navigate to Operations → RADIUS → Live Logs

  2. Filter by:

    • Endpoint ID (MAC address)

    • Username (certificate CN)

    • Time range

  3. Verify:

    • Status: Passed (green checkmark)

    • Authentication Protocol: EAP-TLS

    • Authorization Profile: Expected profile name

    • Identity Group: Correct group assignment

Policy Verification

  1. Policy → Policy Sets → Select policy set

  2. Verify authentication policy matches EAP-TLS

  3. Verify authorization rules and conditions

  4. Check Allowed Protocols includes EAP-TLS

Certificate Store

  1. Administration → System → Certificates → Trusted Certificates

  2. Verify ROOT CA certificate is imported

  3. Check certificate is marked for Trust for client authentication

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

  1. SSH to switch or use console

  2. Run show commands manually

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

  1. Login to WLC web interface

  2. Navigate to Monitor → Clients

  3. Find client by MAC address

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

openssl x509 -in …​ -noout

Client

wpa_supplicant service running

systemd GUI

systemctl status wpa_supplicant-*

Client

Authentication state COMPLETED

-

wpa_cli -i <iface> status

Client

IP address assigned

Network settings

ip addr show

AD CS

Certificate issued and not revoked

certsrv.msc

certutil -view

ISE

Authentication passed in Live Logs

RADIUS Live Logs

netapi ise mnt sessions

ISE

Correct authorization profile applied

Live Log details

netapi ise dc session <MAC>

Switch

Access session authorized

-

show access-session mac <MAC> d

WLC

Client associated with EAP-TLS

Monitor → Clients

netapi wlc get-clients

E2E

Ping gateway and DNS

-

ping -c 4 <ip>


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 wireless client mac-address <MAC> deauthenticate


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

Successful verification shows:
╔════════════════════════════════════════════════════════════════╗
║  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

Certificate/Key Mismatch

Domain Join Issues