Individual per-passphrase Wifi VLANs using wpa_psk_file (no RADIUS required)

You, my friend, are awesome! Thank you for that clarification. I will make sure to do that when I get home later today.

@takimata I was able to get this working after installing the full wpad-mbedtls package. I used the configuration from this thread as an example and now have password-based VLANs. Thanks again for clarifying that.

I am wondering tho, will this ever be able to use sae-mixed encryption? I was only able to get it working with psk2, but would love to use sae-mixed if possible.

1 Like

sae-mixed won't give you any benefit even if this particular issue is resolved. First of all, some (usually older) devices will not respond kindly to the mixed-mode network. Many WPA2-only devices simply won't connect no matter what, due to the network's advertisement of and/or requirement of features that aren't supported by those devices. Even some devices that officially support both WPA2 and WPA3 still get flaky and experience issues in the mixed-mode environment.

If you're looking to upgrade to WPA3 for the added security but still want WPA2 available for compatibility, you should also be aware that the very nature of the sae-mixed network means any device could be forcefully and remotely bumped back down to using WPA2. Once that has been done, the entire security value of using WPA3 is lost anyway.

If that all weren't enough, there are numerous reports out there of the sae-mixed networks being broken in other ways as well. If those reports are true, then even with this issue resolved, you may still be blocked by other problems.

3 Likes

Got it. Thanks for that heads up on that.

Thank you for your answer. I was afraid of this though. Besides the obvious duplication in the configuration file, if I want to say apply the same wifi-vlan and wifi-station to two APs, can I use exactly the same "option name" value for both of them or do I need to choose different names for each in order to avoid clashes? I'm asking because with 1 wifi-vlan and 1 wifi-station for 2 APs it is relatively straightforward but with larger numbers the extra names to avoid duplication would be just plain silly.

You will always have duplicate configurations, even with a RADIUS setup you still have to configure the individual APs. But yes, I see your point, it may get cumbersome to deploy changes and more elaborate configurations. Wasn't there someone who created a set of scripts to do that centralized?

Anyway, noone's stopping you from copy&pasting:

I don't see why not. The other devices don't see that, they only see the traffic from the AP tagged with the respective numeric VLAN tag, and sharing that VLAN-tagged traffic between devices is actually kind of the point.

I currently use a bunch of different SSIDs for segregating traffic. Each has its own bridge device and VLAN interface. This works fine, but generates extra 'beacon' traffic. Since I normally keep most of the SSIDs hidden, client setup typically requires extra steps in the UI. Using a single SSID with different passwords would eliminate both issues.

It's my understanding that your setup will automatically create the bridge device and VLAN interface based on the hostapd.wpa_psk and hostapd.vlan files. I have wpad-mbedtls installed. I think I've got everything configured properly, but LuCI shows the SSIDs as disabled. I don't see any error messages, but maybe I'm not looking in the right place.

The documentation gives the following example of a minimal config:

config	wifi-iface
	option	device		'wl0'
	option	network		'lan'
	option	mode		'ap'
	option	ssid		'MyWifiAP'
	option	encryption	'psk2'
	option	key		'secret passphrase'

It seems that OpenWrt is not happy without a network and key, but the key now has multiple values and the network is supposed to be generated dynamically/automatically. What am I doing wrong? How can I tell if my hostapd files are being used?

Here's my wireless file. I've actually configured 2 SSIDs on each band. Since I have 2 APs, I normally use overlapping SSIDs, but I want a specific SSID for debugging. X is 5GHz overlapped. X2 is 5GHz on AP2. x is 2.4GHz overlapped. x2 is 2.4GHz on AP2. I've added custom MAC addresses so that I can use a common hostapd.wpa_psk. I could further simplify if I can reuse the same MAC.

config wifi-device 'radio0'
	option type 'mac80211'
	option path 'ffe0a000.pcie/pcia000:02/a000:02:00.0/a000:03:00.0'
	option channel '48'
	option band '5g'
	option htmode 'VHT80'
	option cell_density '0'

