Cryptsus Blog rss-feed  |  We craft cyber security solutions.

OpenWrt Wireless Access Point Bridge
with 802.1X PEAP

By: Jeroen van Kessel  |  June 26th, 2019 | 10 min read

Throughout the years it has been known that many SOHO wireless routers are prone to security vulnerabilities. Many stock router firmware are consistently plagued by exploits due to bad quality control and are no longer being updated after the routers reach their end-of-life (EOL). Alternative router firmware such as DD-WRT and OpenWrt are typically more secure. We picked OpenWrt for this project since DD-WRT is updated less frequently than OpenWrt plus OpenWrt is more mainline in terms of its Linux kernel.

This blog post will eleborate on how you can leverage your wireless router to connect to any wireless access point into your home network. We will use a TP-Link TL-WR841ND v7.1 and a Yagi RP-SMA 2.4 GHz High Gain 16 DBi antenna. Note that the D in TP-Link TL-WR841ND standsfor Detachable antenna(s). You are only able to attach external high gain directional antennas to the D-models.

Technical overview

Clients can connect over RJ45 or WPA2 to the bridged TP-link OpenWrt router. The OpenWrt router authenticates with 802.1X to an open AP such as eduroam or Ziggo HotSpots. NAT will occur on the OpenWrt router. The eduroam or Ziggo 8021.X authenticator server will eventually verify and approve or deny authentication based on username, password and certificate. Figure 1 shows this process:

8021x-radius-authentication
Figure 1: OpenWrt 802.1X authentication overview

Flashing the firmware

Lets download the latest version of OpenWrt so we can replace the stock firmware on the router. I downloaded the firmware binary via the latest official OpenWRT repository which is sorted by chipset platform. The TP-Link WR841ND relies on the Atheros AR7241 chipset. Pick the tiny verion of OpenWrt due to its 4MB flash size memory limitations.

When logged in on the 192.168.1.1 web-interface of the stock firmware, upload the openwrt-18.06.2-ar71xx-tiny-tl-wr841-v7-squashfs-factory.bin file to the router. It will reboot after flashing and OpenWrt should be installed and accessable on the same IP-adres.

We login as root without a password. Change your password because you do not want others to login unauthorized.

Certificates rely on the correct time/ date information to prevent clock related errors. Set the time to the correct local timezone: System -> System -> Timezone

OpenWrt supports WEP, WPA and WPA2 but not 802.1X authentication out-of-the-box. Therefore we will install the 802.1X supplicant, which is the client side authenticator package. We first need to remove the wpad-mini package before installing the 802.1X supplicant. Go to: System -> Software -> Installed packages: wpad-mini -> Remove.

Next go to System -> Software -> Update packages -> Filter: 802.1X -> Find pacakage -> wpa-supplicant -> Install -> Ok:

wpa-supplicant-mini	2018-05-21-62566bc2-5	163091	WPA Supplicant (minimal version)

Because of limited memory space on the router we get the following error which withholds us from installing the package:

 * verify_pkg_installable: Only have 76kb available on filesystem /overlay, pkg wpa-supplicant-mini needs 159
 * opkg_install_cmd: Cannot install package wpa-supplicant-mini.

Because the router has only 4MB flash size available, we need to remove packages which are not necessary for this 802.1X bridged setup. Unfortunately removing packages from the web-portal or by CLI does not do the job. We need to recompile the firmware binary from source with a minimal set of packages.

I am using the latest version of Ubuntu 18.04 LTS for this project. You can use VirtualBox to spawn a box if you are not running a Linux distro on your bare-metal.

$ lsb_release -d
Description:	Ubuntu 18.04.2 LTS

We download the tiny version of the OpenWrt Imagebuilder of ar71xx chipsets. Download the compressed Imagebuilder binaries:

$ wget http://downloads.openwrt.org/releases/18.06.2/targets/ar71xx/tiny/openwrt-imagebuilder-18.06.2-ar71xx-tiny.Linux-x86_64.tar.xz

