WPA-Enterprise with Open Source Software
by John Lucas
I. Introduction
The "smbldap-installer" script by Matt Oquist and David Trask (http://majen.net/smbldap/) has gone a long way
toward establishing an Open Source, cross-platform, single sign-on infrastructure for Linux and Windows
workstations. This script has taken the sting out of installing and configuring a Samba-based Windows NT-style
domain with credentials stored in OpenLDAP. Having once set up such an environment from scratch without such a
wonderful tool (back when Windows NT was the current Microsoft release), I appreciate what a monumental step
forward "smbldap-installer" is.
This document describes how an NT Domain set up with "smbldap-installer" can be leveraged to provide
authentication for "WPA-Enterprise" (aka 802.11i RSN) Wifi security.
Wifi (aka 802.11) has become a popular and nearly ubiquitous technology in recent years. One common problem
with many Wifi implementations is a lack of adequate security. There are many methods that can be used to
secure Wifi, but since about 2004 there has been an IEEE 802.11 standard that provides "AAA" (Authorization,
Authentication, and Accounting) and transport privacy via stong encryption. This standard is best known as
"WPA", officially known as IEEE 802.11i. There are two common implementations of 802.11i known as "Personal"
(aka PSK for pre-shared key), and "Enterprise". WPA Personal is suitable for home use or with a small group of
trusted users; since all users share the same "pre-shared key", it tends to get passed around and it is
possible for users to "see" (decrypt) each other's net traffic. WPA Personal does not scale well and is
unsuitable for larger installations.
WPA "Enterprise" uses a RADIUS (Remote Authentication Dial-in User Service) server to provide authentication of
users and unique encryption keys for each user. As the name implies, this implementation is designed to support
large Wifi deployments. This document describes how to set up WPA Enterprise with Open Source software and
low-end hardware.
The model deployment I had in mind when choosing to begin this project was deploying Wifi in a K-12 school. A
natural limit for the number of Wifi clients is 250: a class C subnet can have 254 IP addresses and a common
deployment scenario is to isolate Wifi traffic onto a separate subnet (VLAN) connected to the main LAN via a
firewall. I think 250 is a good starting value anyway. To support 250 *simultaneous* users would require a
minimum of 10 Access Points, probably closer to 20 in the real world. When deploying LDAP, you should have at
least one "master" and one "slave" server for redundancy. If you install RADIUS on each LDAP server and split
the authentication load, I don't think there would be any issue with supporting WPA-Enterprise for 250
simultaneous users and you would have RADIUS redundancy that way too.
Caveat: The system described here is a testbed, not a production network.
II. Objectives
I set several goals for this exercise that I consider important, mostly to hold down costs and simplify the
installation/configuration and administration process. These goals are:
- Use the LDAP tree set up through "smbldap-installer" w/o mods.
- Use only Open Source software
- Use commonly available and inexpensive Wifi Access Points
- Use methods that work across platforms (Win, Mac & *NIX)
- Use "Networkmanager" as the Linux 802.1X supplicant
- Avoid the generation/distribution of client certificates
The various pieces integrated into this demo system were:
Server Pieces:
SMB-LDAP server: Fedora Core 5 (VMware virtual machine)
LDAP: openldap-D2.3.19-4
Samba: samba-3.0.24-1.fc5
RADIUS server: freeradius-1.0.5-1.2
smbldap-installer: v3.1
PKI: openvpn-2.1-0.17.rc2.fc5 (only used to generate certs)
Encryption Libs: openssl-0.9.8a-5.4
Client Pieces:
Dell Inspiron 6400 laptop w/ Intel 3945 802.11 a/b/g Wifi NIC
Fedora Core 6 OS with KDE 3.5.6-0.1
NetworkManager:
NetworkManager-0.6.4-5.fc6
NetworkManager-vpnc-0.6.4-2.fc6
NetworkManager-glib-0.6.4-5.fc6
NetworkManager-gnome-0.6.4-5.fc6
NetworkManager-openvpn-0.3.2-7.fc6
knetworkmanager-0.1-0.6.svn20061113.fc6
Wifi NIC packages (from Freshrpms for FC6):
ipw3945-firmware-1.13-1
dkms-ipw3945-1.2.0-1
ipw3945d-1.7.22-4
Access Point
LinkSys WAP54G firmware version 3.04
Whenever possible packages were installed via "yum" and no source compilation was required.
III. Server Setup
I started with a minimal Fedora Core 5 installation setup as a Samba-NT Primary Domain Controller using the
"smbldap-installer" script, which automatically installed the needed packages and their dependancies,
configured OpenLDAP and Samba and left me impressed with the work that went into that script. I named my domain
"Minibox.net" and other than adding the /opt/IDEALX/bin to the execution PATH, the only other change was to add
some access control rules to the "slapd.conf" file (more about that later). This server is a virtual machine
using VMware Server v1.0 with it's NIC bridged to my LAN and named "vNAS" (since I use this as a virtual file
server (Network Attached Storage) too).
Once I had this PDC/NAS server up and tested, I added "FreeRADIUS" from the updates repository via "yum
install" and then went in search of information about how to configure FreeRADIUS to implement WPA-Enterprise
with LDAP. I settled on "PEAP" as the target 802.1X authentication method, since it can be used by Linux,
Windows and Mac "natively" (without third party add-ons for the proprietary systems) and it does not require
client-side certificates (two of my initial goals).
I didn't find a comprehensive "HowTo", but I did find enough to figure out the missing pieces. The two HowTos
closest to my needs were:
http://vuksan.com/linux/dot1x/802-1x-LDAP.html#Set_up_FreeRADIUS
By Vladimir Vuksan. This almost covered the RADIUS-LDAP piece and referred to:
http://tldp.org/HOWTO/html_single/8021X-HOWTO/#confradius
By Lars Strand, which covered the EAP-PEAP parts (but didn't use LDAP). The Vuksan approach required extending
the OpenLDAP schema with the FreeRADIUS schema and adding attributes to user entries. I wanted to leave the
schema alone so that the smbldap tools could be used without modification (another of my goals).
FreeRADIUS Setup
I made two trivial changes to the "ldap" module in the "radiusd.conf" file from the Vuksan HowTo: I used the
"uid" LDAP attribute as the "access_attribute" as suggested in the text:
access_attr = "uid"
and also added a vital "password_attribute" missing from the Vuksan HowTo:
password_attribute = "userPassword"
Without this addition, authentication will fail, since RADIUS requests require both ID and Password. This might
seem obvious, but the actual PEAP method performs comparisons on the "sambaNTPassword" attribute via additional
"checkItem" mappings (more later). But without the request supplying a value pair (ID/Password) you don't get
that far. The revised "ldap module" configuration in the "radiusd.conf" file looks like this:
ldap {
server = "127.0.0.1"
identity = "uid=onex,ou=Users,dc=Minibox,dc=net"
password = "SuperSecret"
basedn = "dc=Minibox,dc=net"
start_tls = no
base_filter = "(objectclass=posixAccount)"
filter = "(uid=%{Stripped-User-Name:-%{User-Name}})"
access_attr = "uid"
password_attribute = "userPassword"
dictionary_mapping = ${raddbdir}/ldap.attrmap
authtype = ldap
ldap_connections_number = 5
timeout = 4
timelimit = 3
net_timeout = 1
}
The entire "radiusd.conf" file is included in the accompanying tarball. I added a dummy user that has read
privleges to the three password attributes in LDAP, as detailed in the Vuksan HowTo. Another change was to
alter the "base_filter" from "radiusprofile" to "posixAccount" (since the former objectclass was not added to
OpenLDAP) and added "filter" to supply stripped user IDs. This module completely replaced the "ldap" stanza in
the generic radiusd.conf file. I am not planning to use this RADIUS server for any other purpose other than
Wifi authentication. I don't need TLS talking to the LDAP server since they are on the same host and
communicate over the localhost interface. If RADIUS and OpenLDAP were on different hosts, you should add
certificates to both RADIUS and LDAP servers and set "start_tls" to "yes".
Next, we need to make sure that we have both "eap" and "ldap" listed in the "authorize" and "authenticate" stanzas
of the "radiusd.conf" file:
authorize {
preprocess
chap
mschap
suffix
ldap
files
eap
}
authenticate {
Auth-Type PAP {
pap
}
Auth-Type CHAP {
chap
}
Auth-Type MS-CHAP {
mschap
}
unix
Auth-Type LDAP {
ldap
}
eap
}
To finish off the LDAP parts of FreeRADIUS setup, I modified the "ldap.attrmap" that is included by
radiusd.conf. This file maps RADIUS attributes to LDAP attributes and by default uses the FreeRADIUS LDAP
schema extentions, which I didn't use. I did need four items mapped, and I eliminated everything else. My
complete ldap.attrmap file looks liks this:
checkItem User-Password userPassword
checkItem LM-Password sambaLMPassword
checkItem NT-Password sambaNTPassword
checkItem SMB-Account-CTRL-TEXT sambaAcctFlags
checkItem $GENERIC$ radiusCheckItem
replyItem $GENERIC$ radiusReplyItem
The critical ones are are "userPassword" to provide the required ID/Password value pair, and "sambaNTPassword"
used by the actual PEAP authentication.
FreeRADIUS EAP Setup
The last part of FreeRADIUS setup was configuring EAP-PEAP. PEAP requires that the "authenticator" (FreeRADIUS
in this case) have valid public key encryption certificates to enable TLS and provide the encrypted tunnel in
which "mschapv2" authentication can safely take place. The MD4 NT password hash is a "password equivalent" and
should not appear unprotected over the air (or wire for that matter).
In order to most easily generate and manage certificates, I used the Certificate Authority scripts supplied
with OpenVPN (http://openvpn.net/). I needed to sign the certificates and supply the public root certificate
for the CA. So I followed the OpenVPN directions to create a new CA and generate and sign a server certificate
for FreeRADIUS and for the CA. The root CA cert can be distributed to your clients to (optionally) verify the
server certificate (recommended). If you have a Windows 2000 or 2003 server, you should probably use
certificates from your PKI for your clients; I understand that Windows clients are picky that way. I don't have
a Windows server (or client), so I took the open source path.
The certificates are part of the "tls" EAP method, which is the "outer" authentication method used by PEAP,
which uses "mschapv2" for the "inner" authentication.
Next step was to modify the "eap.conf" file to refer to our new certificates and set the default EAP type. Here
is my complete "eap.conf" file:
eap {
default_eap_type = peap
timer_expire = 60
ignore_unknown_eap_types = no
cisco_accounting_username_bug = no
md5 {
}
leap {
}
gtc {
auth_type = PAP
}
tls {
private_key_file = ${raddbdir}/certs/vnas.key
certificate_file = ${raddbdir}/certs/vnas.crt
CA_file = ${raddbdir}/certs/demoCA/vnas-ca.crt
dh_file = ${raddbdir}/certs/dh
random_file = ${raddbdir}/certs/random
fragment_size = 1024
}
peap {
default_eap_type = mschapv2
}
mschapv2 {
}
}
Notice that the certificates and keys are in the "tls" module. Even though we are using PEAP, the outer
authentication calls the "tls" module to set up the encrypted tunnel used for inner authentication via
PEAP/mschapv2.
We need to make some changes in the "mschap" stanza in "radiusd.conf" in order to have the "mschapv2" work as we intend (from the Strand HowTo):
mschap {
authtype = MS-CHAP
use_mppe = yes
require_encryption = yes
require_strong = yes
}
Only two more pieces to the FreeRADIUS setup. The "users" file is simplified to two entries: One entry is for
my chosen anonymous user "nobody", which is used as a dummy user to set up the TLS tunnel without revealing the
real user identity "in the clear", i.e. before the encrypted tunnel is set up. The other entry is used to
perform LDAP authentication for all other user IDs.
nobody Auth-Type := System
DEFAULT Auth-Type := LDAP
This setup will allow anyone with a valid "uid" and password to authenticate. If you wanted to restrict which
users can use Wifi, you could explicitly enter them in the "users" file, so that if they aren't listed they
can't authenticate. Something like this:
jlucas Auth-Type := LDAP
vvuksan Auth-Type := LDAP
lstrand Auth-Type := LDAP
DEFAULT Auth-Type := System
Since their isn't an sambaNTPassword in the local /etc/passwd file, without a matching "Auth-Type := LDAP"
entry for their ID, innner authentication will fail.
The last part of FreeRADIUS setup is the "clients.conf" file, included in radiusd.conf to allow RADIUS clients
to communicate with the RADIUS server. In this demo setup, I have only two clients: the local RADIUS host (for
testing) and my Wifi Access Point. These are easy. Here is my complete "clients.conf" file:
client 127.0.0.1 {
secret = testing123
shortname = localhost
}
client 192.168.0.11 {
secret = AnotherSuperSecretPassword
shortname = wap54g
nastype = other
}
The "secret" entry is the shared secret between the Access Point and the RADIUS server. Normally this would be
pretty insecure, but by communicating in the EAP-TLS tunnel set up during PEAP outer authentication, it is
considered secure. You need to use a very good, long secret here, and you will need to enter it in the Access
Point setup too.
Once you get to this point, you should test your RADIUS-LDAP setup by using "radtest" on the RADIUS host (see
man page for radtest):
radtest jlucas MyPassword localhost 0 testing123
If you can't get an "Access-Accept", check your configuration before proceeding with your Wifi setup.
Running radiusd in the foreground is a great help in troubleshooting the authentication process:
radiusd -X -f
IV. Wifi Access Point Setup
Before implementing any advanced Wifi security setup, make sure you can use Wifi on a completely "open" Access
Point (open authentication, no encryption). Save yourself some trouble by making sure you don't have any basic
Wifi problems.
My test setup uses a LinkSys WAP54G with firmware v3.04 and the Wifi security setup is very straightforward and
easy. After logging into the built-in web configuration interface (from the "wired" side of the AP), navigate
to the "Wireless Security" setup screen and select:
Security Mode: WPA Enterpise
Encryption: AES (use TKIP for widest compatibility)
RADIUS Server: IP address of your RADIUS Server
Port: 1812
Shared Secret: AnotherSuperSecretPassword (match "clients.conf" file)
Key Renewel: 300 secs. (default)
One drawback to using a low end Access Point is that it doesn't support RADIUS accounting. If you need
accounting you would need something like the Proxim AP-700 for $329 instead of a Linksys WAP54G for $69. So in
this case I missed one of my goals by failing to provide the third "A" in AAA. The "/var/log/radius/radius.log"
file does contain authentication information, but there is no record of dis-associations with the AP so session
duration is not known.
V. NetworkManager Setup
My test setup is limited to one Wifi client: I only have one Wifi NIC that is capable of WPA security and it is
the built-in NIC in my Dell laptop, so I am limited to testing Linux (I hope to borrow a WinXP laptop to test
further). I very carefully selected my laptop hardware so that I could use Wifi with Linux without resorting to
the "NDIS-wrapper" and would be compatible with NetworkManager.
I installed the Intel 3945 drivers and firmware from FreshRPMs following the procedure described in this HowTo
by Paul Wayper:
http://www.mabula.net/dell_inspiron_6400.html
I use KDE as my primary desktop, so I used the "knetworkmanager" GUI tool to configure Networkmanager. In the
"Connect to Other Wireless Network..." dialog, fill in:
ESSID: Minibox (my SSID, use yours instead)
Check the Encryption box
Encryption: WPA Enterprise
EAP Method: PEAP
Identity: jlucas (your user ID)
Password: MyPassword (your password)
Anonymous Identity: nobody (dummy user used in outer authentication)
WPA Version: 1 (there is no version 2 of WPA Enterprise)
CA Certificate File: path to your root CA certificate for server
The CA certificate file is optional but highly recommended. It allows
the client to authenticate the server.
The other fields can be left blank, they are used for other EAP methods
(EAP-TLS uses both client and server certificates).
Hit the "Connect" button and cross your fingers. You should see the gears turning and if you connect
successfully, you will see the 4 blue bars. You should also get a prompt from KWallet to enter your Wallet
password to store kneetworkmanager credentials.
Caveat: I have not been successful in getting knetworkmanager to save my credentials in kwallet. It worked when
I used "WPA Personal" security, but not with the more complicated setup. In fact I have had to delete the
"Minibox" network and re-attach each time I use it. This seems to be a common failing with Networkmanager
(knetworkmanager handing off to kwallet), but it is frustrating. At least I don't have to use "regedit" to
clear things out (as you would with Windows). I don't know if the Gnome Networkmanager applet is any better. I
am sticking with KDE and so I'll put up with the hassle and hope that in future knetworkmanger is improved.
VI. Notes
Security on both RADIUS and LDAP needs to be tightened up.
By default the "smbldap-installer" scripts allow all users to read the 3 password attributes (userPassword,
sambaLMPassword, and sambaNTPassword). This is insecure. I added some basic access control to the OpenLDAP
"/etc/openldap/slapd.conf" file:
access to attrs=userPassword,sambaNTPassword,sambaLMPassword
by dn="uid=onex,ou=Users,dc=minibox,dc=net" read
by dn="uid=root,ou=Users,dc=minibox,dc=net" write
by self write
by * auth
access to *
by dn="uid=root,ou=Users,dc=Minibox,dc=net" write
by * read
This allows the user "onex" to read the password attributes (needed for the "ldap" module in FreeRADIUS). The
"root" user is the only one able to create users with the smbldap-tools scripts. I am still trying to allow the
"Domain Users" group members the same access, but somehow the documented syntax doesn't seem to work (or I am
misunderstanding it).
You should also generate and configure certificates for OpenLDAP so that LDAP queries can be performed in a TLS
tunnel. The default smbldap-installer script does not do this for you. Additionally on a production system I
think I would create an old-style SSL tunnel for LDAP on port 636 via "stunnel" invoked from xinetd, for those
LDAP clients that can't do STARTTLS. Don't forget to restrict access to LDAP through tcpwrappers too.
It is important to protect the configuration files with restriced permissions, especially the ones with
passwords and private keys in them. Something like:
chown -R root:radiusd /etc/raddb chmod -R o-r,o-w,o-x ./etc/raddb
chown -R root:ldap /etc/openldap chmod -R o-r,o-w,o-x /etc/openldap
I find RADIUS extremely powerful, but arcane. I hadn't set up a RADIUS server in over a decade prior to this
project (my last RADIUS setup still used port 1645, that's how long ago it was). Add the novelty (for me at
least) of EAP and PEAP and there are lacuna in the available documentation. Here are some resources you can
draw on:
Books:
"802.11 Wireless Networks the Definitive Guide" 2nd Edition by Matthew S.Gast, O'Reilly copyright 2005
"LDAP System Administration" by Gerald Carver, O'Reilly copyright 2003
"RADIUS" by Jonathan Hassell, O'Reilly copyright 2003
Links:
http://vuksan.com/linux/dot1x/802-1x-LDAP.html#Set_up_FreeRADIUS
http://tldp.org/HOWTO/html_single/8021X-HOWTO/#confradius
http://majen.net/smbldap/
http://www.mabula.net/dell_inspiron_6400.html
http://openvpn.net/