As soon as the radius daemon on my OPNsense box was responding properly I decided to add radsecproxy
.
But before doing so I had to get an idea how things work together. So keep in mind, all I have right now is a basic freeradius
setup that can authenticate users against LDAP (at least with a test client).
Things involved
So while reading about radius, there are several “things” you’ll read about sooner or later: users, clients, servers, NAS, realms and proxies (to name only the most relevant ones).
And all of those things need to be in place in order to make radsecproxy
work. So while there are surely better explanations out there, I’ll start with a very low-level version:
In the beginning there was … no just kidding … but let’s start with the user, or better the username: In the (possibly federated) radius world, a user consists of a (short) username and a realm (something like marcel@mydomain.de
, where marcel
is the short username and mydomain.de
represents a realm).
This user will use a client (e.g. his laptop) to connect to a NAS (network access server) and that could be anything from a WiFi access point to a RDP-Server.
This NAS will then use the credentials provided by the user to authenticate against a (radius) server.
If you paid close attention you’ll have noticed, that there are two things still missing: proxies and realms.
The (radius) proxy can do different things: One is the thing I try to achieve: Wrap the radius protocol in some kind of encryption layer, to make it more secure. The other use case is federated radius: So what’s that?
Basically it means you will have multiple different authentication services (maybe from different institutions) but you can use all of them to authenticate.
And that’s where the realm comes into play: in such an environment the user databases are spread over several realms. An the realm (as part of the username) helps to decide which authentication server should be used.
That’s it (in a very short version). We’ll come back to all of this later on during the configuration.
Installation radsecproxy
So first of all there’s the plugin to install. So by going to System->Firmware->Plugins
and searching for “radsec” results in:
os-radsecproxy: RADIUS proxy provides both RADIUS UDP and TCP/TLS (RadSec) transport
Next step: Install it using the "+"
button.
Do a short reload of the OPNsense
web UI to make the new entry Services->RadSecProxy
appear.
Configuration
Allow co-existence of freeradius and radsecproxy
As I’d like to run both freeradius and radsecproxy on my OPNsense firewall, and both are by default using the same radius port (1812/udp
) one of them will fail to start.
So let’s enable “advanced mode” under Services->RadSecProxy->General
and set “Listen UDP” to “192.168.1.1:1814
” (where 192.168.1.1
should be replaced with the IP of your OPNsense firewall appliance and 1814
by some unused UDP port).
That should make radsecproxy happy port-wise.
What needs to be configured?
First of all we’ll just try to get radsecproxy
up and running as a plain UDP proxy – no encryption, just forwarding requests to freeradius
.
Here’s what needs to be done to make that work:
Services->RadSecProxy->Clients
:
We’ll add possible clients (as we did in the freeradius configuration. I’ll even use the same secret for now, to easily switch between the freeradius backend and the new proxied one)
Services->RadSecProxy->Servers
:
Here we just enter the IP
/Port
/Secret
of the pre-configured freeradius server and give it an “Unique Identifier
“
Services->RadSecProxy->Realms
:
Add a realm (in my case “mydomain.de
“) and select the server configured in the last step as “Server
” (no “Accounting Server
” for now).
Save settings and restart radsecproxy
.
Testing – UDP proxy only
For now we’ve not really done anything to improve things: We’re still using UDP only, we’re only forwarding/proxying requests to freeradius
. Nonetheless this seems a good point to check if things are working as expected.
So let’s rerun the (old) test without and with realm:
linux # radtest user_in_vlan_group1 user_password opnsense.mydomain.de:1812 1 shared_radius_client_secret
Sent Access-Request Id 66 from 0.0.0.0:39874 to 192.168.1.1:1812 length 76
User-Name = "user_in_vlan_group1"
User-Password = "user_password"
NAS-IP-Address = 192.168.1.154
NAS-Port = 1
Message-Authenticator = 0x00
Cleartext-Password = "user_password"
Received Access-Accept Id 66 from 192.168.1.1:1812 to 192.168.1.154:39874 length 53
Message-Authenticator = 0xea33cfcedd27bbf9f381d8815dd55a87
Tunnel-Type:0 = VLAN
Tunnel-Medium-Type:0 = IEEE-802
Tunnel-Private-Group-Id:0 = "1"
linux # radtest user_in_vlan_group1@mydomain.de user_password opnsense.mydomain.de:1812 1 shared_radius_client_secret
Sent Access-Request Id 89 from 0.0.0.0:51962 to 192.168.1.1:1814 length 88
User-Name = "user_in_vlan_group1"
User-Password = "user_password"
NAS-IP-Address = 192.168.1.154
NAS-Port = 1
Message-Authenticator = 0x00
Cleartext-Password = "user_password"
Received Access-Accept Id 89 from 192.168.1.1:1814 to 192.168.1.154:51962 length 59
Message-Authenticator = 0x742e9afe8235bf58289ee17f48d95b32
Tunnel-Type:0 = VLAN
Tunnel-Medium-Type:0 = IEEE-802
Tunnel-Private-Group-Id:0 = "3"
Framed-Protocol = PPP
As you can see: We get “Access-Accept
” in both cases, however in the proxied request we’re not getting the VLAN “1” (but “3”, the fallback for unauthorized users, instead). So there’s still something odd here …
…looks like that’s where the proxy settings on the freeradius
side come into play:
Services->FreeRADIUS->Proxy->Realms
:
The solution is to add a realm “mydomain.de
” (but without setting any of the values requested there … took a while to get that right 😉 ). Once set, the above tests yield exactly the same results.
Finally adding some encryption
In order to enable encryption we’ll first need to create a CA and a certificate/key. Here’s how that’s done:
Creating CA and certificate
Add new CA for using with radius:
System->Trust->Authorities
:
Add new CA (e.g. “RadSec CA
“).
Creating new server certificate for radsecproxy
:
System->Trust->Certificates:
Add new certificate “RadSec Cert
” using:
“Type
“: “Server Certificate
“
“Issuer
“: “RadSec CA
“
And make sure that “Common Name
” matches the server’s hostname or IP that you’ll use from the client (as my Unifi AP only allows IPs I’ll go for “192.168.1.1
” here).
Modifying radsecproxy to use TLS
Next we’ll have to put that CA / certificate in use:
Services->RadSecProxy->TLS
:
Add newly created certificate:
“Unique name
“: “radsecservercert
“
“CA-Certificate
“: “RadSec CA
“
“This server's certificate
“: “RadSec Cert
“
Services->RadSecProxy->Clients
:
Edit the existing client:
“Type
“: change to “TLS
“
“Secret
“: leave blank or use TLS default “radsec
“
“TLS-Config
“: change to “radsecservercert
“
Modifying radsecproxy client settings to use TLS
In a TLS setup the client does authenticate using a certificate, so we’ll need to create one for each client:
System->Trust->Certificates
:
Add new certificate “RadSec Cert
” using:
“Type
“: “Client Certificate
“
“Issuer
“: “Radius Client 1
“
As with the server make sure that “Common Name
” matches the client’s hostname or IP that you’ll use (my Unifi AP has the IP “192.168.1.1
61″ so I’ll take that one).
No let’s tell radsecproxy
that our client will talk TLS in the future:
Maybe I should mention, that only if a matching client is configured the daemon will open the ports (defined in the General
section).
And another thing to save you some time: It currently is not possible in OPNsense to offer different protocols (UDP/TCP/TLS/DTLS) for the same client: OPNsense does not allow multiple clients with the same IP/Net settings (validation failure: UniqueConstraints). I hadn’t expected that, but maybe there’s some good reason for that.
Modifying the Unifi Access Point
Settings->Profiles->RADIUS
:
Enable “TLS
“
Upload “Radius Client 1
” certificate and key and “RadSec CA
” certificate.
“Authentication Servers
“: enter “IP Address
” (192.168.1.1), “Port
” (2083) and “Shared Secret
” (radsec) – and don’t forget to press “Add” in the end.
Keep “Radius Accounting Servers
” empty for now).
Setting up a WPA2 enterprise client
EAP method: TTLS
Phase-2 auth: PAP
CA-Certificate: <accept on first connect>
Identity: marcel@mydomain.de
Anonymous identity: marcel@mydomain.de (or leave blank, "anonymous" does not work)
Passwort: <users AD password>