The company with no Active Directory

A few months ago I was called to a presales meeting at a new customer. The customer was moving into new facilities and wanted secure, stable and fast wifi. Not an unusual project. On my way to the meeting I was thinking EAP-TLS, using a Microsoft AD PKI and enrolling certificates using GPO. Should be fairly easy.

But leaving the meeting my initial ideas were shot dead. The customer didn’t have a Microsoft AD. For central user account administration they were using Google Apps. This was a new task for me.

After searching the web for solutions I found two cloud based solution that offers RADIUS authentication using Google Apps as a backend.

Cloudessa and Ironwifi.

After trying to contact Cloudessa multiple times I gave up and was left with Ironwifi.

Both Cloudessa and Ironwifi uses the same concept. They have a RADIUS service that support EAP-TTLS. I have never found a great use case for EAP-TTLS until now.

EAP-TTLS builds a secure tunnel from the client to the authentication server. Inside this tunnel multiple protocols are supported including PAP. I know what you are thinking. Old-send-username-and-password-in-clear-text PAP. But this is exactly what is needed for Ironwifi to use Google Apps as a backend.

The client starts the EAP session with the authentication server validating the authentication server using the servers certificate. Using this the secure tunnel is setup. Inside the tunnel the client sends the username and password in clear text. The Ironwifi RADIUS server takes the username and password and validate them towards the Google Apps API. If Google Apps returns an OK the Ironwifi RADIUS server returns a Access-Accept to the authenticator. If Google Apps returns an Error the Ironwifi RADIUS server returns a Access-Reject.

The only drawback to this solution is that most supplicants only support PEAP and EAP-TLS right out of the box. Fortunately Ironwifi has a profile generator to help you setup the different clients.

This customer mostly used MacOS and the cfg files setup worked like a charm.

I did have some concerns about MITM attack. What would happen if someone sets up a SSID and the supplicant was misconfigured or if the certificate on the RADIUS server wasn’t trusted. I decided to test with a freeradius-wpe modified to allow any authentication attempt.

My first finding was that the client didn’t show a “Wrong certificate, do you want to continue anyway”. It simple didn’t work if the certificate configured in the supplicant wasn’t the one presented. This kind of takes the edge of the MITM possibilities.

My second finding was that freeradius-wpe is a wonderful and a bit evil RADIUS server.

From the freeradius-wpe logfile:

Virtual server inner-tunnel received request
 User-Name = "cisco1.Jensen@flowstop.dk"
 User-Password = "bubber1234567"
 FreeRADIUS-Proxied-To = 127.0.0.1
WARNING: Outer and inner identities are the same. User privacy is compromised.
server inner-tunnel {
 # Executing section authorize from file /etc/freeradius-wpe/3.0/sites-enabled/inner-tunnel
 authorize {
 policy filter_username {
 if (&User-Name) {
 if (&User-Name) -> TRUE
 if (&User-Name) {
 if (&User-Name =~ / /) {
 if (&User-Name =~ / /) -> FALSE
 if (&User-Name =~ /@[^@]*@/ ) {
 if (&User-Name =~ /@[^@]*@/ ) -> FALSE
 if (&User-Name =~ /\.\./ ) {
 if (&User-Name =~ /\.\./ ) -> FALSE
 if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/)) {
 if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/)) -> FALSE
 if (&User-Name =~ /\.$/) {
 if (&User-Name =~ /\.$/) -> FALSE
 if (&User-Name =~ /@\./) {
 if (&User-Name =~ /@\./) -> FALSE
 } # if (&User-Name) = notfound
 } # policy filter_username = notfound
 [chap] = noop
 [mschap] = noop
suffix: Checking for suffix after "@"
suffix: Looking up realm "flowstop.dk" for User-Name = "cisco1.Jensen@flowstop.dk"
suffix: No such realm "flowstop.dk"
 [suffix] = noop
 update control {
 &Proxy-To-Realm := LOCAL
 } # update control = noop
eap: No EAP-Message, not doing EAP
 [eap] = noop
files: users: Matched entry DEFAULT at line 221
 [files] = ok
 [expiration] = noop
 [logintime] = noop
 [pap] = updated
 } # authorize = updated
 Found Auth-Type = PAP
 # Executing group from file /etc/freeradius-wpe/3.0/sites-enabled/inner-tunnel
 Auth-Type PAP {
pap: Login attempt with password
pap: Comparing with "known good" Cleartext-Password
pap: User authenticated successfully
 [pap] = ok
 } # Auth-Type PAP = ok
 # Executing section post-auth from file /etc/freeradius-wpe/3.0/sites-enabled/inner-tunnel
 post-auth { ... } # empty sub-section is ignored
} # server inner-tunnel
Virtual server sending reply
eap_ttls: Got tunneled Access-Accept
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s