Verify the hash for integrity and CRC reasons:

$ echo "ed0d6d4ea6c1147c8145fd33a4225ad60c1165a67c09ab7d7dba2346caaa4076" openwrt-imagebuilder-18.06.2-ar71xx-tiny.Linux-x86_64.tar.xz |
sha256sum -c -
openwrt-imagebuilder-18.06.2-ar71xx-tiny.Linux-x86_64.tar.xz: OK

Extract the imagebuilder tar:

$ tar -xvf openwrt-imagebuilder-18.06.2-ar71xx-tiny.Linux-x86_64.tar.xz
$ cd openwrt-imagebuilder-18.06.1-ar71xx-generic.Linux-x86_64

lets see how we compile this firmware:

$ make info
Current Target: "ar71xx (Devices with small flash)"
Default Packages: base-files libc libgcc busybox dropbear mtd uci opkg netifd fstools uclient-fetch logd kmod-gpio-button-hotplug
swconfig kmod-ath9k wpad-mini uboot-envtoolsdnsmasq iptables ip6tables ppp ppp-mod-pppoe firewall odhcpd-ipv6only odhcp6c

...
tl-wr841-v1.5:
    TP-LINK TL-WR841N/ND v1.5
    Packages:
tl-wr841-v10:
    TP-LINK TL-WR841N/ND v10
    Packages:
tl-wr841-v11:
    TP-LINK TL-WR841N/ND v11
    Packages:
tl-wr841-v12:
    TP-LINK TL-WR841N/ND v12
    Packages:
tl-wr841-v3:
    TP-LINK TL-WR841N/ND v3
    Packages:
tl-wr841-v5:
    TP-LINK TL-WR841N/ND v5
    Packages:
tl-wr841-v7:
    TP-LINK TL-WR841N/ND v7
    Packages:
tl-wr841-v8:
    TP-LINK TL-WR841N/ND v8
    Packages:
tl-wr841-v9:
    TP-LINK TL-WR841N/ND v9
    Packages:
...

Lets build the firmware with the luci web-interface, wpad package which is the 802.1X client supplicant package, but without the wpad-mini package:

$ make image PROFILE=tl-wr841-v7 PACKAGES="luci wpad -wpad-mini"

...
[mktplinkfw] *** error: images are too big by 9060 bytes
cp: cannot stat '/home/krabelize/Desktop/openwrt-imagebuilder-18.06.2-ar71xx-tiny.Linux-x86_64/build_dir/target-mips_24kc_musl/
linux-ar71xx_tiny/tmp/openwrt-18.06.2-ar71xx-tiny-tl-wr841-v7-squashfs-factory.bin': No such file or directory
...

The firmware binary will still be 9060 bytes too big for the 4MiB router. Therefore we get rid of more unnecessary pacakges:

$ make image PROFILE=tl-wr841-v7 PACKAGES="luci wpad -wpad-mini -ppp -ppp-mod-pppoe -kmod-ppp -kmod-pppoe -kmod-pppox -kmod-ipv6 -6relayd
 -ip6tables -odhcp6c -odhcpd-ipv6only"

2292370 bytes (2.3 MB, 2.2 MiB) copied, 0.0234007 s, 98.0 MB/s
[mktplinkfw] rootfs offset aligned to 0x1365064
[mktplinkfw] firmware file "/home/krabelize/Desktop/openwrt-imagebuilder-18.06.2-ar71xx-tiny.Linux-x86_64/build_dir/target-mips_24kc_musl/
linux-ar71xx_tiny/tmp/openwrt-18.06.2-ar71xx-tiny-tl-wr841-v7-squashfs-sysupgrade.bin.new" completed
4477+1 records in
4477+1 records out
2292370 bytes (2.3 MB, 2.2 MiB) copied, 0.0284081 s, 80.7 MB/s
[mktplinkfw] rootfs offset aligned to 0x1365064
[mktplinkfw] firmware file "/home/krabelize/Desktop/openwrt-imagebuilder-18.06.2-ar71xx-tiny.Linux-x86_64/build_dir/target-mips_24kc_musl/
linux-ar71xx_tiny/tmp/openwrt-18.06.2-ar71xx-tiny-tl-wr841-v7-squashfs-factory.bin.new" completed
padding image to 00230000
padding image to 00230000
padding image to 00240000
18+1 records in
19+0 records out
2490368 bytes (2.5 MB, 2.4 MiB) copied, 0.00946213 s, 263 MB/s

