802.1X EAP-TLS
802.1X EAP-TLS client configuration, wpa_supplicant setup, and authentication debugging.
wpa_supplicant EAP-TLS Configuration
Minimal wpa_supplicant.conf for EAP-TLS — the only method worth deploying
cat /etc/wpa_supplicant/wpa_supplicant-eth0.conf
EAP-TLS config file structure — certificate paths are the whole game
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=wheel
eapol_version=2
ap_scan=0
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-802.1x.pem"
private_key="/etc/ssl/private/modestus-razer-802.1x.key"
eapol_flags=0
}
NetworkManager 802.1X Profile
Create 802.1X wired profile with nmcli — the production approach
nmcli connection add \
type ethernet \
con-name "802.1x-wired" \
ifname eth0 \
802-1x.eap tls \
802-1x.identity "modestus-razer.inside.domusdigitalis.dev" \
802-1x.ca-cert /etc/ssl/certs/domus-ca-chain.pem \
802-1x.client-cert /etc/ssl/certs/modestus-razer-802.1x.pem \
802-1x.private-key /etc/ssl/private/modestus-razer-802.1x.key \
802-1x.private-key-password "" \
connection.autoconnect yes
Activate the 802.1X connection profile
nmcli connection up 802.1x-wired
Inspect 802.1X settings on an existing profile
nmcli -f 802-1x connection show 802.1x-wired
Certificate Verification
Verify certificate chain before deploying — catches 90% of auth failures
openssl verify -CAfile /etc/ssl/certs/domus-ca-chain.pem /etc/ssl/certs/modestus-razer-802.1x.pem
Check certificate subject and SAN — ISE matches on these
openssl x509 -in /etc/ssl/certs/modestus-razer-802.1x.pem -noout -subject -ext subjectAltName
Check certificate expiry — expired certs are the silent killer
openssl x509 -in /etc/ssl/certs/modestus-razer-802.1x.pem -noout -enddate
Verify private key matches the certificate — mismatched pairs fail silently
diff <(openssl x509 -in /etc/ssl/certs/modestus-razer-802.1x.pem -noout -modulus) \
<(openssl rsa -in /etc/ssl/private/modestus-razer-802.1x.key -noout -modulus)
Authentication Testing
Start wpa_supplicant manually with debug output — the investigative tool
sudo wpa_supplicant -i eth0 -c /etc/wpa_supplicant/wpa_supplicant-eth0.conf -d
Full debug logging — when -d is not enough
sudo wpa_supplicant -i eth0 -c /etc/wpa_supplicant/wpa_supplicant-eth0.conf -dd -f /tmp/wpa_debug.log
Interactive control via wpa_cli — check status without restarting
sudo wpa_cli -i eth0 status
Force reauthentication without bouncing the interface
sudo wpa_cli -i eth0 reassociate
RADIUS Testing with eapol_test
Test EAP-TLS against RADIUS directly — bypasses the switch entirely
eapol_test -c /etc/wpa_supplicant/eapol_test.conf -a 10.50.1.20 -s <REDACTED> -r 0
eapol_test config file — same certs, different format
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-802.1x.pem"
private_key="/etc/ssl/private/modestus-razer-802.1x.key"
}
Build eapol_test from wpa_supplicant source — not packaged by default
cd wpa_supplicant-*/wpa_supplicant && make eapol_test
Troubleshooting
Check if wpa_supplicant is running and on which interface
ps aux | grep wpa_supplicant | grep -v grep
Check systemd unit status for wpa_supplicant
systemctl status wpa_supplicant@eth0.service
Watch authentication events in real time via journalctl
journalctl -u wpa_supplicant@eth0.service -f
Check EAP state from the kernel side — did the port authorize?
cat /sys/class/net/eth0/operstate
Capture EAPOL frames with tcpdump — see the handshake
sudo tcpdump -i eth0 -nn ether proto 0x888e -v
ISE Correlation
Match client MAC to ISE RADIUS Live Log — use this after auth failure
ip link show eth0 | awk '/ether/{print $2}'
Common ISE failure reasons and what they mean on the Linux side
12321 - PEAP/TLS handshake failed → Wrong CA chain or expired cert
12308 - Client cert not found → private_key path wrong or permissions
12514 - EAP-TLS handshake failed → Key/cert mismatch or missing SAN
22056 - Subject not found in ID store → identity= doesn't match cert CN/SAN
Check supplicant cert file permissions — ISE never sees the error, you do
ls -la /etc/ssl/certs/modestus-razer-802.1x.pem /etc/ssl/private/modestus-razer-802.1x.key