Private PSK (PPSK) function on hostapd
File or RADIUS
FILE - Quick and dirty PPSK on OpenWrt
config wifi-iface 'two'
option ifname 'two0'
option disabled '0'
option encryption 'psk2'
option isolate '0'
option key '12345678'
option mode 'ap'
option network 'lan'
option device 'radio0'
option hidden '0'
option ssid 'RADIUSdesk'
config wifi-iface 'two'
option ifname 'two0'
option disabled '0'
option encryption 'psk2'
option isolate '0'
#option key '12345678'
option wpa_psk_file /etc/psk.list
option mode 'ap'
option network 'lan'
option device 'radio0'
option hidden '0'
option ssid 'RADIUSdesk'
# Special MAC address 00:00:00:00:00:00 can be used to configure PSKs that
# anyone can use.
00:00:00:00:00:00 highwaystar
00:00:00:00:00:00 blacknight
00:00:00:00:00:00 smokeonthewater
00:00:00:00:00:00 picturesofhome
00:00:00:00:00:00 childintime
wifi down
wifi up
FILE - Advanced PPSK on OpenWrt
The first section dealt with a very simple PPSK implementation.
This section is about more advanced options, including mapping MAC and VLAN to specific keys.
You can also visit
this forum discussion where most of the information comes from.
Key specific for MAC
# List of WPA PSKs. Each line, except for empty lines and lines starting
# with #, must contain a MAC address and PSK separated with a space.
# Special MAC address 00:00:00:00:00:00 can be used to configure PSKs that
# anyone can use. PSK can be configured as an ASCII passphrase of 8..63
# characters or as a 256-bit hex PSK (64 hex digits).
00:11:22:33:44:55 paperplane
The alternative 256-bit hex value is a hash that contains the specific SSID to which a user connects.
-
When you specify a specific MAC address for a specific device, you should keep the following in mind.
The MAC address is the MAC address of the WiFi radio that is trying to connect to the SSID and NOT the MAC address of the Ethernet interface of e.g. a laptop.
If your phone has WiFi that supports both 2.4G and 5G, the device will usually have a radio for each frequency band and then also a MAC address for each radio.
Also remember that there is a recent MAC randomisation feature on Android and Apple phones which can also cause the MAC address to change.
Key specific for VLAN
# An optional VLAN ID can be specified by prefixing the line with
# vlanid=<VLAN ID>.
vlanid=3 00:00:00:00:00:00 blueforyou
vlanid=4 00:00:00:00:00:00 piledriver
A few additional steps are required for the VLAN tagging function of hostapd to work as intended.
We need to include a few options to instruct hostapd how to handle the VLANs.
Refer to this snippet from /etc/config/wireless
option wpa_psk_file '/etc/hostapd.wpa_psk'
option vlan_file '/etc/hostapd.vlan'
option vlan_tagged_interface 'eth0'
option vlan_bridge 'br-vlan'
option dynamic_vlan '1'
# VLAN ID to network interface mapping
1 vlan1
2 vlan2
3 vlan3
4 vlan4
100 guest
# Optional wildcard entry matching all VLAN IDs. The first # in the interface
# name will be replaced with the VLAN ID. The network interfaces are created
# (and removed) dynamically based on the use.
* vlan#
root@OpenWrt:~# brctl show
bridge name bridge id STP enabled interfaces
br-vlan3 8000.4018b1eb3c80 no vlan3
eth0.3
br-lan 7fff.4018b1eb3c80 no eth0
RADIUS - PPSK on OpenWrt
# Optionally, WPA passphrase can be received from RADIUS authentication server
# This requires macaddr_acl to be set to 2 (RADIUS) for wpa_psk_radius values
# 1 and 2.
# 0 = disabled (default)
# 1 = optional; use default passphrase/psk if RADIUS server does not include
# Tunnel-Password
# 2 = required; reject authentication if RADIUS server does not include
# Tunnel-Password
# 3 = ask RADIUS server during 4-way handshake if there is no locally
# configured PSK/passphrase for the STA
#
# The Tunnel-Password attribute in Access-Accept can contain either the
# 8..63 character ASCII passphrase or a 64 hex character encoding of the PSK.
#
#wpa_psk_radius=0
Option 3 was recently added and this option is a great help.
OpenWrt generates the hostapd configuration files using the /lib/netifd/hostapd.sh script.
This script in turn reads and interprets the /etc/config/wireless file to obtain the information needed to formulate the hostapd configuration files.
The hostapd.sh script currently sets the wpa_psk_radius value to 2 if the ppsk '1' option is set in /etc/config/wireless.
A better option would be to set it to 3.
We can search for this section in hostapd.sh
if [ "$auth_type" = "psk" ] && [ "$ppsk" -ne 0 ] ; then
json_get_vars auth_secret auth_port
set_default auth_port 1812
json_for_each_item append_auth_server auth_server
append bss_conf "macaddr_acl=2" "$N"
append bss_conf "wpa_psk_radius=2" "$N"
elif [ ${#key} -eq 64 ]; then
if [ "$auth_type" = "psk" ] && [ "$ppsk" -ne 0 ] ; then
json_get_vars auth_secret auth_port
set_default auth_port 1812
json_for_each_item append_auth_server auth_server
append bss_conf "macaddr_acl=2" "$N"
append bss_conf "wpa_psk_radius=3" "$N"
elif [ ${#key} -eq 64 ]; then
wpa_psk_radius=3
(9) Received Access-Request Id 48 from 44.88.212.194:47297 to 164.160.89.129:1812 length 160
(9) User-Name = "ae0cd4e2c5ab"
(9) User-Password = "ae0cd4e2c5ab"
(9) NAS-Identifier = "m_hosta_51_74"
(9) Called-Station-Id = "64-64-4A-D1-2D-69:PPSK-1"
(9) NAS-Port-Type = Wireless-802.11
(9) Calling-Station-Id = "AE-0C-D4-E2-C5-AB"
(9) Connect-Info = "CONNECT 11Mbps 802.11b"
(9) Message-Authenticator = 0xeefd284dc6cf79df258e03b84791c2b8
(9) Sent Access-Accept Id 48 from 164.160.89.129:1812 to 44.88.212.194:47297 length 41
(9) Tunnel-Password := "77777777"
The difference in behaviour between wpa_psk_radius=2 and wpa_psk_radius=3 occurs when the PPSK is not correct.
If wpa_psk_radius=2, hostapd does NOT make any follow-up attempts.
If wpa_psk_radius=3, hostapd makes a follow-up attempt with additional attributes:
(10) Received Access-Request Id 49 from 44.88.212.194:47297 to 164.160.89.129:1812 length 337
(10) User-Name = "ae0cd4e2c5ab"
(10) User-Password = "ae0cd4e2c5ab"
(10) NAS-Identifier = "m_hosta_51_74"
(10) Called-Station-Id = "64-64-4A-D1-2D-69:PPSK-1"
(10) NAS-Port-Type = Wireless-802.11
(10) Calling-Station-Id = "AE-0C-D4-E2-C5-AB"
(10) Connect-Info = "CONNECT 11Mbps 802.11b"
(10) WLAN-AKM-Suite = 1027074
(10) Attr-245.26.11344.1 = 0xc4b0e7ca5cba50304c28e6995068b4b58dfb7d82944cf9c6caba2276018debde
(10) Attr-245.26.11344.2 = 0x0103007502010a0000000000000000000131a6c134eadc39dd97da1e4f9c0484e8b85d127f05edf553eb063248791ab0940000000000000000000000000000000000000000000000000000000000000000aad1fa6a0274d00e683b5947b4dc5e9d001630140100000fac040100000fac040100000fac020000
(10) Message-Authenticator = 0xd1ff97e6c9a794077c12e015e4f8e424
RADIUSdesk then includes advanced features in FreeRADIUS to process these additional attributes and attempt to determine the user's PPSK based on hash comparisons.
If a match is found, an access accept is returned with the plain text of the matching hash value.
(10) Sent Access-Accept Id 49 from 164.160.89.129:1812 to 44.88.212.194:47297 length 58
(10) Tunnel-Medium-Type = IEEE-802
(10) Tunnel-Type = VLAN
(10) Tunnel-Private-Group-Id = "100"
(10) Tunnel-Password = "11223344"
(10) Finished request
Heads-Up
Interestingly, during a troubleshooting session, I left FreeRADIUS running in debug mode for a day or two while sending requests to it from hostapd.
At some point, it stopped receiving the follow-up request no matter how many times I restarted the access points.
Finally, out of desperation, I restarted FreeRADIUS and lo and behold, the follow-up requests started coming in again.
Just a heads up about FreeRADIUS.
Reference config
config wifi-iface 'zero'
option ifname 'zero0'
option encryption 'psk2'
option acct_interval '300'
option mode 'ap'
option nasid 'a_hosta_53_97'
option acct_server '164.160.89.129'
option acct_secret 'testing123'
option auth_server '164.160.89.129'
option auth_secret 'testing123'
option network 'lan'
option device 'radio0'
option ssid 'PPSK-APdesk-1'
option ppsk '1'
option vlan_naming '0'
option vlan_tagged_interface 'wan'
option vlan_bridge 'br-ex_vlan'
option dynamic_vlan '1'
RADIUS-based PPSK implementations usually consist of two components:
The private key, which is used for authentication on the WiFi network.
The VLAN assignment, which is usually bound to the private key specified by the user.
The VLAN assignment is optional. If the RADIUS server has not specified a VLAN in the access acceptance, hostapd does not perform VLAN tagging for the connection of this client.
If a VLAN is specified in the RADIUS response, the following configuration options determine how hostapd handles the VLAN assignment:
option vlan_naming '0'
option vlan_tagged_interface 'wan'
option vlan_bridge 'br-ex_vlan'
option dynamic_vlan '1'
brctl show
bridge name bridge id STP enabled interfaces
br-ex_vlan100 7fff.ae7c588014f4 no vlan100
zero0.100
The name of the bridge is formulated with the value of vlan_bridge and the appending of the VLAN number (100).
The members of this bridge are the tagged WiFi client connection, zero0.100 and vlan100.
The vlan100 interface requires a little more explanation. Depending on the value of vlan_naming, which can be 0 or 1, the name of the second interface is determined.
Have a look at this part of the hostapd documentation
# When hostapd creates a VLAN interface on vlan_tagged_interfaces, it needs
# to know how to name it.
# 0 = vlan<XXX>, e.g., vlan1
# 1 = <vlan_tagged_interface>.<XXX>, e.g. eth0.1
#vlan_naming=0
brctl show
bridge name bridge id STP enabled interfaces
br-ex_vlan100 7fff.ae7c588014f4 no wan.100
zero0.100
Remember that for the VLAN to work correctly, you must also provide a DHCP server in the VLAN so that the client receives an IP address after it has authenticated itself in the WiFi network.
If you do not have such a server in your current network, you can easily do this in MESHdesk and APdesk.
The details are explained on the corresponding wiki pages.