Our firmware binary got created with a size of 3840KB :)

$ ls -lsa build_dir/target-mips_24kc_musl/linux-ar71xx_tiny/tmp/openwrt-18.06.2-ar71xx-tiny-tl-wr841-v7-squashfs-factory.bin
3840 -rw-r--r-- 1 root root 3932160 jun 22 20:48 build_dir/target-mips_24kc_musl/linux-ar71xx_tiny/tmp/
openwrt-18.06.2-ar71xx-tiny-tl-wr841-v7-squashfs-factory.bin

Let's copy this binary to the router:

$ scp build_dir/target-mips_24kc_musl/linux-ar71xx_tiny/tmp/openwrt-18.06.2-ar71xx-tiny-tl-wr841-v7-squashfs-factory.bin
root@192.168.1.1:/tmp

Next up is flashing the firmware:

$ ssh root@192.168.1.1
$ cd /tmp && mtd -r write openwrt-18.06.2-ar71xx-tiny-tl-wr841-v7-squashfs-factory.bin firmware

Configuring 802.1X authentication

We will choose Ziggo Hotspots for 802.1X authentication. Ziggo HotSpots requires the installation of a ca.pem. The Eduroam network does not require certificate based authentication anymore.

wget https://www.ziggo.nl/content/dam/www.ziggo.nl/tools/WifiSpots%20certificaten/WifiSpots%20certificaat%20Windows%20Phone%20Ziggo.pem
mv 'WifiSpots certificaat Windows Phone Ziggo.pem' ca.pam

