Setup 802.1X Authentication on Arch Linux

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. To make matters more interesting, the machine in question has two onboard NICs, a Realtek r8169 and an Intel e1000e, and each ended up causing a different kind of trouble: the former during authentication, the latter during DHCP. 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 your 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. 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' ...
...
eno1: CTRL-EVENT-EAP-STARTED EAP authentication started
...
eno1: CTRL-EVENT-EAP-SUCCESS EAP authentication completed successfully
eno1: CTRL-EVENT-CONNECTED - Connection to 01:80:c2:00:00:03 completed [id=0 id_str=]
EAPOL: Supplicant port status: Authorized
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

No matter what I tried, the e1000e would not obtain a lease from the NTU DHCP server, even though it worked fine behind a TP-Link router, so the NIC itself was healthy. After exhausting my patience, I gave up debugging it and simply swapped in a different NIC, which picked up an IP address from the NTU DHCP server right away.

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. Note that netplan ships with Ubuntu but isn’t part of a default Arch install, so you’ll need to install it (e.g. from the AUR) first.

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.

Afterthoughts

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.