Setting Up 802.1x Authentication with Debian Linux and FreeRadius Part 1

by Tobias Rice
Version 1.1 (5.4.2008 – Simplified/corrected certificate creation)

Integrating wireless networking in today’s security conscious environment has its many challenges, but that doesn’t mean it can’t be done and done well. With the failure of early security schemes such as WEP, LEAP, etc… many enterprises have opted to not deploy wireless or wait until the technology matured to the point where wireless networking was a safe, viable solution. As better encryption standards such as WPA/TKIP and WPA2/AES have become available, the viability of adding secure wireless to the enterprise has once again become an option. Another challenge of deploying wireless in the enterprise has been that of scalability. Pre shared keys are a bad idea in the enterprise since you can not easily change a key if a laptop is stolen or a user is terminated without reconfiguring every device in the environment. Since most large enterprises have a centralized user database such as LDAP, Active Directory, or RADIUS, it is much better to have access to the wireless based on a user’s identity. If a laptop is stolen it will not be able to connect to the network without knowledge of a valid account. Or if a user is terminated it doesn’t affect any other user’s access to the network. Enter 802.1x. Although not new, 802.1x bridges the gap between security and scalability for wireless in the enterprise. In this tutorial we will be leveraging open source software to setup our authentication infrastructure using Debian Linux and FreeRADIUS. With these components in place we can access various user databases (and/or use the local users file within FreeRADIUS) securely via a variety of EAP protocols such as EAP-TLS, EAP-TTLS, PEAP, etc… In Part 1 of this article we will compile, install, and configure FreeRADIUS with support for EAP-TLS and PEAP with FreeRADIUS’ local user database. We will initially use the example certificates that come with FreeRADIUS until we are sure that everything is working properly, then create our own certificate infrastructure for use with PEAP. In future parts of this article we will tie FreeRADIUS into other databases such as OpenLDAP, setup our own PKI, and use EAP-TLS for authentication.
So let’s get started!

We’ll assume you’ve already installed Debian Linux, which at the time of this article is 4.0r2 (Etch) on your server. Typically installing software on Debian is as easy as “apt-get install freeradius” but since OpenSSL’s license doesn’t comply with Debian’s adherence to the GPL we must compile our own deb packages with support for EAP-TLS and PEAP. But fear not, it is extremely easy to make our own custom packages. For non-Debian users you can skip this section.
First we’ll need a place to work, so I created a directory:

mkdir /usr/src/freeradius && cd /usr/src/freeradius

Next we need to fetch our source and get any dependencies, so update your sources and enter the following commands:

apt-get update
apt-get build-dep freeradius
apt-get install libssl-dev fakeroot
apt-get source freeradius

This should have downloaded the FreeRADIUS source code for us, so now we’ll have to make a few changes to tell our compiler to build it with the EAP modules we’ll be using. First edit /usr/src/freeradius/freeradius-1.1.3/debian/control and remove libssl-dev from Build-Conflicts: and add it to the end of Build-Depends: line. Your file should look like this:

Build-Depends: debhelper (>= 5), libltdl3-dev, libpam0g-dev, libmysqlclient15-dev | libmysqlclient-dev, libgdbm-dev, libldap2-dev, libsasl2-dev, libiodbc2-dev, libkrb5-dev, snmp, autotools-dev, dpatch (>= 2), libperl-dev, libtool, dpkg-dev (>= 1.13.19), libssl-dev
Build-Conflicts:

Next you’ll need to add descriptions for your EAP modules, so enter the following at the end of the file:

Package: freeradius-eaptls
Architecture: any
Depends: freeradius (= ${binary:Version}), ${shlibs:Depends}
Description: eap-tls module for FreeRADIUS server
Debian will not provide a binary version of the rlm_eap_tls.so library. This
module is required if you want to use EAP/TLS authentication, commonly used
for WiFi access points.

Package: freeradius-eappeap
Architecture: any
Depends: freeradius (= ${binary:Version}), ${shlibs:Depends}
Description: eap-peap module for FreeRADIUS server
Debian will not provide a binary version of the rlm_eap_peap.so library. This
module is required if you want to use EAP/PEAP authentication, commonly used
for WiFi access points.

Save and exit this file.

Next we’ll edit /usr/src/freeradius/freeradius-1.1.3/debian/rules. Find and comment our the “buildssl=” and “moduleslist=-“ lines and add the following lines:

buildssl=–without-rlm_otp –without-rlm_sql_postgresql –without-snmp
modulelist=krb5 ldap sql_mysql sql_iodbc eap_peap eap_tls