config wifi-iface 'wifinet1'
	option device 'radio0'
	option ifname 'X'
	option macaddr 'ee:ee:ee:ee:00:22'
	option mode 'ap'
	option ssid 'X'
	option hidden '0'
	option encryption 'psk2'
	option key 'not_used'
	option wpa_psk_file '/etc/hostapd.wpa_psk'
	option vlan_file '/etc/hostapd.vlan'
    option vlan_tagged_interface 'eth0'
    option vlan_bridge 'magic'	
    option dynamic_vlan '2'

config wifi-iface 'wifinet2'
	option device 'radio0'
	option ifname 'X2'
	option macaddr 'ee:ee:ee:ee:02:22'
	option mode 'ap'
	option ssid 'X2'
	option hidden '0'
	option encryption 'psk2'
	option key 'not_used'
	option wpa_psk_file '/etc/hostapd.wpa_psk'
	option vlan_file '/etc/hostapd.vlan'
    option vlan_tagged_interface 'eth0'
    option vlan_bridge 'magic'	
    option dynamic_vlan '2'


config wifi-device 'radio1'
	option type 'mac80211'
	option path 'ffe09000.pcie/pci9000:00/9000:00:00.0/9000:01:00.0'
	option channel '6'
	option band '2g'
	option htmode 'HT20'
	option cell_density '0'

config wifi-iface 'wifinet3'
	option device 'radio1'
	option ifname 'x'
	option macaddr 'ee:ee:ee:ee:00:12'
	option mode 'ap'
	option ssid 'x'
	option hidden '0'
	option encryption 'psk2'
	option key 'not_used'
	option wpa_psk_file '/etc/hostapd.wpa_psk'
	option vlan_file '/etc/hostapd.vlan'
    option vlan_tagged_interface 'eth0'
    option vlan_bridge 'magic'	
    option dynamic_vlan '2'

config wifi-iface 'wifinet4'
	option device 'radio1'
	option ifname 'x2'
	option macaddr 'ee:ee:ee:ee:02:12'
	option mode 'ap'
	option ssid 'x2'
	option hidden '0'
	option encryption 'psk2'
	option key 'not_used'
	option wpa_psk_file '/etc/hostapd.wpa_psk'
	option vlan_file '/etc/hostapd.vlan'
    option vlan_tagged_interface 'eth0'
    option vlan_bridge 'magic'	
    option dynamic_vlan '2'

There may be more involved depending on your setup, but I've found in all of my attempts that the main configuration (effectively the fallback) must have a network and key associated before the SSID will come online. In my setup, for instance, I started with a simple configuration that points the SSID at my guest network and guest network password. On top of that, I added the separate PSK options and vlan definitions for the other networks I wanted to extend. Once all was in place, I performed a complete restart of wpad and everything came online as intended.

Please note that there's a chance your specified MAC address may be involved as well, if it wasn't the one you previously successfully used. For whatever reason, some wireless radios refuse to accept the assignment certain MAC addresses. I don't know the reasoning or logic for this.

Thanks for your reply. I already tried commenting out the custom MACs. I don't think that's the problem. I'll create a dummy network and see if the magic comes alive.

Just for reference, are you running the latest OpenWrt release? I was not able to get the hostapd.wpa_psk method to work-- even though I believe my configuration is correct and I could tell something had changed (i.e. the radio was disabled). Are your interfaces created and destroyed on-demand or does everything appear at startup?

I decided to try the equally obscure wifi-vlan and wifi-station sections (which do not get stripped out by LuCI). This actually works as expected and does not require anything more than hostapd-basic-mbedtls. You create the bridges and wrapper interfaces manually. OpenWrt automatically creates the Wi-Fi interfaces and attaches each to the corresponding ethernet interface/bridge. This is all immediately visible under LuCI > Network > Interfaces.

Behind the scenes, in /tmp/run there's a hostapd-<name>.psk and hostapd-<name>.vlan generated for each SSID. Curiously, these files are formatted exactly as my original hostapd.wpa_psk. The only difference is that I had merged them all into a single file based on MAC.

There still appears to be a bug when you disconnect from an SSID. I assume this affects everyone whether you knew it or not. In my case, it does not crash the AP, so I can limp along until I get a build with the fix.

