Hello all and sorry for my lack of posts this year.
I have had many visitors who have given my private Wi-FI password because they needed internet access, but later I thought that I don’t like having them on my private network.
What I wanted was locking them out, without creating a new “Guest Network”, but keeping the same SSID/key. In other words, I’d wanted my trusted devices and the visitor’s devices on two Layer 2 separated networks. The answer is: VLAN.
Oh… The trusted list is a MAC address list.
My access point is based on hostapd, a linux daemon that is managing the Wi-Fi cards (PCI or USB) and it has a couple of settings to manage VLANs:
# Dynamic VLAN mode; allow RADIUS authentication server to decide which VLAN # is used for the stations. This information is parsed from following RADIUS # attributes based on RFC 3580 and RFC 2868: Tunnel-Type (value 13 = VLAN), # Tunnel-Medium-Type (value 6 = IEEE 802), Tunnel-Private-Group-ID (value # VLANID as a string). Optionally, the local MAC ACL list (accept_mac_file) can # be used to set static client MAC address to VLAN ID mapping. # 0 = disabled (default) # 1 = option; use default interface if RADIUS server does not include VLAN ID # 2 = required; reject authentication if RADIUS server does not include VLAN ID #dynamic_vlan=0 # Station MAC address -based authentication # 0 = accept unless in deny list # 1 = deny unless in accept list # 2 = use external RADIUS server (accept/deny lists are searched first) #macaddr_acl=0 # Bridge (prefix) to add the wifi and the tagged interface to. This gets the # VLAN ID appended. It defaults to brvlan%d if no tagged interface is given # and br%s.%d if a tagged interface is given, provided %s = tagged interface # and %d = VLAN ID. #vlan_bridge=brvlan
As you can see, one option is using the ‘accept_mac_file’ file, which permits a static mapping of your MAC Addresses <-> VLANs. Anyway, using this approach would force you to list all the MAC addresses of every device connecting to your Wi-Fi network. That’s because you can’t use any wildcard for the MAC addresses on that file!
But there is another approach, using RADIUS.
With ‘dynamic_vlan=1’ plus ‘macaddr_acl=2’, the accept/reject request based on the MAC Address pass through the RADIUS server, which reply with or without the “Tunnel-Private-Group-ID” (VLAN ID). The RADIUS server must be configured to accept any request (remember, the network is already protected by your PSK key) but including the “Tunnel-Private-Group-ID” parameter only to the unknown MAC addresses, because we want the well known MACs to be left on the default VLAN (dynamic_vlan=1 # use default interface if RADIUS server does not include VLAN ID).
This is the theory. Now the practice..
apt-get install freeradius
On a Ubuntu 15.10 I didn’t modify much of the freeradius configuration.
The most important file is /etc/freeradius/users in which we can define the replies to give back to hostapd daemon. You must configure first the well known MAC addresses with the Auth-Type ‘Accept’ but without the VLAN specification. For example my ESP8266 has the ’18:fe:34:fa:5a:ba’ MAC address, so…
18fe34fa5aba Auth-Type := Accept
Then, if an unknown MAC address is requesting connectivity to our network, we have a default entry accepting it and assigning the guest VLAN ID to it. On the hostapd side, this means that the device will be attached to the brvlan1000 bridge.
DEFAULT Auth-Type := Accept Tunnel-Type = VLAN, Tunnel-Medium-Type = IEEE-802, Tunnel-Private-Group-Id := 1000
To complete the post, here’s my hostapd.conf:
interface=wlan1 bridge=br0 # AP Name Definition ssid=MyNetwork hw_mode=g ieee80211n=1 ieee80211d=1 country_code=GD wmm_enabled=1 channel=1 # WPA-PSK Passphrase definition wpa=2 # WPA2 only auth_algs=1 # 1=wpa, 2=wep, 3=both wpa_key_mgmt=WPA-PSK rsn_pairwise=CCMP wpa_pairwise=TKIP wpa_passphrase=secret # RADIUS authentication server own_ip_addr=127.0.0.1 auth_server_addr=127.0.0.1 auth_server_port=1812 auth_server_shared_secret=testing123 # VLAN Configuration # # # use default interface if RADIUS server does not include VLAN ID dynamic_vlan=1 # defining vlan vlan_file=/etc/hostapd/hostapd1.vlan # use external RADIUS server for MAC Address filtering macaddr_acl=2
Do not forget to define the VLANs on /etc/hostapd/hostapd1.vlan (1000 + default) and attach the brvlan1000 to your firewall with your rules.