wpa_supplicant Configuration

wpa_supplicant is the standard Linux supplicant for 802.1X authentication. This guide covers wired EAP-TLS configuration with systemd integration.

Prerequisites

Before configuring wpa_supplicant:

  • Client certificate issued and installed

  • Private key installed with correct permissions

  • CA certificate installed

  • Network interface identified

Configuration File

Wired EAP-TLS Template

Create the configuration file at /etc/wpa_supplicant/wpa_supplicant-wired-.conf:

# 802.1X EAP-TLS Configuration for Wired Networks
# Template - replace placeholders with actual values

ctrl_interface=/run/wpa_supplicant
ctrl_interface_group=wheel
eapol_version=2
ap_scan=0
fast_reauth=1

network={
    key_mgmt=IEEE8021X
    eap=TLS
    identity="<hostname>.<domain>"
    ca_cert="/etc/ssl/certs/ca-chain.pem"
    client_cert="/etc/ssl/certs/<hostname>-eaptls.pem"
    private_key="/etc/ssl/private/<hostname>-eaptls.key"
    eapol_flags=0
}

Parameter Reference

Parameter Value Purpose

ctrl_interface

/run/wpa_supplicant

Socket path for wpa_cli control

ctrl_interface_group

wheel or netdev

Group allowed to use wpa_cli

eapol_version

2

EAPOL protocol version (use 2 for modern switches)

ap_scan

0

Disable AP scanning (wired networks)

fast_reauth

1

Enable fast reauthentication

key_mgmt

IEEE8021X

802.1X key management

eap

TLS

EAP method

identity

hostname.domain

Client identity sent to RADIUS

ca_cert

Path to CA certificate

Validates RADIUS server certificate

client_cert

Path to client certificate

Proves client identity

private_key

Path to private key

Signs authentication handshake

eapol_flags

0

Disable dynamic WEP (use 0 for wired)

File Permissions

Private keys must be protected:

# Secure the private key
sudo chmod 600 /etc/ssl/private/<hostname>-eaptls.key
sudo chown root:root /etc/ssl/private/<hostname>-eaptls.key

# Secure the configuration file (contains key path)
sudo chmod 600 /etc/wpa_supplicant/wpa_supplicant-wired-<interface>.conf
sudo chown root:root /etc/wpa_supplicant/wpa_supplicant-wired-<interface>.conf

# Verify permissions
ls -la /etc/ssl/private/<hostname>-eaptls.key
# Expected: -rw------- 1 root root

systemd Service

Create Service Unit

Create a template service at /etc/systemd/system/[email protected]:

[Unit]
Description=WPA supplicant for wired 802.1X (%I)
Requires=sys-subsystem-net-devices-%i.device
After=sys-subsystem-net-devices-%i.device
Before=network.target
Wants=network.target

[Service]
Type=simple
ExecStart=/usr/bin/wpa_supplicant -c /etc/wpa_supplicant/wpa_supplicant-wired-%I.conf -i %I -D wired
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Enable and Start

# Reload systemd
sudo systemctl daemon-reload

# Enable service for your interface
sudo systemctl enable wpa_supplicant-wired@<interface>.service

# Start service
sudo systemctl start wpa_supplicant-wired@<interface>.service

# Verify status
systemctl status wpa_supplicant-wired@<interface>.service

Manual Testing

Before enabling the systemd service, test manually:

# Run in foreground with debug output
sudo wpa_supplicant -i <interface> \
    -c /etc/wpa_supplicant/wpa_supplicant-wired-<interface>.conf \
    -D wired \
    -d

# Expected output on success:
# EAP-TLS: Received Finished
# CTRL-EVENT-EAP-SUCCESS
# CTRL-EVENT-CONNECTED

wpa_cli Commands

Use wpa_cli to interact with a running wpa_supplicant:

# Check authentication status
sudo wpa_cli -i <interface> status

# Force reauthentication
sudo wpa_cli -i <interface> logoff
sudo wpa_cli -i <interface> logon

# Reassociate
sudo wpa_cli -i <interface> reassociate

# View current configuration
sudo wpa_cli -i <interface> list_networks

Status Output

$ sudo wpa_cli -i eth0 status
bssid=00:00:00:00:00:00
ssid=
id=0
mode=station
wpa_state=COMPLETED          # <-- This means authenticated
key_mgmt=IEEE8021X
ip_address=10.x.x.x
Supplicant PAE state=AUTHENTICATED
EAP state=SUCCESS
selectedMethod=13 (EAP-TLS)

Key indicators: - wpa_state=COMPLETED — authentication successful - Supplicant PAE state=AUTHENTICATED — port authorized - EAP state=SUCCESS — EAP exchange completed

Identity Format

The identity field must match what your RADIUS server expects.

Format Example

Hostname only

workstation01

FQDN

workstation01.corp.example.com

UPN style

host/workstation01.corp.example.com

Machine account

[email protected]

Check your RADIUS server’s certificate authentication profile for the expected format. Cisco ISE commonly uses the certificate Subject CN or SAN.

Certificate Chain

The ca_cert should contain the full trust chain:

# Create chain file (Root CA + Intermediate CA)
cat root-ca.pem intermediate-ca.pem > /etc/ssl/certs/ca-chain.pem

# Verify chain
openssl verify -CAfile /etc/ssl/certs/ca-chain.pem \
    /etc/ssl/certs/<hostname>-eaptls.pem

If verification fails, the RADIUS server certificate won’t be trusted.

Network Stack Integration

With dhcpcd

After authentication, obtain IP via DHCP:

# dhcpcd should start automatically after port authorization
# If not, manually request:
sudo dhcpcd <interface>

With NetworkManager

If using NetworkManager alongside wpa_supplicant:

# Tell NetworkManager to ignore the interface
# Add to /etc/NetworkManager/conf.d/unmanaged.conf:
[keyfile]
unmanaged-devices=interface-name:<interface>

# Restart NetworkManager
sudo systemctl restart NetworkManager

Logging

View Authentication Logs

# Follow wpa_supplicant logs
sudo journalctl -u wpa_supplicant-wired@<interface> -f

# Filter for EAP events
sudo journalctl -u wpa_supplicant-wired@<interface> | grep -i eap

Enable Debug Logging

For troubleshooting, increase verbosity in the service file:

ExecStart=/usr/bin/wpa_supplicant -c /etc/wpa_supplicant/... -i %I -D wired -dd

The -dd flag enables maximum debug output.