Tuesday, January 8, 2019

Configuring 802.1x authentication using wpa_supplicant on Ubiquiti Edgerouter

This guide describes steps required to configure 802.1x wired authentication using wpa_supplicant on Cavium-based Ubiquiti Edgerouter devices running EdgeOS 2.0. Mediatek (Edgerouter-X) procedure is similar, however I do not have such device and could not recompile wpa_supplicant for it.
Copy EAP-TLS certificates and private key in PEM format to /config/auth/
Run sudo chmod -R 0600 /config/auth to secure the credentials.
Copy wpa_supplicant.conf to /config/
If you are using wpa_supplicant.conf generated by a tool in the previous post, modify certificate and key paths to point to /config/auth/
Assuming wpa_supplicant.conf resides in /config/, the router has Internet connectivity and Internet interface that requires wpa_supplicant is eth0, run the following commands in console:
#Remove 1.x repository, add 2.0 Debian repository and install prerequisites
delete system package repository wheezy
set system package repository stretch components 'main contrib'
set system package repository stretch distribution stretch
set system package repository stretch password ''
set system package repository stretch url 'http://http.us.debian.org/debian'
set system package repository stretch username ''
sudo apt-get update && sudo apt-get install libpcsclite1
#Download backported Debian Buster wpa_supplicant and install it
curl https://community.ubnt.com/ubnt/attachments/ubnt/EdgeMAX/235525/1/wpasupplicant_2.6-21~bpo9+1_mips.deb.tar.gz -o /tmp/wpasupplicant_2.6-21~bpo9+1_mips.deb.tar.gz
cd /tmp/
tar -xvf ./wpasupplicant_2.6-21~bpo9+1_mips.deb.tar.gz
sudo dpkg -i /tmp/wpasupplicant_2.6-21~bpo9+1_mips.deb
#Create symbolic link to wpa_supplicant.conf for eth0
sudo ln -s /config/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant-wired-eth0.conf
#Disable dbus service and enable wired wpa_supplicant for eth0
sudo systemctl disable wpa_supplicant.service
sudo systemctl enable wpa_supplicant-wired@eth0.service
#Save DEB packages for future use, allow /etc/ubnt/ubnt-rcS/ubnt-rcS.sh to install them
sudo mkdir -p /config/data/firstboot/install-packages &&  cd /config/data/firstboot/install-packages
sudo apt-get download libpcsclite1sudo curl https://community.ubnt.com/ubnt/attachments/ubnt/EdgeMAX/235525/1/wpasupplicant_2.6-21~bpo9+1_mips.deb.tar.gz -o /config/data/firstboot/install-packages/wpasupplicant_2.6-21~bpo9+1_mips.deb.tar.gz
sudo tar -xvf ./wpasupplicant_2.6-21~bpo9+1_mips.deb.tar.gz
sudo rm /config/data/firstboot/install-packages/wpasupplicant_2.6-21~bpo9+1_mips.deb.tar.gz
#Recover configuration on EdgeOS upgrade
sudo mkdir -p /config/scripts/firstboot.d/
echo '#!/usr/bin/env bash' | sudo tee -a /config/scripts/firstboot.d/8021x-eth0.sh
echo 'ln -s /config/wpa_supplicant.conf /etc/wpa_supplicant/wpa_supplicant-wired-eth0.conf' | sudo tee -a /config/scripts/firstboot.d/8021x-eth0.sh
echo 'systemctl stop wpa_supplicant.service' | sudo tee -a /config/scripts/firstboot.d/8021x-eth0.sh
echo 'systemctl disable wpa_supplicant.service' | sudo tee -a /config/scripts/firstboot.d/8021x-eth0.sh
echo 'systemctl enable wpa_supplicant-wired@eth0.service' | sudo tee -a /config/scripts/firstboot.d/8021x-eth0.sh
echo 'systemctl start wpa_supplicant-wired@eth0.service' | sudo tee -a /config/scripts/firstboot.d/8021x-eth0.sh
sudo chmod 0744 /config/scripts/firstboot.d/8021x-eth0.sh


  1. Is this also compatible with the e300 / ER4 router?

  2. This worked for me on ER4, latest firmware (2.0).

    1. I gave up on the ER-X and bought an ER4.

      Everything installed great (thanks for the fantastic instructions!) but I still can't get an IP address.

      I have the SFP from AT&T plugged directly into the ER4 (there is no ONT, the NVG595 has an SFP slot).

      Do you know if there is some extra step to make this work?

      Or is this the DHCP issue where it's sent over VLAN 0 and the ER4 can't see it?

    2. Try 802.1q VLAN 2 instead of 802.1p (VLAN 0). Your DHCP interface would be something like 'eth0 vif 2'

    3. Awesome! That worked immediately, thanks!

      `set interfaces ethernet eth3 vif 2 address dhcp`

      (eth3 is the SFP on the ER4)

      All I had to do then was change the NAT rule to masquerade to eth3.2 and it worked.

      Is there anything special I need to do so it remembers this after a fw update or reboot?

    4. Sergey I assume we have to run the command `set interfaces ethernet eth3 vif 0 address dhcp` to get the 802.1p going right?

      These instructions skip over that as well as the mac cloning so that's why I ask.

  3. FYI, the ER-X and ER-X-SFP are MIPSEL. Do you know if there is a WPA_Supplicant package wpasupplicant_2.6-21~bpo9+1 compiled for mipsel?

    I'm assuming the regular 2.6.21 from buster won't work.

  4. Sorry, missed this "... [I] could not recompile wpa_supplicant for it"

    Does the wpa_supplicant on 1.10 have the same race condition problem that 2.0 does without using the Buster backport?

  5. Native wheezy wpa_supplicant works just fine in 1.10, but there is a different problem in 1.x - there is no built in mechanism to start it, unlike systemd in 2.0, so you have to start it from a script in /config/scripts/post-config.d/

    Here is a script I've used for ONT on eth0 with 1.x:

    #!/usr/bin/env bash
    #Start EAP-TLS on eth0
    #Check if already running to avoid multiple instances

    PROCESS_COUNT=$(ps -A | grep $PROCESS_NAME | egrep -v "grep|$(basename $0)" | grep -c $PROCESS_NAME)

    if [ $PROCESS_COUNT = 0 ]; then
    echo "`date +"%b %d %T"` `hostname` eap-tls: Starting" >> /var/log/messages 2>&1
    if [ -x /sbin/wpa_supplicant ]; then
    echo "`date +"%b %d %T"` `hostname` `/sbin/wpa_supplicant -s -B -Dwired -ieth0 -c/config/wpa_supplicant.conf -P/var/run/wpa_supplicant.pid &`" >> /var/log/messages 2>&1
    echo "`date +"%b %d %T"` `hostname` eap-tls: wpa_supplicant is not installed" >> /var/log/messages 2>&1
    echo "`date +"%b %d %T"` `hostname` eap-tls: wpa_supplicant is already running" >> /var/log/messages 2>&1

  6. Here is a script that installs wpa_supplicant on 1.x in correct order across 1.x firmware flashes. You would want to download packages into /config/data/install-packages/

    #!/usr/bin/env bash
    # Installs wpa_supplicant after upgrade
    echo "`date +"%b %d %T"` `hostname` install-deb: Starting" >> /var/log/messages 2>&1
    if /usr/bin/dpkg -s libpcsclite1 | grep -lq "Status: install ok installed"; then echo "`date +"%b %d %T"` `hostname` libpcsclite1 is already installed" >> /var/log/messages 2>&1; else echo "`date +"%b %d %T"` `hostname` `/usr/bin/dpkg --no-force-all -i /config/data/install-packages/libpcsclite1_1.8.4-1+deb7u1_mips.deb`" >> /var/log/messages 2>&1; fi
    if /usr/bin/dpkg -s libreadline5 | grep -lq "Status: install ok installed"; then echo "`date +"%b %d %T"` `hostname` libreadline5 is already installed" >> /var/log/messages 2>&1; else echo "`date +"%b %d %T"` `hostname` `/usr/bin/dpkg --no-force-all -i /config/data/install-packages/libreadline5_5.2+dfsg-2~deb7u1_mips.deb`" >> /var/log/messages 2>&1; fi
    if /usr/bin/dpkg -s libssl1.0.0 | grep -lq "Status: install ok installed"; then echo "`date +"%b %d %T"` `hostname` libssl1.0.0 is already installed" >> /var/log/messages 2>&1; else echo "`date +"%b %d %T"` `hostname` `/usr/bin/dpkg --no-force-all -i /config/data/install-packages/libssl1.0.0_1.0.1e-2+deb7u20_mips.deb`" >> /var/log/messages 2>&1; fi
    if /usr/bin/dpkg -s wpasupplicant | grep -lq "Status: install ok installed"; then echo "`date +"%b %d %T"` `hostname` wpasupplicant is already installed" >> /var/log/messages 2>&1; else echo "`date +"%b %d %T"` `hostname` `/usr/bin/dpkg --no-force-all -i /config/data/install-packages/wpasupplicant_1.0-3+deb7u3_mips.deb`" >> /var/log/messages 2>&1; fi
    echo "`date +"%b %d %T"` `hostname` install-deb: Done" >> /var/log/messages 2>&1

    1. Would you provide URLs for those debs? Having quite some difficulty finding all of them.

  7. I also have four helper scripts that monitor for wpa_supplicant crash (in case the link to ONT is not up when router starts, or connection is interrupted), restart wpa_supplicant and subsequently restart dhcp and dhcpv6 clients and radvd. Let me know if you need them.

    On 2.x I was able to decommission all of the scripts - it runs great with just instructions in the post, gracefully handling connection interruptions and late ONT link.

  8. Buster and Sid packages don't work out of the box on Stretch or Wheezy due to dependency on newer glibc. You would need to recompile them on Stretch box so that it links with older glibc.
    If you would like to backport to MediaTek, use these two guides:
    Use schroot and debootstrap to create a build environment on usb drive or network share, so that you don't have to install extra packages to the router filesystem.
    Once the build environment is up, use this guide to backport the package:

    1. There doesn't seem to be a reasonable way to compile this for the ER-X/ER-X-SFP. There's no USB and I don't have access to network storage.

      Do you know if the newer wpasupplicant for Stretch fixes the issue you described?

      What is the problem with it?

    2. It is missing "wpa_supplicant-wired@.service". You could add the missing file manually from source. See details here: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=871488

  9. Could I use this guide for a Ubiquiti USG-XG, assuming eth0 is connected to the ONT?

    1. You likely could. I don't have a USG-XG to test with, but it is based on the same (but more powerful) Cavium platform, so the instructions should work with minimum changes. I am not following the software development cycle for USG products, but if it is using the same Debian Stretch as EdgeOS counterparts, it should work. If it uses Wheezy, see my comments above for 1.x EdgeOS.

    2. When I SSH into the USG, it says EdgeOS, but I don't think it is totally like what is on the Edgerouters. I'm moving to the house with ATT Fiber at the end of April, so I'll give it a shot then and report back.

      Thanks for this awesome work! It has been such an interesting rabbit hole to explore!

    3. Looks like my USG-XG-8 uses wheezy. Could you please share your helper scripts from 1.x?

    4. I've uploaded the scripts here. It's a quick and dirty hack for 1.x, I have not really spent much time refining them, since I've moved to 2.0 almost right away. The scripts assume that ONT is on eth0 https://mega.nz/#!rr4E2SbS!GBQK9pEcYZdtAd1e0wDgeCh9Sr48qWNFRAO0QI-6nwA

      Set permissions to 755, download the DEBs to /config/data/install-packages and add the following two commands to config:

      set system task-scheduler task eap-tls crontab-spec '* * * * *'
      set system task-scheduler task eap-tls executable path /config/scripts/restart-eap-tls

    5. Thank you for this, it is very appreciated!

  10. Has anyone had any success in utilizing a static block of addresses in addition to the DHCP one that is handed via wpa_supplicant? I can't figure out how the provider is routing the static block back to their network?

    1. I set it up the same way you would on the RG essentially, though strictly speaking, I'm not sure it's necessary. I have the smallest block with IP addressing like so - 99.xx.xx.200/29. I assigned what they would call the "gateway" address from that block to a LAN interface on my router (an ER12) -- 99.xx.xx.206/29, then I have the end devices with static IPs use that as the gateway in their setup. Then I have a DNAT rule in my WAN_IN firewall config that sits above 'allow established/related' but below 'drop invalid state' for each static IP that is in actual use which forwards all protocols to the static address. It will work this way as is, but the static devices will be seen externally as the DHCP WAN address so to fix that I added an SNAT exclude rule for the entire block in the NAT section which masquerades to the WAN VLAN. Not sure if this is the 'right way' exactly but it has been working just fine for me. Clear as mud? lol. Hope that helps some.

  11. Has anyone gotten this to run on a usg pro4?

    1. Nevermind got it working by looking through comments

  12. Created symlink /etc/systemd/system/dbus-fi.w1.wpa_supplicant1.service -> /lib/s ystemd/system/wpa_supplicant.service.
    Created symlink /etc/systemd/system/multi-user.target.wants/wpa_supplicant.servi ce -> /lib/systemd/system/wpa_supplicant.service.
    Job for wpa_supplicant.service failed because a fatal signal was delivered to th e control process.
    See "systemctl status wpa_supplicant.service" and "journalctl -xe" for details.
    wpa_supplicant.service couldn't start.

    Get that when I set up wpa_supplicant on an edgerouter lite running edgeos 2.0.1. What am i missing here?

  13. I have the regular USG. Will this work?

  14. While I've been having authentication issues with this on my USG3, that doesn't appear to be an issue on my ER4. Although it seems authentication is successful, I'm not getting an IP address.

    ubnt@ubnt:~$ sudo journalctl -u wpa_supplicant-wired@eth0.service -b
    -- Logs begin at Thu 2016-11-03 17:16:43 UTC, end at Fri 2019-04-12 12:40:30 UTC. --
    Nov 03 17:16:46 ubnt systemd[1]: Started WPA supplicant daemon (interface- and wired driver-specific version).
    Apr 12 12:37:00 ubnt wpa_supplicant[274]: Successfully initialized wpa_supplicant
    Apr 12 12:37:01 ubnt wpa_supplicant[274]: eth0: Associated with xx:xx:xx:xx:xx:xx
    Apr 12 12:37:01 ubnt wpa_supplicant[274]: WMM AC: Missing IEs
    Apr 12 12:37:01 ubnt wpa_supplicant[274]: eth0: CTRL-EVENT-SUBNET-STATUS-UPDATE status=0
    Apr 12 12:37:33 ubnt wpa_supplicant[274]: eth0: CTRL-EVENT-EAP-SUCCESS EAP authentication completed successfully
    Apr 12 12:37:33 ubnt wpa_supplicant[274]: eth0: CTRL-EVENT-CONNECTED - Connection to xx:xx:xx:xx:xx:xx completed [id=0 id_str=]

    I've ensured that eth0.0 is spoofing the mac address specified in wpa_supplicant.conf:

    ubnt@ubnt# show interfaces ethernet eth0
    duplex auto
    speed auto
    vif 0 {
    address dhcp
    description Internet
    firewall {
    in {
    ipv6-name WANv6_IN
    name WAN_IN
    local {
    ipv6-name WANv6_LOCAL
    name WAN_LOCAL
    mac yy:yy:yy:yy:yy:yy

    Is there perhaps another step I may have missed?

    1. I had to spoof the mac both on eth0 and eth0.0 I am not sure if others are also doing this in there config. I'm a noob and was not able to pull the IP either until I had both vlan and eth0 set the same mac #.

    2. what were the steps that you did to get it working if you don't mind.

  15. THANK YOU SO MUCH! Got it working on my ER-4 and my god finally getting fiber speeds! I did not realize how much of a freaking rabbit hole this was going to turn into. I had the BGW210 gateway but I could never get my upload to get above 400 mbps but at&t web test showed I was getting 1gig to my gateway.

    Tried the eap_proxy improved speeds by roughly 100 for both upload and download just not enough. USG wasn't able to do it for me and had to switch to er-4 and now I am finally getting my full speed!

    Thank you for making the work public and accessible! I'd send you some beer/intoxicant funds.

  16. Wow. I am definitely going share this with a few of my friends. Very cool information.
    24 hour locksmith

  17. If anyone has steps for getting this to work on USG, I would appreciate this. I'm trying to piece together the comments and other details I am finding scattered around.

    I've got the certificates and my wpa_supplicant.conf file. So I'm getting close! (^_^)


Configuring 802.1x authentication using wpa_supplicant on Ubiquiti Edgerouter

This guide describes steps required to configure 802.1x wired authentication using wpa_supplicant on Cavium-based Ubiquiti Edgerouter devic...