Over the past few days, I attempted to set up 802.1X authentication on Arch Linux, a wired identity authentication protocol widely used in enterprise environments and well-supported on Windows and Ubuntu. However, when it came to Arch Linux, a series of strange issues emerged. This post will detail the problems I encountered and the debugging process.

WPA-Supplicant for 802.1X Authentication

On Arch Linux, 802.1X authentication is handled by wpa_supplicant. To begin, you need to test our protocol configuration and user credentials by manually running wpa_supplicant. If you haven’t installed it yet, use the following command:

pacman -S wpa_supplicant

After installing, you can create a configuration file at /etc/wpa_supplicant.conf with the following content:

ctrl_interface=/run/wpa_supplicant

network={
  key_mgmt=IEEE8021X
  eap=PEAP
  identity="your-username"
  password="your-password"
}

For more options, please refer to [1] and [2] in the references. Next, test the configuration using the following command:

wpa_supplicant -ddd -i eno1 -D wired -c /etc/wpa_supplicant.conf

If you’re extremely lucky, you’ll see output like this:

wpa_supplicant v2.11-hostap_2_11+
Successfully initialized wpa_supplicant
Initializing interface 'eno1' conf '/etc/wpa_supplicant.conf' driver 'wired' ctrl_interface 'N/A' bridge 'N/A'
Configuration file '/etc/wpa_supplicant.conf' -> '/etc/wpa_supplicant.conf'
...
eno1: Cancelling scan request
eno1: CTRL-EVENT-SUBNET-STATUS-UPDATE status=0
EAPOL: startWhen --> 0
EAPOL: SUPP_PAE entering state CONNECTING
EAPOL: txStart
TX EAPOL: dst=01:80:c2:00:00:03
EAPOL: startWhen --> 0
l2_packet_receive: src=00:78:88:8e:1f:08 len=46
eno1: RX EAPOL from 00:78:88:8e:1f:08
EAPOL: Received EAP-Packet frame
EAPOL: SUPP_PAE entering state RESTART
EAP: EAP entering state INITIALIZE
EAP: EAP entering state IDLE
EAPOL: SUPP_PAE entering state AUTHENTICATING
EAPOL: SUPP_BE entering state REQUEST
EAPOL: getSuppRsp
EAP: EAP entering state RECEIVED
EAP: Received EAP-Request id=1 method=1 vendor=0 vendorMethod=0
EAP: EAP entering state IDENTITY
eno1: CTRL-EVENT-EAP-STARTED EAP authentication started
EAP: Status notification: started (param=)
EAP: EAP-Request Identity data - hexdump_ascii(len=0):
EAP: using real identity - hexdump_ascii(len=20):
...
eno1: CTRL-EVENT-EAP-SUCCESS EAP authentication completed successfully
EAPOL: IEEE 802.1X for plaintext connection; no EAPOL-Key frames required
eno1: WPA: EAPOL processing complete
eno1: Cancelling authentication timeout
eno1: State: ASSOCIATED -> COMPLETED
eno1: CTRL-EVENT-CONNECTED - Connection to 01:80:c2:00:00:03 completed [id=0 id_str=]
EAPOL: SUPP_PAE entering state AUTHENTICATED
EAPOL: Supplicant port status: Authorized
EAPOL: SUPP_BE entering state RECEIVE
EAPOL: SUPP_BE entering state SUCCESS
EAPOL: SUPP_BE entering state IDLE
EAPOL authentication completed - result=SUCCESS

Troubleshooting

Unfortunately, I wasn’t so lucky and encountered the following log. It would hang for a long time at EAPOL: startWhen --> 0, eventually followed by the message EAP authentication failed.

(The above messages are exactly the same)
...
EAPOL: txStart
TX EAPOL: dst=01:80:c2:00:00:03
EAPOL: startWhen --> 0 
EAPOL: SUPP_PAE entering state CONNECTING
EAPOL: txStart
TX EAPOL: dst=01:80:c2:00:00:03
(>>>>>>> Several minutes waiting <<<<<<<)
EAPOL: idleWhile --> 0
EAP: EAP entering state FAILURE
eno1: CTRL-EVENT-EAP-FAILURE EAP authentication failed

At first, I suspected there was an issue with the wpa_supplicant configuration. However, I discovered that the same configuration file worked perfectly on Ubuntu. So, I began debugging (a.k.a. consulting ChatGPT) and, with the help of [3], identified a compatibility issue between the Realtek EIC (Ethernet Interface Controller) R8169 and the latest Linux kernel.