$ cat ca.pam
-----BEGIN CERTIFICATE-----
MIIFZTCCA02gAwIBAgIQMRRC4yx40plHb1I51cU4BDANBgkqhkiG9w0BAQsFADBF
MRMwEQYDVQQKEwpaaWdnbyBCLlYuMQswCQYDVQQGEwJOTDEhMB8GA1UEAxMYWmln
Z28gUHVibGljIFJvb3RDQSAtIEcxMB4XDTE0MDYyNjEyMzYxOFoXDTM0MDYyNjEy
MzYxOFowRTETMBEGA1UEChMKWmlnZ28gQi5WLjELMAkGA1UEBhMCTkwxITAfBgNV
BAMTGFppZ2dvIFB1YmxpYyBSb290Q0EgLSBHMTCCAiIwDQYJKoZIhvcNAQEBBQAD
ggIPADCCAgoCggIBAL7u99oSjtFHKcjs3NFNiojGDyjcTIYmowMkKPFRWD+QjBA8
t1Gkddc0CpsEvbdzLY6oArJYmmMTayMXeOp1wdXfGKBgvnWieehNH39vzBlQjby0
9U/iKm0O2pMzwK6XocpOh6Dy3vxnyv/XdTkuL6WU2KuhYLOZ8VWX8AmbUN5hKnEr
6bwAsTvj6afOloMFPxynFHdiKYr3E75rGUC5K3u+H7dbJyWbbCUmaBT/GAkMPhj6
2uPicWIxfNVI3ER1cKwvfMUULYNuJ6g2GNEs1yImrZ6ktVAMMogF1dGHomR/kuAA
z73H09pCx4IxzxRCWCKEfQydkRwPz+4M3aIRG71OW1DhZM4pS8uyrmKzBZDDhDwS
IB/2aGA0hphUf3+3MJNntqjdCWd0LOkRdbcDj2rNSlA2pE3+XbYrKGl8f6q/5RVf
UmQhgkBex8whRCBg8OroCvKM5AC5hSz+IkXPGcg9quMd97YOaUdX8MqBJutVMhMq
Xemhh/3CzDMFnrLRk3uEMf6kDPPO+7UKxbl7dhh/I9Ym9lmuq3NM6EK0rdMXoy49
ALyE+qvyhCvjchVyX1DgA/l4Flx4Vxlopo+m6hC1XKtI437bc97+8MxM/cKcTMe5
qyq5akhVpqRTmnDNDEdaZ74ZUYLbamKCsjuKSrON8jQcn3bQBX9D2JgBaFhHAgMB
AAGjUTBPMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBT/
e2d1lo6L4HHujKQ4wNmm5H1AaTAQBgkrBgEEAYI3FQEEAwIBADANBgkqhkiG9w0B
AQsFAAOCAgEANwRp4Q4tFtb2Z3hRnWnj21eEbigt3UmsEbCXFD+SdJMpF+DTK8wa
Ikken2Ws3WfsxJLUSgAlsk7k/4TEpWLfXLvAc0/BgLQKjtnJ3517Pb7AyQnLJTX/
njJ+uAO7gRurR3Fmwp+EQ0jMhhSfjXHcfTNKEhH7nH2ghDV3dKxE4Gs2ETfkaQQH
7H9IOCLjUGWz1cLYgmvJECN1wFwCZP3wIlxWW5x4/uctw/7kdeMp239tkB6UNDvE
5PXsUVKaG94BPYZV0dWREGsZrtKb4qrfMmraz7yCZWhDC/BzfSomNKuRqqyCOZv4
jfatvGvP4EexCVfIn0+QetTUmu0zNOV9FzbPxglYUqdat4tCOh8MYTi8KVBbwibX
TT9ifimTx0rses20pq0ixHPWPj8M97FDhMRGCM7SYCrXGScrPPlQEIKLsVMUC5ns
RUp/BLMVIQ0yDElOULefbP9vSNugKnethslNWi4vKc0OokhLrad7ymq3RyVrge1a
dIghxTv+eoKnBFYgenafPNEvurr+jHLquTiP4nqEmQxWbXL3Nzeve6mABm13owHN
09r0QvCKsI1paz0iBjzfIy7qrTZeD1Q4zPTN0dR93ENugauWgL5B8L8+UfED7W0H
r3SUD6YaIGzrDf8Qv02XcHQX5Bt3e+UbmYR1IR0QSsERn8DA4kEMXvA=
-----END CERTIFICATE-----

Let's configure 802.1X via the webinterface. Go to 192.168.1.1 and login.

Go to: Network -> Wireless -> radio0 -> Scan -> 84% Ziggo -> Join network -> Submit

Now that we associated radio0 with the SSID of the public Hotspot of Ziggo, lets configure the 802.1X authentication: Wireless security:

Encryption: WPA2-EAP
Cipher: Force CCMP (AES)
EAP-Method: PEAP
CA-certificate: ca.pem
Authentication: EAP-MSCHAPv2
Identity: [Ziggo username]
Anonymous Identity: [empty]
Password [Ziggo password]

For the eduroam network:

Encryption: WPA-EAP
Cipher: CCMP TKIP
EAP-Method: PEAP
CA-certificate: [none]
Authentication: EAP-MSCHAPv2
Identity: [eduroam username]
Anonymous Identity: [empty]
Password [eduroam password]

Save and Apply

Let's see if we can route traffic over the Ziggo public hotspot gateway:

C:\Users\PC>ping cryptsus.com

