Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
technical:ppsk-hostapd [2024/04/18 18:27] systemtechnical:ppsk-hostapd [2024/04/30 08:22] (current) – [Key specific for VLAN] system
Line 5: Line 5:
  
 ----- -----
-====== Private PSK (PPSK) feature on hostapd ======+====== Private PSK (PPSK) function on hostapd ======
 ===== File or RADIUS ===== ===== File or RADIUS =====
-  * The PPSK feature in hostapd gives the user the choice of providing the PPSKs using a file or using RADIUS. +  * The PPSK function in hostapd gives the user the choice of providing the PPSKs via a file or via RADIUS. 
-  * Having the option of supplying the PPSKs in a text file allows for quick and simplified deployments.+  * The option to provide the PPSKs in a text file enables fast and simplified provisioning.
  
 ------ ------
-===== Quick and dirty file based PPSK on OpenWrt ===== +===== FILE - Quick and dirty PPSK on OpenWrt ===== 
-  * We assume you are familiar with the UCI system in OpenWrt. +  * We assume that you are familiar with the UCI system in OpenWrt. 
-  * Configure SSID with WPA2 pre shared key.+  * Configure an SSID with WPA2 pre-shared key.
 <code bash> <code bash>
 config wifi-iface 'two' config wifi-iface 'two'
Line 27: Line 27:
    option ssid 'RADIUSdesk'    option ssid 'RADIUSdesk'
 </code>  </code> 
-  * Next we will replace the key which is a single value (12345678) with a file with multiple keys.+  * Nextwe will replace the keywhich is a single value (12345678)with a file with multiple keys.
 <code bash> <code bash>
 config wifi-iface 'two' config wifi-iface 'two'
Line 44: Line 44:
   * Here is the contents of the /etc/psk.list file   * Here is the contents of the /etc/psk.list file
 <code bash> <code bash>
 +# 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 highwaystar
 00:00:00:00:00:00 blacknight 00:00:00:00:00:00 blacknight
Line 55: Line 57:
 wifi up wifi up
 </code> </code>
-  * hostapd will now go through the list in the PSK file and see if it can find a match when someone tries to connect to the SSID.+  * hostapd now goes through the list in the PSK file and checks whether it finds a match when someone tries to connect to the SSID.
  
 --------- ---------
  
-===== Advanced file based PPSK on OpenWrt ===== +===== FILE - Advanced PPSK on OpenWrt ===== 
-  * The first section covered a very basic PPSK implementation. +  * The first section dealt with a very simple PPSK implementation. 
-  * This section will look at more advanced options including MAC and VLAN association with certain keys.+  * This section is about more advanced optionsincluding mapping MAC and VLAN to specific keys. 
 +  * You can also visit [[https://forum.openwrt.org/t/individual-per-passphrase-wifi-vlans-using-wpa-psk-file-no-radius-required/161696|this]] forum discussion where most of the information comes from. 
 +==== Key specific for MAC ====   
 +  * If we look at the comments of the sample psk.list file we see the following 
 +<code bash> 
 +# 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 
 +</code> 
 +  * The alternative 256-bit hex value is a hash that contains the specific SSID to which a user connects. 
 +  * You can generate the value using this JavaScript-based online utility from WireShark.(https://www.wireshark.org/tools/wpa-psk.html) 
 +  * 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 ====   
 +  * If we look at the comments of the sample psk.list file also we see the following 
 +<code bash> 
 +# 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 
 +</code>  
 +  * 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 
 +<code bash> 
 +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' 
 +</code> 
 +  * Then here is an example of hostapd.vlan 
 +<code bash> 
 +# 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# 
 +</code> 
 +  * hostapd will create a bridge with each VLAN and automatically create tagged interfaces and make them members of this bridge: 
 +<code bash> 
 +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 
 +</code>
  
 ------ ------
 +===== RADIUS - PPSK on OpenWrt =====
 +  * This section describes how to implement RADIUS-based PPSK on OpenWrt.
 +  * The key to enabling RADIUS-based PPSK lies in the following setting in **hostapd.conf**.
 +<code bash>
 +# 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
 +</code>
 +  * 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
 +<code bash>
 +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
 +
 +</code>
 +  * And change it to:
 +<code bash>
 +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
 +</code>
 +
 +  * We will look at the reason for this in the next section.
 +
 +==== wpa_psk_radius=3 ====
 +  * If wpa_psk_radius=2 or wpa_psk_radius=3, the first request from hostapd to the RADIUS server looks like this:
 +<code bash>
 +(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
 +</code>
 +  * RADIUS will then typically reply with an Access Accept with the PPSK
 +<code bash>
 +(9) Sent Access-Accept Id 48 from 164.160.89.129:1812 to 44.88.212.194:47297 length 41
 +(9)   Tunnel-Password := "77777777"
 +</code>
 +  * 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:
 +<code bash>
 +(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
 +</code>
 +  * 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.
 +<code bash>
 +(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
 +</code>
 +  * This behaviour enables PPSK in RADIUS, which does not require MAC address matching.
 +  * To summarise once again:
 +        *  If **wpa_psk_radius=2**, the RADIUS implementation has to work with MAC address matching and is very cumbersome.
 +        *  If **wpa_psk_radius=3**, the RADIUS implementation can work with the encrypted value of the PSK specified by the user to perform a hash comparison and is therefore much more flexible. RADIUSdesk supports this option.
 +        * However, you will need to modify the /lib/netifd/hostapd.sh file to create the hostapd configuration with this option.
 +
 +
 +<alert type="warning">
 +=== 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.
 +</alert>
 +
 +
 +==== Reference config ====
 +  * Let us take a look at a simple reference configuration of /etc/config/wireless in which RADIUS-based PPSK is configured.
 +<code bash>
 +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'        
 +</code>
 +  * 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:
 +<code>
 +option vlan_naming '0'                                                                                                                                                                                                                                                  
 +option vlan_tagged_interface 'wan'                                                                                                                                                                                                                                      
 +option vlan_bridge 'br-ex_vlan'                                                                                                                                                                                                                                         
 +option dynamic_vlan '1' 
 +</code>
 +  * If a client establishes a connection and RADIUS specifies VLAN 100, for example, hostapd dynamically creates the following bridge:
 +<code bash>
 +brctl show
 +bridge name bridge id STP enabled interfaces
 +br-ex_vlan100 7fff.ae7c588014f4 no vlan100
 + zero0.100
 +
 +</code>
 +  * 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
 +<code bash>
 +# 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
 +</code>
 +  * So if we change our configuration to the **vlan_naming '1'** option, the bridge would look like this:
 +<code bash>
 +brctl show
 +bridge name bridge id STP enabled interfaces
 +br-ex_vlan100 7fff.ae7c588014f4 no wan.100
 + zero0.100
 +
 +</code>
 +  * 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.
 +
  • technical/ppsk-hostapd.1713457643.txt.gz
  • Last modified: 2024/04/18 18:27
  • by system