It's not clear why they bothered to implement option mac <address> when you can use the more generic option iface <name> which references a config wifi-iface <name> block. As mentioned above, the password pools are already separated by SSID. Using a specific MAC filter is redundant.

Since you manually configure your own interfaces, the vid under wifi-vlan and wifi-station is really just an arbitrary link. You could use a different physical VLAN or none at all. If your Wi-Fi lives inside a router, you could directly configure subnets and DHCP on each interface.

For anyone else trying to set this up, when attempting a Wi-Fi connection, if you get stuck on 'authenticating', then there's something wrong with your password configuration. You'll likely get a prompt to reenter the password. If you get stuck on 'connecting', then OpenWrt matched your password, but there's something wrong with your interface. If you need to test an interface, you could add a spare ethernet port to the corresponding bridge.

You don't have to waste your base option key and option network under config wifi-iface. Fill in those values and omit what would be another config wifi-station.

1 Like

I am indeed using the latest release. I didn't directly edit the wpa_psk file, but instead used the wifi-vlan and wifi-station sections in the wireless config file, but the bridges and wrapper interfaces are automatically created for me.

I did note that changes to these sections in settings required a complete restart of wpad and occasionally a reboot for everything to be recognized.

The bug does indeed appear to be present on multiple platforms, including the ones I'm using. However, like you said, it doesn't appear to be fatal and so it went unnoticed until I checked just now.

OK, so our configuration and outcome are similar. What additional options did you add to your config wifi-iface section(s)? Is it possible that your 'automatic' bridges/interfaces were actually created some time in the past by an earlier build? I prefer the manual process, but I'd like to understand the options.

The wireless vlan bridges are created and destroyed on-the-fly, even in 23.05.3. I've altered the configuration a few times over multiple revisions of 23.05.x and have had similar results, and the current configuration I am using was not in place prior to 23.05.x.

As for the options I used, here's a functional example with the same parameters that I successfully used in my configuration:

config wifi-iface 'wifinet0'
	option device 'radio0'
	option mode 'ap'
	option ssid 'YourWifiSSIDGoesHere'
	option key 'GuestNetworkWPAKey'
	option network 'MYGUESTNETWORK'
	option encryption 'psk2+ccmp'
	option proxy_arp '1'
	option wnm_sleep_mode_no_keys '1'
	option wpa_disable_eapol_key_retries '1'
	option ieee80211k '1'
	option bss_transition '1'

config wifi-vlan
	option name 'example'
	option vid '3'
	option network 'MYSECONDNETWORK'
	option iface 'wifinet0'

config wifi-station
	option iface 'wifinet0'
	option vid '3'
	option key '2ndNetworkWPAKey'

config wifi-vlan
	option name 'anotherexample'
	option vid '4'
	option network 'MYTHIRDNETWORK'
	option iface 'wifinet0'

config wifi-station
	option iface 'wifinet0'
	option vid '4'
	option key 'ThirdNetworkWPAKey'

2 Likes

What VLAN id does the base wifi-iface get with this? 1?
(use bridge vlan to test)
Thanks.

When the packets go out via the ethernet port, they will take on whichever vlan is associated with the network interface to which the wifi network is connected. For instance, taking my example configuration, if the wireless client connects with the password "GuestNetworkWPAKey", the packets will be sent alongside the rest of the traffic for the uci network configuration interface named "MYGUESTNETWORK". Said settings include DHCP from that network's range, the vlan tag(s) associated with that network (if any), and every other setting configured for that interface will apply.

If the client connects with the password "2ndNetworkWPAKey", the packets will be sent with the settings applied to the network interface called "MYSECONDNETWORK" and so on.

Thanks for the detailed explanation.

So if the definition of MYGUESTNETWORK has list ports 'lan.17', the VLAN id will be 17?

If so, what happens if MYSECONDNETWORK has list ports 'lan.19'? will it be VLAN id 19 or 3 (from the wifi-vlan named example)

Will that work also when the AP is bridged to a 802.11s mesh or a STA iface instead of an ethernet switch (e.g. wireless repeater)?

If MYSECONDNETWORK uses lan.19 then it would be VLAN 19 when the packets emerge on the cable.