You can use ethtool -i eno1 to check your NIC model. The output is shown below. If the driver is identified as r8169, you might encounter the same issue I did.

driver: r8169
version: 6.11.7-arch1-1
firmware-version:
expansion-rom-version:
bus-info: 0000:02:00.0
supports-statistics: yes
supports-test: no
supports-eeprom-access: no
supports-register-dump: yes
supports-priv-flags: no

The solution is to downgrade the Linux kernel by installing linux-lts. If you’re using the nvidia driver, you also need to replace it with nvidia-lts.

pacman -S linux-lts nvidia-lts
pacman -R linux nvidia
mkinitcpio -c /etc/mkinitcpio.conf -g /boot/initramfs-linux-lts.img -k `ls /lib/modules`
grub-mkconfig > /boot/grub/grub.cfg

ChatGPT also suggested replacing the NIC driver with the following commands:

pacman -S r8168-lts  
modprobe -r r8169  
modprobe r8168  

However, this solution didn’t work for me. Downgrading to the Linux-LTS kernel was the only solution that worked.

Request for IP Address

Once wpa_supplicant successfully authenticates, you can use dhcpcd to request an IP address from the DHCP server with the following command:

dhcpcd eno1

If everything goes well, you should see output like this:

dhcpcd-10.1.0 starting
DUID 00:01:00:01:2e:c6:d1:31:a8:a1:59:11:d5:db
eno1: IAID 59:11:d5:db
eno1: soliciting an IPv6 router
eno1: soliciting a DHCP lease
eno1: offered 10.88.74.210 from 155.69.3.7
eno1: probing address 10.88.74.210/21
eno1: leased 10.88.74.210 for 86400 seconds
eno1: adding route to 10.88.72.0/21
eno1: adding default route via 10.88.79.254
Dropped protocol specifier '.dhcp' from 'eno1.dhcp'. Using 'eno1' (ifindex=2).

However, unlucky me encountered the following output instead:

eno1: IAID 59:11:d5:dd
eno1: soliciting a DHCP lease
eno1: soliciting an IPv6 router
eno1: no IPv6 Routers available
timed out
dhcpcd exited

In my case, the issue was caused by the Intel e1000e NIC failing to receive a response from the DHCP server. While it could receive a DHCP offer from a TP-Link router, it was unable to obtain a DHCP offer from the NTU DHCP server. Here’s the output of ethtool -i eno1.

driver: e1000e
version: 6.6.61-1-lts
firmware-version: 0.5-4
expansion-rom-version: 
bus-info: 0000:00:1f.6
supports-statistics: yes
supports-test: yes
supports-eeprom-access: yes
supports-register-dump: yes
supports-priv-flags: yes

Automatic Authentication

The procedure above can be automated with the following bash script, which handles authentication and IP address request automatically.

IP_ADDR=$(ip addr show eno1 | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1)

# At NTU, unauthorized devices are assigned an IP address beginning with 10.100.
if [[ $IP_ADDR =~ ^10\.100\.[0-9]+\.[0-9]+$ ]]; then
    echo "Current IP Addr: ${IP_ADDR}"
    killall wpa_supplicant dhcpcd
    ip link set eno1 down
    ifconfig eno1 0.0.0.0
    wpa_supplicant -B -i eno1 -D wired -c /etc/wpa_supplicant.conf
    sleep 5
    dhcpcd eno1
fi

Alternatively, the above process can be handled by netplan using the following configuration located at /etc/netplan/config.yaml.

network:
  version: 2
  renderer: NetworkManager
  ethernets:
    eno1:
      dhcp4: true
      auth:
        key-management: "802.1x"
        method: "peap"
        identity: "your-username"
        password: "your-password"
      dhcp4-overrides:
        use-routes: true

Run netplan apply to apply this configuration.

Conclusion

  • Use wpa_supplicant for 802.1X authentication.
  • If authentication or DHCP fails, check the compatibility of your NIC with the Linux kernel.
  • Use netplan to automate 802.1X authentication.

On a side note, I noticed that traffic on StackOverflow has significantly dropped since the launch of ChatGPT [4]. It seems that defeating StackOverflow doesn’t mean creating the next StackOverflow. ChatGPT has certainly improved the speed of information retrieval. I was stuck for a long time with wpa_supplicant, but ChatGPT suggested that the issue might be with the NIC driver, which ultimately helped me resolve the problem.

References

The Disqus comment system is loading ...
If the message does not appear, please check your Disqus configuration.