Pinging cryptsus.com [95.179.150.8] with 32 bytes of data:
Reply from 95.179.150.8: bytes=32 time=19ms TTL=245
Reply from 95.179.150.8: bytes=32 time=19ms TTL=245
Reply from 95.179.150.8: bytes=32 time=21ms TTL=245
Reply from 95.179.150.8: bytes=32 time=24ms TTL=245

Ping statistics for 95.179.150.8:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 19ms, Maximum = 24ms, Average = 20ms

logread shows the DHCP handshake between the WPA2 802.1X supplicant and the 802.1X authentication server:

$ logread
...
Mon Jun 24 19:30:34 2019 daemon.notice netifd: wwan (1467): udhcpc: sending discover
Mon Jun 24 19:30:34 2019 daemon.notice netifd: wwan (1467): udhcpc: sending select for [wan routable IP]
Mon Jun 24 19:30:34 2019 daemon.notice netifd: wwan (1467): udhcpc: lease of [wan routable IP] obtained, lease time 7200
Mon Jun 24 19:30:34 2019 daemon.notice netifd: Interface 'wwan' is now up
Mon Jun 24 19:30:34 2019 daemon.info dnsmasq[1335]: reading /tmp/resolv.conf.auto
Mon Jun 24 19:30:34 2019 daemon.info dnsmasq[1335]: using local addresses only for domain test
Mon Jun 24 19:30:34 2019 daemon.info dnsmasq[1335]: using local addresses only for domain onion
Mon Jun 24 19:30:34 2019 daemon.info dnsmasq[1335]: using local addresses only for domain localhost
Mon Jun 24 19:30:34 2019 daemon.info dnsmasq[1335]: using local addresses only for domain local
Mon Jun 24 19:30:34 2019 daemon.info dnsmasq[1335]: using local addresses only for domain invalid
Mon Jun 24 19:30:34 2019 daemon.info dnsmasq[1335]: using local addresses only for domain bind
Mon Jun 24 19:30:34 2019 daemon.info dnsmasq[1335]: using local addresses only for domain lan
Mon Jun 24 19:30:34 2019 daemon.info dnsmasq[1335]: using nameserver [ip_dns1]#53
Mon Jun 24 19:30:34 2019 daemon.info dnsmasq[1335]: using nameserver [ip_dns2]#53
...

Your OpenWrt config should look something like this for Ziggo HotSpots:

$ vi /etc/config/wireless
config wifi-device 'radio0'
        option type 'mac80211'
        option hwmode '11g'
        option path 'pci0000:00/0000:00:00.0'
        option htmode 'HT20'
        option channel '1'
        option country 'US'
        option legacy_rates '1'
        option disabled '0'

config wifi-iface 'default_radio0'
        option device 'radio0'
        option network 'lan'
        option mode 'ap'
        option ssid 'FBI Surveillance Van'
        option encryption 'psk2'
        option key 'P@ssw0rd'

config wifi-iface
        option network 'wwan'
        option ssid 'Ziggo'
        option device 'radio0'
        option mode 'sta'
        option bssid 'DE:AD:BE:EF:01:01'
        option encryption 'wpa2+ccmp'
        option eap_type 'peap'
        option ca_cert '/etc/luci-uploads/cbid.wireless.cfg033579.ca_cert'
        option auth 'EAP-MSCHAPV2'
        option identity 'y0urID_h3r3'
        option password 'p@ssw0rd'
        option disabled '0'

Don't forget to set a strong root passphrase and configure SSH public key authentication. Furthermore, The SSID of the bridged AP is unprotected. Set a strong WPA2-PSK passphrase on radio1.

Dynamic MAC address

This script changes the MAC address on OpenWrt on any specified (v)NIC interface. Change the OUI of the MAC address to a legitmate NIC vendor for RFC and IEEE compliancy. The 802.1X authentication server might have a validator in place to check spoofed MAC addresses against the above IEEE database. We are not responsible for any legal violations. Check with your ISP if changing your MAC address on a dynamic basis is allowed.

Discussion and questions