Save and exit.

Now enter the following commands:

echo “usr/lib/freeradius/rlm_eap_tls*.so” >/usr/src/freeradius/freeradius-1.1.3/debian/freeradius-eaptls.install
echo “usr/lib/freeradius/rlm_eap_peap*.so” > /usr/src/freeradius/freeradius-1.1.3/debian/freeradius-eappeap.install

Next let’s create /usr/src/freeradius/freeradius-1.1.3/debian/freeradius-eaptls.postinst and enter the following:

#! /bin/sh

set -e

case "$1" in
 configure)
       if [ -x "`which invoke-rc.d 2>/dev/null`" ]; then
         invoke-rc.d freeradius restart
       else
         /etc/init.d/freeradius restart
       fi
       ;;
 abort-upgrade)
       ;;
 abort-remove)
       ;;
 abort-deconfigure)
       ;;
esac

#DEBHELPER#

Now we’ll create /usr/src/freeradius/freeradius-1.1.3/debian/freeradius-eappeap.postinst and add the following to it:

#! /bin/sh

set -e

case "$1" in
 configure)
       if [ -x "`which invoke-rc.d 2>/dev/null`" ]; then
         invoke-rc.d freeradius reload
       else
         /etc/init.d/freeradius reload
       fi
       ;;
 abort-upgrade)
       ;;
 abort-remove)
       ;;
 abort-deconfigure)
       ;;
esac

#DEBHELPER#

Now that the hard part is finished let’s compile our deb packages. Enter the following command:

cd /usr/src/freeradius/freeradius-1.1.3/
dpkg-buildpackage -rfakeroot -uc -us

If all went well you should now have several of .deb packages in /usr/src/freradius, so let’s install them by entering the following:

dpkg -i freeradius_1.1.3-3_i386.deb
dpkg -i freeradius-eaptls_1.1.3-3_i386.deb
dpkg -i freeradius-eappeap_1.1.3-3_i386.deb

Check to see if FreeRADIUS compiled and installed correctly by issues the following command:

ps aux | grep freeradius

And you should see something similar to this:

freerad 29998 0.0 0.8 44620 2224 ? Ssl 00:55 0:00 /usr/sbin/freeradius

If not start FreeRADIUS in debug mode as root and look for any clues to why things are not working properly:

freeradius –X

Also check /usr/lib/freeradius and ensure that the rlm_eap_peap-1.1.3.so and rlm_eap_tls-1.1.3.so modules exist.

Now to configure FreeRADIUS

First we’ll edit /etc/freeradius/radiusd.conf
NOTE: When editing the configuration files be sure that every open bracket ({) has a corresponding ending bracket (}) or you will break FreeRADIUS!

Find the mschap stanza under MODULES and configure it with the following parameters:

mschap {
                authtype = MS-CHAP
                use_mppe = yes
                require_encryption = yes
                require_strong = yes
 }

Next verify the authorize stanza includes these parameters:

preprocess
mschap
suffix
eap
files

Now verify that the authenticate stanza is configured like this:

authenticate {
	#  MSCHAP authentication.   
 	Auth-Type MS-CHAP {
mschap
}
#  Allow EAP authentication.
         eap
}

Now we have to add a client to the clients.conf. By client we mean an authenticator such as an access point (AP) or a wireless controller. For this example we’ll use my Juniper SSG5’s address of 192.168.44.129. Add the following stanza to the clients.conf:

client	192.168.44.129 {
	secret = test123
	shortname = Juniper
}

Next we’ll configure our server to support PEAP by editing /etc/freeradius/eap.conf.

First change the default_eap_type in the eap stanza to look like this:

default_eap_type = peap

Because PEAP needs to support our example certificates uncomment the tls stanza as well as the following parameters.

tls {
private_key_password = whatever
private_key_file = ${raddbdir}/certs/cert-srv.pem
certificate_file = ${raddbdir}/certs/cert-srv.pem
CA_file = ${raddbdir}/certs/demoCA/cacert.pem
dh_file = ${raddbdir}/certs/dh
random_file = ${raddbdir}/certs/random
}

Next find and uncomment the peap stanza and the following parameter:

default_eap_type = mschapv2

Now add a test user in the /etc/freeradius/users file so we can test the system. Add the following:

“tobias” User-Password == “password123″

Restart FreeRADIUS with the following command:

/etc/init.d/freeradius restart

Now if you’ve done everything correctly you should be able to authenticate with your test user with the following command:

radtest tobias password123 localhost 0 testing123

You should see:

