802.1X Port Security
802.1X port security provides a framework for controlling access to a switched Ethernet network on a per-port basis. Ports can be configured to operate in a locked state. If a port is configured this way, all user traffic is blocked until authentication completes. Only special 802.1X control messages (EAPOL frames) are allowed to reach the authenticator software running on the host.
The authenticator validates client credentials using Extensible Authentication Protocol (EAP) methods. This can be done locally by hostapd acting as an EAP server, or remotely through a RADIUS backend. Once the client is authenticated, its MAC address is explicitly installed into the forwarding database (FDB). From this point, normal Ethernet traffic for that MAC is permitted. All other sources remain blocked, ensuring that only authenticated devices can communicate through the switch.
By combining hardware enforcement in the driver and dynamic authorization logic in user space, 802.1X port security ensures that unauthorized or rogue clients cannot send traffic onto the network. It also prevents accidental leaks by disabling flooding and learning until authentication has succeeded. This provides a strong security boundary at the first hop of the network.
Setup Overview
A setup could consist of three components working together:
-
Supplicant (
wpa_supplicant
) running on the client device. -
Authenticator (
hostapd
) running on the switch. It processes EAPOL frames and validates credentials. -
Switch driver + Linux bridge, which enforce the locked-port behavior and only allow traffic from authorized MAC addresses.
The authenticator uses hostapd_cli
, a command-line client for hostapd’s
control interface, in action mode to trigger a helper script. In this mode,
hostapd_cli
stays connected to hostapd and listens for events such as client
connect, disconnect, or EAP success/failure. When an event occurs, it executes
the helper script with the event details as arguments. The script then installs
or removes FDB entries dynamically, ensuring that only authenticated MAC
addresses are allowed to forward traffic.
In the setup described here, hostapd is configured to act as the EAP server, validating client credentials directly. An alternative deployment is to have hostapd forward EAP requests to an external RADIUS server for authentication. This document focuses on the simpler case where hostapd itself provides the EAP server functionality.
+----------------+ +---------------------------------------------------------+
| Client host | | Switch host |
|----------------| |---------------------------------------------------------|
| | | +-------------------+ +-------------------------+ |
| Supplicant | | | Authenticator | | Switch Driver + Linux | |
|(wpa_supplicant)| | | (hostapd) | | Bridge | |
| | | | | | (FDB enforcement) | |
| | | +-------------------+ +-------------------------+ |
+----------------+ +---------------------------------------------------------+
| | [Locked Port]
| EAPOL frames | |
|---------------------->| |
| | Authentication decision |
| | |
| | hostapd_cli action script |
| | runs "bridge fdb add" |
| | (if authenticated) |
| |-------------------------------->|
| | v
| | [FDB add → Port Unlocked]
| | |
| Normal traffic now allowed (MAC authorized) |
|<--------------------------------------------------------|
Client (Supplicant)
The client must run a wired supplicant such as wpa_supplicant, which is responsible for sending 802.1X credentials to the switch. The credentials configured in the supplicant must match the EAP configuration defined in the authenticator.
Platform (Authenticator)
On the switch, a user-space authenticator daemon such as hostapd must be running. Hostapd terminates EAPOL frames from the client and authenticates the credentials. When using the internal EAP server, no external RADIUS server is required.
Hostapd listens for EAPOL frames, parses the EAP messages, and verifies them against its internal user database. When authentication succeeds, it installs the client’s MAC into the bridge FDB via a helper script. If authentication fails, the port remains locked.
hostapd.conf (internal EAP server)
Place this file at /etc/hostapd/hostapd.conf
.
interface=eth1
driver=none
ieee8021x=1
eapol_version=2
# Enable internal EAP server
eap_server=1
# Define authentication method
eap_user_file=/etc/hostapd.eap_user
ctrl_interface=/var/run/hostapd
logger_syslog=-1
logger_stdout=1
logger_stdout_level=2
hostapd.eap_user
Place this file at /etc/hostapd.eap_user
.
# identity EAP method
"testuser" MD5 "password123"
hostapd_cli Action Script
To dynamically manage FDB entries based on authentication events, run hostapd
with hostapd_cli -a
pointing to an action script.
Place the following script at /usr/local/sbin/hostapd-fdb.sh
and make it
executable (chmod +x /usr/local/sbin/hostapd-fdb.sh
).
#!/usr/bin/env bash
set -euo pipefail
BRIDGE="${BRIDGE:-br0}"
VID="${VID:-}"
LOG_TAG="hostapd-fdb"
IFACE="${1:-}"
EVENT="${2:-}"
log() { logger -t "$LOG_TAG[$IFACE]" -- "$*"; }
add_fdb() {
local mac="$1"
if [[ -n "$VID" ]]; then
bridge fdb add "$mac" dev "$IFACE" master static vlan "$VID" || true
else
bridge fdb add "$mac" dev "$IFACE" master static || true
fi
log "FDB ADD mac=$mac iface=$IFACE bridge=$BRIDGE vlan=${VID:-none}"
}
del_fdb() {
local mac="$1"
if [[ -n "$VID" ]]; then
bridge fdb del "$mac" dev "$IFACE" master vlan "$VID" || true
else
bridge fdb del "$mac" dev "$IFACE" master || true
fi
log "FDB DEL mac=$mac iface=$IFACE bridge=$BRIDGE vlan=${VID:-none}"
}
extract_mac() {
for token in $*; do
if [[ "$token" =~ ^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$ ]]; then
echo "$token"
return 0
fi
done
return 1
}
case "$EVENT" in
AP-STA-CONNECTED*|CTRL-EVENT-EAP-SUCCESS*)
if mac="$(extract_mac "$EVENT")"; then
add_fdb "$mac"
else
log "No MAC found in connect/success event: $EVENT"
fi
;;
AP-STA-DISCONNECTED*|CTRL-EVENT-EAP-FAILURE*|CTRL-EVENT-DISCONNECTED*)
if mac="$(extract_mac "$EVENT")"; then
del_fdb "$mac"
else
log "No MAC found in disconnect/failure event: $EVENT"
fi
;;
*)
;;
esac
exit 0
Run it like:
hostapd_cli -i eth1 -a /usr/local/sbin/hostapd-fdb.sh -B
Control Interface (hostapd_cli)
hostapd_cli is a command-line client that communicates with the hostapd control socket. It can be used to:
-
Query station state and status information.
-
Subscribe to events such as client connection, disconnection, or EAP success/failure.
-
Run in action mode (
hostapd_cli -a <script>
) where it automatically executes a script when events occur.
In the port security setup, hostapd_cli
is primarily used in action mode
together with an event script to add or remove FDB entries dynamically based on
authentication state.