I didn't write the support code and haven't reviewed it to see where all the data goes, but it looks to me and appears to behave as if the 'vid' assignments are effectively little more than an ID to ensure the proper wifi_vlan and wifi_station sections are linked together without getting mixed up with any others. However, there's nothing wrong with using the same number that you expect to see for the VLAN, either. At the very least, it would reduce confusion there.

2 Likes
Wrote this:
#!/bin/sh

TEMP_DIRS="/tmp /var/tmp /dev/shm"
SCRIPT_DIR=$(dirname "$0")
IS_TEMP=0

for temp_dir in $TEMP_DIRS; do
    if [ "$SCRIPT_DIR" = "$temp_dir" ]; then
        IS_TEMP=1
        break
    fi
done

if [ $IS_TEMP -eq 0 ]; then
    echo "This script must be run from a temporary directory."
    echo "Please move it to a temporary directory and run it again."
    exit 1
fi

trap 'rm -f "$0"' EXIT

opkg update
opkg install wpa_supplicant

echo "Enter the SSID:"
read SSID

echo "Enter the passphrases (separated by space):"
read -a PASSPHRASES

cat <<EOF >> /etc/wpa_supplicant/wpa_supplicant.conf
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=0
update_config=1
fast_reauth=1
ap_scan=1

EOF

for passphrase in "${PASSPHRASES[@]}"; do
    cat <<EOF >> /etc/wpa_supplicant/wpa_supplicant.conf
network={
    ssid="$SSID"
    psk="$passphrase"
    id_str="$passphrase"
    key_mgmt=WPA-PSK
    priority=1
}

EOF
done

cat <<EOF > /usr/local/bin/assign_permissions.sh
#!/bin/sh

CONNECTED_PASSPHRASE=\$(cat /etc/wpa_supplicant/wpa_supplicant.conf | grep -A 1 "id_str" | tail -n 1 | cut -d '"' -f 2)

case "\$CONNECTED_PASSPHRASE" in
    "Passphrase1")
        echo "Assigning permissions for Passphrase1"
        ;;
    "Passphrase2")
        echo "Assigning permissions for Passphrase2"
        ;;
    *)
        echo "Unknown passphrase"
        ;;
esac
EOF

chmod +x /usr/local/bin/assign_permissions.sh

echo "post-up=/usr/local/bin/assign_permissions.sh" >> /etc/wpa_supplicant/wpa_supplicant.conf

/etc/init.d/wpa_supplicant restart

Hope this will make such setup less painless…

Thanks for this summary to get things up and running :slight_smile:

This helped me to implement the 'without RADIUS' PPSK support in RADIUSdesk.

'with RADIUS' we added some more advanced features like ability to do data limits.

Hey, I'm trying to make it work on my main router (before going to the ap's).

I don't know what am I missing, but when I add the vlan stuff into wireless settings, the 5ghz interface is not going up, its enabled but the ssid is not even appearing looking for wifi devices.

I did remove wpad-basic-mbedtls (which was the one installed on my router by default) and installed wpad-mbedtls.

Here is my config:

ubus call system board

