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.