ending Access-Request of id 170 to 127.0.0.1 port 1812
	User-Name = "tobias"
	User-Password = "password123"
	NAS-IP-Address = 255.255.255.255
	NAS-Port = 0
rad_recv: Access-Accept packet from host 127.0.0.1:1812, id=170, length=20

At this point everything should be working, although you would have to export your CA’s certificate to your PEAP clients so they would trust the server certificate being used by FreeRADIUS. The certificates we are currently using are there only to test with and should not be used for production. Next I’ll explain how to setup your own certificate authority (CA) and create your own certificates.

First we’ll need to install OpenSSL and since we’ll need to generate some complex passwords we’ll also install PWGen the password generator.

apt-get install openssl pwgen

OpenSSL uses a defaults file, /etc/ssl/openssl.cnf, that we’ll backup and edit to save us some time when we start generating our certs.

cp /etc/ssl/openssl.cnf /etc/ssl/openssl.cnf.bak

Now edit /etc/ssl/openssl.cnf and find this line:

dir =./demoCA

and change to:

dir =/etc/freeradius/eap/eapCA

This is the location were I’ll be creating the new CA. You might want to look through the rest of the file and edit the defaults to your environment. Here are some of the changes that I made to my openssl.cnf.

-countryName_default = AU
+countryName_default = US

-stateOrProvinceName_default = Some-State
+stateOrProvinceName_default = Oregon

+localityName_default = Portland

-0.organizationName_default = Widget ltd
+0.organizationName_default = Fat of the LAN

Now create and change to the directory that all of our certificates and CA will exist:

mkdir /etc/freeradius/eap && cd /etc/freeradius/eap

We will use one of OpenSSL’s included scripts to generate our CA, but you’ll want to customize it a bit before we use it so we’ll make a copy of it in our certificate directory.

cp /usr/lib/ssl/misc/CA.pl /etc/freeradius/eap

Next we have to edit CA.pl to tell it where to create our CA. Open it and change the following line:

CATOP=./demoCA

to:

CATOP=/etc/freeradius/eap/eapCA

Your CA is at the heart of your certificate infrastructure so it is important to protect it once you’ve generated it as well as use a strong password for it. I’ll generate a nice random 25 character password with pwgen. Be sure to record this password as you’ll need it each time you sign a certificate.

pwgen 25 1
aem5xahheethohP5Woh5Eb3ph

Now let’s run the script from within the /etc/freeradius/eap directory.

cd /etc/freeradius/eap
./CA.pl –newca

Answer all of the questions based on your environment and use the password you just created when prompted. When the script finishes you’ll have your own CA in /etc/freeradius/eap/eapCA. The next thing we need to do is create a server certificate for FreeRADIUS and sign it with our new CA.

./CA.pl –newreq-nodes

We should now have a new key pair as well as a signing request ready to send to our CA.
A quick note on compatibility. If you plan to use any of these certificates on Windows clients you’ll need to add XP extensions to the certificates you generate. The xpextensions file is included with Debian’s FreeRADIUS packages and I’ll include it in the appendix for our non-Debian readers. Just make a copy of it in our certificate directory.

cp /usr/share/doc/freeradius/examples/xpextensions /etc/freeradius/eap

Now let’s use our CA key to sign the FreeRADIUS’ certificate request, entering the CA’s password when prompted:

./CA.pl –sign (Optionally add -extensions xpserver_ext -extfile /etc/freeradius/eap/xpextensions)

Now that all of the certificates we need are generated, we need to create a couple of files needed for keying material and tell FreeRADIUS to use the new certs. To create the dh and random files, issue the following command:

openssl dhparam -check -text -5 512 -out dh
dd if=/dev/urandom of=random count=2
chmod 640 random newcert.pem newkey.pem newreq.pem dh

Now open your /etc/freeradius/eap.conf file, find the tls stanza, and change to reflect the new certificates we created.

private_key_file = /etc/freeradius/eap/newkey.pem
certificate_file = /etc/freeradius/eap/newcert.pem
CA_file = /etc/freeradius/eap/eapCA/cacert.pem
dh_file = /etc/freeradius/eap/dh
random_file = /etc/freeradius/eap/random

And while we’re at it, uncomment the following lines:

fragment_size = 1024
include_length = yes

Restart FreeRADIUS and copy your CA’s certificate (/etc/freeradius/eap/eapCA/cacert.pem) to your clients. Configure your clients’ supplicant for your new PEAP enabled SSID, configure your AP to use 802.1x and your new FreeRADIUS server and you’re good to go!