{
        "kernel": "5.15.150",
        "hostname": "OpenWrt-Main",
        "system": "ARMv8 Processor rev 4",
        "model": "GL.iNet GL-MT6000",
        "board_name": "glinet,gl-mt6000",
        "rootfs_type": "squashfs",
        "release": {
                "distribution": "OpenWrt",
                "version": "23.05.3",
                "revision": "r23809-234f1a2efa",
                "target": "mediatek/filogic",
                "description": "OpenWrt 23.05.3 r23809-234f1a2efa"
        }

/etc/config/network

config interface 'loopback'
	option device 'lo'
	option proto 'static'
	option ipaddr '127.0.0.1'
	option netmask '255.0.0.0'

config device
	option name 'br-lan'
	option type 'bridge'
	list ports 'lan1'
	list ports 'lan2'
	list ports 'lan3'
	list ports 'lan4'
	list ports 'lan5'
	option ipv6 '0'

config device
	option name 'lan1'
	option macaddr 'censored'
	option ipv6 '0'

config device
	option name 'lan2'
	option macaddr 'censored'
	option ipv6 '0'

config device
	option name 'lan3'
	option macaddr 'censored'
	option ipv6 '0'

config device
	option name 'lan4'
	option macaddr 'censored'

config device
	option name 'lan5'
	option macaddr 'censored'
	option ipv6 '0'

config interface 'lan'
	option device 'br-lan.9'
	option proto 'static'
	option ipaddr '192.168.9.1'
	option netmask '255.255.255.0'
	option delegate '0'

config device
	option name 'eth1'
	option macaddr 'censored'
	option ipv6 '0'

config interface 'wan'
	option device 'eth1'
	option proto 'dhcp'

config bridge-vlan
	option device 'br-lan'
	option vlan '9'
	list ports 'lan1:u*'
	list ports 'lan2:t'
	list ports 'lan4:u*'
	list ports 'lan5'

config bridge-vlan
	option device 'br-lan'
	option vlan '5'
	list ports 'lan2:t'
	list ports 'lan3:t'

config bridge-vlan
	option device 'br-lan'
	option vlan '7'
	list ports 'lan2:t'

config bridge-vlan
	option device 'br-lan'
	option vlan '16'
	list ports 'lan2:t'

config bridge-vlan
	option device 'br-lan'
	option vlan '18'
	list ports 'lan2:t'

config bridge-vlan
	option device 'br-lan'
	option vlan '20'
	list ports 'lan2:t'
	list ports 'lan3:t'

config bridge-vlan
	option device 'br-lan'
	option vlan '30'
	list ports 'lan2:t'
	list ports 'lan3:t'

config interface 'LOCAL'
	option proto 'static'
	option device 'br-lan.5'
	option ipaddr '192.168.5.1'
	option netmask '255.255.255.0'
	option delegate '0'

config interface 'TRABAJO'
	option proto 'static'
	option device 'br-lan.7'
	option ipaddr '192.168.7.1'
	option netmask '255.255.255.0'
	option delegate '0'

config interface 'CAMARAS'
	option proto 'static'
	option device 'br-lan.16'
	option ipaddr '192.168.16.1'
	option netmask '255.255.255.0'
	option delegate '0'

config interface 'ALARMA'
	option proto 'static'
	option device 'br-lan.18'
	option ipaddr '192.168.18.1'
	option netmask '255.255.255.0'
	option delegate '0'

config interface 'IoT'
	option proto 'static'
	option device 'br-lan.20'
	option ipaddr '192.168.20.1'
	option netmask '255.255.255.0'
	option delegate '0'

config interface 'GUEST'
	option proto 'static'
	option device 'br-lan.30'
	option ipaddr '192.168.30.1'
	option netmask '255.255.255.0'
	option delegate '0'

config bridge-vlan
	option device 'br-lan'
	option vlan '10'
	list ports 'lan2:t'
	list ports 'lan3:t'
	list ports 'lan5:u*'

config interface 'MANAGEMENT'
	option proto 'static'
	option device 'br-lan.10'
	option ipaddr '192.168.10.1'
	option netmask '255.255.255.0'
	option delegate '0'

/etc/config/wireless


config wifi-device 'radio0'
	option type 'mac80211'
	option path 'platform/soc/18000000.wifi'
	option band '2g'
	option htmode 'HE20'
	option country 'ES'
	option cell_density '0'
	option channel '1'
	option txpower '10'

config wifi-iface 'default_radio0'
	option device 'radio0'
	option network 'LOCAL'
	option mode 'ap'
	option ssid 'SSID2.4'
	option encryption 'psk2'
	option key 'censored'
	option disabled '1'

config wifi-device 'radio1'
	option type 'mac80211'
	option path 'platform/soc/18000000.wifi+1'
	option channel '40'
	option band '5g'
	option htmode 'HE80'
	option country 'ES'
	option cell_density '0'
	option txpower '12'

config wifi-iface 'default_radio1'
	option device 'radio1'
	option network 'LOCAL'
	option mode 'ap'
	option ssid 'SSID5'
	option encryption 'psk2'
	option key 'censored'

config wifi-vlan
	option name 'wifi-vlan'
	option network 'IoT'
	option vid '20'
	option iface 'default_radio1'

config wifi-station
	option key 'censored'
	option vid '20'
	option iface 'default_radio1'

What am I missing?