Using freeradius to assign VLANs for UniFi Wi-Fi

This is another post which is as much for me as for anyone else.

Using freeradius to assign VLANs for UniFi Wi-Fi

I have a UniFi-based Wi-Fi setup, with different VLANs for different things. The UniFi controller is running on a Debian 10 virtual machine.

Rather than just using different SSIDs for each VLAN, I wanted one VLAN, and then to use radius to authenticate users, and assign them to the right VLAN.

I was planning on using a bit of Ubiquiti hardware for this - one of their Unifi Security Gateways - but I wanted to use it only for the radius functionality, and not for any routing. However, according to the UniFi support, this is not possible (yet, at least).

So I am using freeradius, running on the same virtual machine as the UniFi controller.

Getting freeradius working

Installing freeradius should be as simple as

apt install freeradius -y

And it might be for you.

I had a bit of a fight with it, and I'm not 100% sure if it is my fault (probably), or some unusual packaging issue.

My problem was perhaps an edge case - I have tried this before, gave up, and seemingly deleted the directory structure in /etc/freeradius. When I tried to re-install freeradius with apt install freeradius -y, it failed, citing the lack of /etc/freeradius.

The solution - thanks to 0x47DF - was that I had seemingly failed to purge all the various freeradius apt packages.

I cannot be sure exactly what I did to get it working, as I tried so much, but I think it was:

apt purge freeradius-config -y
apt install freeradius -y

Anyway, I finally got it running.

Configuring freeradius

I kept configuration very light.

If you use the default Debian packages, the install path for the config files is /etc/freeradius/3.0.

If you use the networkradius Debian packages, as I ended up doing, the install path for the config files is /etc/freeradius.

In mods-enabled/eap, I set the following:

  • default_eap_type = tls
  • use_tunneled_reply = yes in both places that stanza appeared

I left the certificates alone, as they worked. However, the default expiry is just 60 days. I have changed the config file to extend this, but I could not work out how to replace the already-generated certificates, so that is a problem for another day.

Adding a client

I am using the UniFi controller to control my system, and so I need the radius system to respond to traffic from my access points. For this, I configured the clients.conf file.

I added a new section:

client unifi {
    ipaddr = [the IP range of my UniFi APs]
    secret = [a long password, which goes into the UniFi controller]
    shortname = unifi
}

Adding users

In used the users file to specify which users should get access, and to which VLAN they should be assigned.

Each user looks a bit like this:

name-of-user Cleartext-Password := "a-long-password"
    Tunnel-Type = VLAN,
    Tunnel-Medium-Type = 6,
    Tunnel-Private-Group-Id = [numeric VLAN tag]

So if you wanted to add a configuration for the username "bob", with a password of "television-adventurer-40", putting their traffic onto VLAN 20, you would use:

bob Cleartext-Password := "television-adventurer-40"
    Tunnel-Type = VLAN,
    Tunnel-Medium-Type = 6,
    Tunnel-Private-Group-Id = 20

Restart freeradius

When you've done with the configuration, restart freeradius.

You could use systemd for that:

systemctl restart freeradius

But it might be easier, for debugging, to start it manually:

freeradius -X

Testing using radtest

Before trying it out on a proper device, I tested my config using radtest.

However, I could not test my unifi client config, only the default config for localhost.

For the "bob" user above, you might test it with:

radtest bob television-adventurer-40 localhost 0 testing123

You should get a result of:

Sent Access-Request Id 72 from 0.0.0.0:39469 to 127.0.0.1:1812 length 77
    User-Name = "bob"
    User-Password = "television-adventurer-40"
    NAS-IP-Address = 127.0.1.1
    NAS-Port = 0
    Message-Authenticator = 0x00
    Cleartext-Password = "television-adventurer-40"
Received Access-Accept Id 72 from 127.0.0.1:1812 to 127.0.0.1:39469 length 37
    Tunnel-Type:0 = VLAN
    Tunnel-Medium-Type:0 = IEEE-802
    Tunnel-Private-Group-Id:0 = "20"

Connecting the UniFi controller to radius

The UniFi side of things was quite easy.

In Settings / Profiles (in the Unifi controller), I created a new radius profile.

I ticked Enable RADIUS assigned VLAN for wireless network.

For IP address, I gave:

  • IP address: the IPv4 address of the server (not localhost / 127.0.0.1)
  • Port: 1812
  • Password: the "secret" I set in the unifi section of freeradius's client.conf

I saved the profile.

Also in Settings, in Wireless Networks, I created a new wireless network, set the RADIUS profile to the profile I just created, and saved it.

Connecting a device

On my device - in my case, an Apple TV - I selected the SSID, and was prompted for the username and password. I used the credentials I set up in the freeradius users file. I was then prompted to accept the unsigned, soon-to-expire, certificate.

And it worked: the Apple TV was assigned to the right VLAN.

If that works, it should be straightforward to attempt to connect


Author: neil

I'm Neil. By day, I run a law firm, decoded.legal, giving advice on Internet, telecoms, and tech law. This is my personal blog, so will be mostly about tech stuff, cycling, and other hobbies.

You can find me (and follow me) on Mastodon and Twitter.