FreeRADIUS EAP/TLS - WinXP HOWTO

Version 1.2
10/30/2002
Raymond McKay
mailto:raymckay@supserv.com

Table of Contents

1) Purpose of this Document
2) Intended Audience
3) EAP/TLS Background
4) Required Software and Hardware
5) Software Installation
6) Certificate Generation
7) FreeRADIUS Configuration
8) Running and Testing FreeRADIUS
9) Access Point Setup
10) XP Client (supplicant) Setup
11) Troubleshooting

REFERENCES

1) Purpose of this Document

This document was created out of my frustration while setting up an EAP/TLS implementation. While available documentation provided some of the core knowledge to build this solution, there were many holes that just were not covered. This document attempts to clear up all that has been unclear on setting up an EAP/TLS solution.

2) Intended Audience

This document assumes that the reader has a administrator level knowledge of Linux and is at least casually familiar with wireless security protocols and terminology.

3) EAP/TLS Background

EAP/TLS is an authentication method that works within the structure of 802.1x. 802.1x is the standard that defines port based security within networking. 802.1x and EAP/TLS have gained much relevance with the growing popularity of wireless networks. Due to the inherent insecure nature of broadcasting data wirelessly, methods are needed to: 1) Authenticate user identity to validate that only valid users are able to connect to the network. 2) Restrict unauthorized individuals from accessing data being transmitted. EAP/TLS accomplishes this through providing secure certificate based authentication and, through extensions, can provide dynamic rotating WEP keys for data encryption. EAP/TLS authentication requires 3 components to function. The supplicant, or client computer, is the device that is requesting access to the network. It must communicate with the authenticator. In the realm of wireless networking, the authenticator is the access point. The supplicant communicates authentication information with the authenticator which forwards the information to the authentication server to validate the information. The authentication server in this scenario is the FreeRADIUS server. If the authentication information is correct, the authentication server communicates to the Authenticator to allow access and normal network traffic may now traverse from the supplicant to the network. Different access points support some different options from here. Some permit an authentication timeout period while some also provide a separate timer for dynamic encryption keying. Consult the documentation for the specific hardware to know what it supports. Dynamic encryption keying and re-keying requires the MPPE extensions within the rlm_eap module in FreeRADIUS. This is currently a part of the CVS version ONLY!!! The release version does not include it.

4) Required Software and Hardware

SOFTWARE

OpenSSL 0.9.6g*
  0.9.7-beta3*
  SNAP-20021027*
FreeRADIUS snapshot-20021028
Windows XP SP1 Recommended (You'll have to buy your own copy...)

*This software package uses strong cryptography, so even if it is created, maintained and distributed from liberal countries in Europe (where it is legal to do this), it falls under certain export/import and/or use restrictions in some other parts of the world.

PLEASE REMEMBER THAT EXPORT/IMPORT AND/OR USE OF STRONG CRYPTOGRAPHY SOFTWARE, PROVIDING CRYPTOGRAPHY HOOKS OR EVEN JUST COMMUNICATING TECHNICAL DETAILS ABOUT CRYPTOGRAPHY SOFTWARE IS ILLEGAL IN SOME PARTS OF THE WORLD. SO, WHEN YOU IMPORT THIS PACKAGE TO YOUR COUNTRY, RE-DISTRIBUTE IT FROM THERE OR EVEN JUST EMAIL TECHNICAL SUGGESTIONS OR EVEN SOURCE PATCHES TO THE AUTHOR OR OTHER PEOPLE YOU ARE STRONGLY ADVISED TO PAY CLOSE ATTENTION TO ANY EXPORT/IMPORT AND/OR USE LAWS WHICH APPLY TO YOU. THE AUTHORS OF OPENSSL ARE NOT LIABLE FOR ANY VIOLATIONS YOU MAKE HERE. SO BE CAREFUL, IT IS YOUR RESPONSIBILITY.

CREDIT INFORMATION: This product includes cryptographic software written by Eric A. Young (eay@cryptsoft.com). This product includes software written by Tim J. Hudson (tjh@cryptsoft.com).

You may have noticed that there are three versions of openSSL needed. As of this time, ALL of them are needed. Here is why. A stable version of openSSL is required to build most of FreeRADIUS. A recent SNAP version of openSSL is required to build the EAP/TLS modules. OpenSSL-0.9.6g does not support the enhanced OID's needed to create certificates that WinXP can use for EAP/TLS authentication (more on that later). Actually any relatively recent stable version of openSSL should be fine for the base openSSL used for the entire system. I do strongly recommend using >=0.9.6g as some SERIOUS security issues have been fixed. In theory, you could just install the beta version of openSSL and the SNAP version to minimize on the different versions installed. I recommend against this as it is not good practice to use a beta version of security software as the primary system wide version in a production environment. It is possible that potential security issues may exist in pre-release versions that may make your system vulnerable. For test systems, installing just the two versions should be fine.

FreeRADIUS requires a recent CVS snapshot for the EAP/TLS module and MPPE dynamic keying extension to work. All the modules are NOT included in the release version at this time.

HARDWARE

On the AP side, the access point used must be able to support 802.1x and EAP/TLS. Linksys and other inexpensive access points will not work at this time. I use ORINOCO AP-2000's for my APs and have also seen others use Cisco Aironet APs. Verify with your preferred hardware vendor to make sure that your AP supports the required protocols. For some APs, a simple flash upgrade may be needed. On the client (supplicant) side, a wireless card capable of 128bit WEP encryption is required.

5) Software Installation

OPENSSL

Download and untar the 3 versions of openSSL. (tar -xzf openssl-<version>.tar.gz

OPENSSL 0.9.6g

Enter the openssl-0.9.6g folder

type "./config --prefix=/path/to/current/openssl shared" (substitute the path to your current openssl install here. For RedHat 8 systems, this is /usr. If you have any other options you want to compile, I leave that up to you.)

type "make"

assuming the make completed successfully type "make install"

OPENSSL SNAP-20021027

Enter the openssl-SNAP-20021027 source folder

type "./config --prefix=/usr/local/openssl shared" (Obviously you don't want to overwrite your stable openSSL install so this SNAP version needs to be installed somewhere else. If you change this path make a note of it as you will need to change the paths I provide in a later part of this HOWTO)

type "make"

assuming the make completed successfully type "make install"

cd to /usr/local/openssl (or wherever you installed this SNAP version) and enter the lib directory.

Verify that libssl.so and libssl.so.0 are sym linked to libssl.so.0.9.8 and that libcrypto.so libcrypto.so.0 are sym linked to libcrypto.so.0.9.8

OPENSSL 0.9.7-beta3

Enter the openssl-0.9.7beta3 source folder

type "./config --prefix=/usr/local/openssl-certgen shared"

type "make"

assuming the make completed successfully type "make install"

cd to /usr/local/openssl-certgen (or wherever you installed this beta version) and enter the lib directory

Verify that libssl.so and libssl.so.0 are sym linked to libssl.so.0.9.7 and that libcrypto.so libcrypto.so.0 are sym linked to libcrypto.so.0.9.7

FREERADIUS

Untar FreeRADIUS (tar -xzf freeradius-snapshot-20021028.tar.gz)

Enter the freeradius-snapshot-20021028.tar.gz

type "./configure --sysconfdir=/etc" (add any specific options you need here see FreeRADIUS documentation for details)

cd to src/modules/rlm_eap/types/rlm_eap_tls

Edit the Makefile in this directory to look like this. Substitute the path to the SNAP version of openssl you installed earlier if different.

# Generated automatically from Makefile.in by configure.
TARGET = rlm_eap_tls
SRCS = rlm_eap_tls.c eap_tls.c cb.c tls.c mppe_keys.c
RLM_CFLAGS = $(INCLTDL) -I../.. -I/usr/local/openssl/include
HEADERS = eap_tls.h
RLM_INSTALL =
RLM_LDFLAGS += -L/usr/local/openssl/lib
RLM_LIBS += -lssl -lcrypto

$(STATIC_OBJS): $(HEADERS)

$(DYNAMIC_OBJS): $(HEADERS)

RLM_DIR=../../
include ${RLM_DIR}../rules.mak

Return to the root of the FreeRADIUS source and type "make"

Assuming the build went without errors type "make install"

If you got any errors at this point chances are the path you supplied in the Makefile is not the correct path to the openssl-SNAP installation include and lib directories.

See Section 7 for more information on configuring FreeRADIUS

 

6) Certificate Generation

First let me note a couple things. If you have a local certificate authority already in place (such as Windows2000 Server) you can generate your certificates there and import them for use with FreeRADIUS. Also, any number of CAs can be stored within the root CA file used by FreeRADIUS. Such options are outside the scope of this document so you should consult documentation for Windows and OpenSSL for more info on these two topics

Assuming everything went well in previous steps you are ready to generate the certificates needed by FreeRADIUS to authenticate. Remember you will need to use openSSL-0.9.7beta3 to generate the certificates. 0.9.6g apparently has an issue that doesn't allow it to generate certificates with the added attributes WinXP needs to identify the certificate as an authentication certificate. If you try to specify those attributes it outputs a "header too long" error during certificate generation. The SNAP version of openSSL supports these attributes but the SNAP version used in this build seems to have some issues with PKCS12 encoding and decoding that generates errors. This is why openSSL-0.9.7beta3 gets used. It generates the certificates properly without generating any errors.

With that said, cd to the openSSL-0.9.7beta3 install directory (/usr/local/openssl-certgen if you used the path specified earlier)

Enter the ./ssl directory

First, I recommend editing your openssl.cnf file to include the default variables you will use. This will save you quite a bit of time and typing later.

Here is an example of how I configured. Obviously, edit the parameters in the [req_distinguished_name] section to match your locale and information

openssl.cnf

#
# OpenSSL example configuration file.
# This is mostly being used for generation of certificate requests.
#

# This definition stops the following lines choking if HOME isn't
# defined.
HOME = .
RANDFILE = $ENV::HOME/.rnd

# Extra OBJECT IDENTIFIER info:
# oid_file = $ENV::HOME/.oid
oid_section = new_oids

# To use this configuration file with the "-extfile" option of the
# "openssl x509" utility, name here the section containing the
# X.509v3 extensions to use:
# extensions =
# (Alternatively, use a configuration file that has only
# X.509v3 extensions in its main [= default] section.)

[ new_oids ]

# We can add new OIDs in here for use by 'ca' and 'req'.
# Add a simple OID like this:
# testoid1=1.2.3.4
# Or use config file substitution like this:
# testoid2=${testoid1}.5.6

####################################################################
[ ca ]
default_ca = CA_default # The default ca section

####################################################################
[ CA_default ]

dir = ./demoCA # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
new_certs_dir = $dir/newcerts # default place for new certs.

certificate = $dir/cacert.pem # The CA certificate
serial = $dir/serial # The current serial number
crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.pem# The private key
RANDFILE = $dir/private/.rand # private random number file

x509_extensions = usr_cert # The extentions to add to the cert

# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
# so this is commented out by default to leave a V1 CRL.
# crl_extensions = crl_ext

default_days = 365 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = md5 # which md to use.
preserve = no # keep passed DN ordering

# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy = policy_match

# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

####################################################################
[ req ]
default_bits = 1024
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert

# Passwords for private keys if not present they will be prompted for
# input_password = secret
# output_password = secret

# This sets a mask for permitted string types. There are several options.
# default: PrintableString, T61String, BMPString.
# pkix : PrintableString, BMPString.
# utf8only: only UTF8Strings.
# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
# MASK:XXXX a literal mask value.
# WARNING: current versions of Netscape crash on BMPStrings or UTF8Strings
# so use this option with caution!
string_mask = nombstr

# req_extensions = v3_req # The extensions to add to a certificate request

[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = CT
countryName_min = 2
countryName_max = 2

stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Connecticut

localityName = Locality Name (eg, city)
localityName_default = Canton

0.organizationName = Organization Name (eg, company)
0.organizationName_default = Vivendi Universal Games

# we can do this but it is not needed normally :-)
#1.organizationName = Second Organization Name (eg, company)
#1.organizationName_default = World Wide Web Pty Ltd

organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = Funnybone Interactive

commonName = Common Name (eg, YOUR name)
commonName_max = 64
commonName_default = Funnybone Wireless CA

emailAddress = Email Address
emailAddress_max = 40
emailAddress_default = rmckay@vugames.com

# SET-ex3 = SET extension number 3

[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20

unstructuredName = An optional company name

[ usr_cert ]

# These extensions are added when 'ca' signs a request.

# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.

basicConstraints=CA:FALSE

# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.

# This is OK for an SSL server.
# nsCertType = server

# For an object signing certificate this would be used.
# nsCertType = objsign

# For normal client use this is typical
# nsCertType = client, email

# and for everything including object signing:
# nsCertType = client, email, objsign

# This is typical in keyUsage for a client certificate.
# keyUsage = nonRepudiation, digitalSignature, keyEncipherment

# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"

# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always

# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy

# Copy subject details
# issuerAltName=issuer:copy

#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem
#nsBaseUrl
#nsRevocationUrl
#nsRenewalUrl
#nsCaPolicyUrl
#nsSslServerName

[ v3_req ]

# Extensions to add to a certificate request

basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment

[ v3_ca ]


# Extensions for a typical CA


# PKIX recommendation.

subjectKeyIdentifier=hash

authorityKeyIdentifier=keyid:always,issuer:always

# This is what PKIX recommends but some broken software chokes on critical
# extensions.
#basicConstraints = critical,CA:true
# So we do this instead.
basicConstraints = CA:true

# Key usage: this is typical for a CA certificate. However since it will
# prevent it being used as an test self-signed certificate it is best
# left out by default.
# keyUsage = cRLSign, keyCertSign

# Some might want this also
# nsCertType = sslCA, emailCA

# Include email address in subject alt name: another PKIX recommendation
# subjectAltName=email:copy
# Copy issuer details
# issuerAltName=issuer:copy

# DER hex encoding of an extension: beware experts only!
# obj=DER:02:03
# Where 'obj' is a standard or added object
# You can even override a supported extension:
# basicConstraints= critical, DER:30:03:01:01:FF

[ crl_ext ]

# CRL extensions.
# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.

# issuerAltName=issuer:copy
authorityKeyIdentifier=keyid:always,issuer:always

CERTIFICATE GENERATION SCIRPTS

You will need the following 3 scripts plus an OID extensions file to generate your certificate authority, server certificate, and client certificates. These scripts are modified from Ken Rosers HOWTO to allow you to generate these elements separately. This is useful as many installations demand the need of a primary and backup RADIUS server as well as multiple clients.

You will need to edit the SSL variable to point to your openSSL-0.9.7beta3 install location. If you used the directory I specified, you don't need to change it from the default. Change the passwords in these scripts from "whatever" to the challenge password you wish to use. Make sure you use the same challenge password in all aspects of certificate generation otherwise you will get errors.

CA.root - Certificate Authority Generation.

#!/bin/sh
SSL=/usr/local/openssl-certgen
export PATH=${SSL}/bin/:${SSL}/ssl/misc:${PATH}
export LD_LIBRARY_PATH=${SSL}/lib
# needed if you need to start from scratch otherwise the CA.pl -newca command doesn't copy the new
# private key into the CA directories
rm -rf demoCA
echo "*********************************************************************************"
echo "Creating self-signed private key and certificate"
echo "When prompted override the default value for the Common Name field"
echo "*********************************************************************************"
echo
# Generate a new self-signed certificate.
# After invocation, newreq.pem will contain a private key and certificate
# newreq.pem will be used in the next step
openssl req -new -x509 -keyout newreq.pem -out newreq.pem -passin pass:whatever -passout pass:whatever
echo "*********************************************************************************"
echo "Creating a new CA hierarchy (used later by the "ca" command) with the certificate"
echo "and private key created in the last step"
echo "*********************************************************************************"
echo
echo "newreq.pem" | CA.pl -newca >/dev/null
echo "*********************************************************************************"
echo "Creating ROOT CA"
echo "*********************************************************************************"
echo
# Create a PKCS#12 file, using the previously created CA certificate/key
# The certificate in demoCA/cacert.pem is the same as in newreq.pem. Instead of
# using "-in demoCA/cacert.pem" we could have used "-in newreq.pem" and then omitted
# the "-inkey newreq.pem" because newreq.pem contains both the private key and certificate
openssl pkcs12 -export -in demoCA/cacert.pem -inkey newreq.pem -out root.p12 -cacerts -passin pass:whatever -passout pass:whatever
# parse the PKCS#12 file just created and produce a PEM format certificate and key in root.pem
openssl pkcs12 -in root.p12 -out root.pem -passin pass:whatever -passout pass:whatever
# Convert root certificate from PEM format to DER format
openssl x509 -inform PEM -outform DER -in root.pem -out root.der
#Clean Up
rm -rf newreq.pem

CA.svr - Server certificate generation script.

#!/bin/sh
SSL=/usr/local/openssl-certgen
export PATH=${SSL}/bin/:${SSL}/ssl/misc:${PATH}
export LD_LIBRARY_PATH=${SSL}/lib
echo "*********************************************************************************"
echo "Creating server private key and certificate"
echo "When prompted enter the server name in the Common Name field."
echo "*********************************************************************************"
echo
# Request a new PKCS#10 certificate.
# First, newreq.pem will be overwritten with the new certificate request
openssl req -new -keyout newreq.pem -out newreq.pem -passin pass:whatever -passout pass:whatever
# Sign the certificate request. The policy is defined in the openssl.cnf file.
# The request generated in the previous step is specified with the -infiles option and
# the output is in newcert.pem
# The -extensions option is necessary to add the OID for the extended key for server authentication
openssl ca -policy policy_anything -out newcert.pem -passin pass:whatever -key whatever -extensions xpserver_ext -extfile xpextensions -infiles newreq.pem
# Create a PKCS#12 file from the new certificate and its private key found in newreq.pem
# and place in file specified on the command line
openssl pkcs12 -export -in newcert.pem -inkey newreq.pem -out $1.p12 -clcerts -passin pass:whatever -passout pass:whatever
# parse the PKCS#12 file just created and produce a PEM format certificate and key in certsrv.pem
openssl pkcs12 -in $1.p12 -out $1.pem -passin pass:whatever -passout pass:whatever
# Convert certificate from PEM format to DER format
openssl x509 -inform PEM -outform DER -in $1.pem -out $1.der
# Clean Up
rm -rf newert.pem newreq.pem

CA.clt - Client certificate generation script.

#!/bin/sh
SSL=/usr/local/openssl-certgen
export PATH=${SSL}/bin/:${SSL}/ssl/misc:${PATH}
export LD_LIBRARY_PATH=${SSL}/lib
echo "*********************************************************************************"
echo "Creating client private key and certificate"
echo "When prompted enter the client name in the Common Name field. This is the same"
echo " used as the Username in FreeRADIUS"
echo "*********************************************************************************"
echo
# Request a new PKCS#10 certificate.
# First, newreq.pem will be overwritten with the new certificate request
openssl req -new -keyout newreq.pem -out newreq.pem -passin pass:whatever -passout pass:whatever
# Sign the certificate request. The policy is defined in the openssl.cnf file.
# The request generated in the previous step is specified with the -infiles option and
# the output is in newcert.pem
# The -extensions option is necessary to add the OID for the extended key for client authentication
openssl ca -policy policy_anything -out newcert.pem -passin pass:whatever -key whatever -extensions xpclient_ext -extfile xpextensions -infiles newreq.pem
# Create a PKCS#12 file from the new certificate and its private key found in newreq.pem
# and place in file specified on the command line
openssl pkcs12 -export -in newcert.pem -inkey newreq.pem -out $1.p12 -clcerts -passin pass:whatever -passout pass:whatever
# parse the PKCS#12 file just created and produce a PEM format certificate and key in certclt.pem
openssl pkcs12 -in $1.p12 -out $1.pem -passin pass:whatever -passout pass:whatever
# Convert certificate from PEM format to DER format
openssl x509 -inform PEM -outform DER -in $1.pem -out $1.der
# clean up
rm -rf newcert newreq.pem

xpextensions - OID extensions (used by CA.clt, CA.svr)

[ xpclient_ext]
extendedKeyUsage = 1.3.6.1.5.5.7.3.2
[ xpserver_ext ]
extendedKeyUsage = 1.3.6.1.5.5.7.3.1

RUNNING THE CERTIFICATE GENERATION SCRIPTS

Assuming you saved the scripts with the filenames I specified, make the scripts executable by issuing the command "chmod 700 ./CA.*"

Generate your Certificate Authority by running the CA.root script (type "./CA.root"). When prompted, leave the Common Name as the default set in the openssl.cnf file

Generate your Server Certificate(s) by running the CA.svr script (type "./CA.svr <servername>"). You must specify the servername on the command line only so that the file gets saved with the servername as the filename. When prompted, change the Common Name to your server name.

Generate your Client Certificate(s) by running the CA.clt script (type "./CA.clt <clientusername>" NOTE: No spaces in the username). You must specify the username on the command line only so that the file gets saved with the username as the filename. When prompted, change the Common Name to the client user's full name.

You should now have a bunch of certificates. The certificates that are of importance to this install are:

root.pem
root.der
<servername>.pem
<clientusername>.p12

root.der and <clientusername>.p12 will need to be copied to the client and installed (more on that later)

root.pem and <servername>.pem will get used by FreeRADIUS. These files can be left where they are or copied to another location. If you run FreeRADIUS as a non-privlaged user (non-root), be sure that these files are accessible by that user. In the context of this HOWTO, these files are copied to /etc/1x

7) FreeRADIUS Configuration

CONFIGURATION FILES

FreeRADIUS configuration is relatively simple. Only 3 files need to be configured for the basic configuration. If you need FreeRADIUS to do other forms of authentication or auth via LDAP or PAM, consult the FreeRADIUS documentation. If you configured and installed FreeRADIUS with --sysconfdir=/etc then the files will be in /etc/raddb. These files are clients.conf, radiusd.conf, and users

clients.conf

This file gives access to your access points to connect to the RADIUS server and request authentication. You can specify a single IP address or an entire subnet that can access the server. To add a single IP, add these lines in your clients.conf file

client <ipaddress> {
secret = <clientpassword> # This is seperate from the challenge password specified in the certificates
shortname = AP1 # This is only a descriptive name for accounting purposes
}

To add an entire subnet, add these lines

client <subnet>/<mask> {
secret = <clientpassword>
shortname = LAN
}

Configure access from localhost so you can test to make sure RADIUS is working properly

client 127.0.0.1 {
secret = test
shortname = localhost
}

radiusd.conf

There are only a couple sections that need to be modified to make EAP/TLS to work in this file. Obviously the first is the EAP section. Change the section to look like this and don't worry that the DH and random files don't exist yet. We will be generating those in a second

# Extensible Authentication Protocol
#
# For all EAP related authentications
eap {
# Invoke the default supported EAP type when
# EAP-Identity response is received
default_eap_type = tls

# Default expiry time to clean the EAP list,
# It is maintained to co-relate the
# EAP-response for each EAP-request sent.
timer_expire = 60

# Supported EAP-types
# md5 {
# }

## FIXME: EAP-TLS is highly experimental EAP-Type at the moment.
# Please give feedback.
tls {
private_key_password = whatever
private_key_file = /etc/1x/<servername>.pem

# Sometimes Private key & Certificate are located
# in the same file, then private_key_file & certificate_file
# must contain the same file name.
certificate_file = /etc/1x/<servername>.pem

# Trusted Root CA list
CA_file = /etc/1x/root.pem

dh_file = /etc/1x/DH
random_file = /etc/1x/random
#
# This can never exceed MAX_RADIUS_LEN (4096)
# preferably half the MAX_RADIUS_LEN, to
# accomodate other attributes in RADIUS packet.
# On most APs the MAX packet length is configured
# between 1500 - 1600. In these cases, fragment
# size should be <= 1024.
fragment_size = 1024
# include_length is a flag which is by default set to yes
# If set to yes, Total Length of the message is included
# in EVERY packet we send.
# If set to no, Total Length of the message is included
# ONLY in the First packet of a fragment series.
include_length = yes
}
}

You may need to fiddle with the fragment_size variable a bit depending on your access point. 1024 seems to work for most.

Next you need to edit the Authorization section. Uncomment the reference to eap as follows:

# Authorization. First preprocess (hints and huntgroups files),
# then realms, and finally look in the "users" file.
# The order of the realm modules will determine the order that
# we try to find a matching realm.
# Make *sure* that 'preprocess' comes before any realm if you
# need to setup hints for the remote radius server
authorize {
#
# The preprocess module takes care of sanitizing some bizarre
# attributes in the request, and turning them into attributes
# which are more standard.
#
# It takes care of processing the 'raddb/hints' and the
# 'raddb/huntgroups' files.
#
# It also adds a Client-IP-Address attribute to the request.
#
preprocess

#
# The chap module will set 'Auth-Type := CHAP' if we are
# handling a CHAP request and Auth-Type has not already been set
#
# chap

# counter
# attr_filter
eap
suffix
files
# etc_smbpasswd
}

Finally edit the Authentication section once again uncommenting out the reference to EAP

# Authentication.
#
# This section lists which modules are available for authentication.
# Note that it does NOT mean 'try each module in order'. It means
# that you have to have a module from the 'authorize' section add
# a configuration attribute 'Auth-Type := FOO'. That authentication type
# is then used to pick the apropriate module from the list below.
#
# The default Auth-Type is Local. That is, whatever is not included inside
# an authtype section will be called only if Auth-Type is set to Local
#
# So you should do the following:
# Set Auth-Type to an appropriate value in the authorize section. For example chap
# will set Auth-Type to CHAP, ldap to LDAP etc
# After that create corresponding authtype sections in the authenticate section below
# and call the appropriate modules (chap for CHAP etc)
authenticate {
# pam
unix

# Uncomment it if you want to use ldap for authentication
# authtype LDAP {
# ldap
# }
# mschap
eap

# Uncomment it if you want to support CHAP
# authtype CHAP {
# chap
# }

# Uncomment the following if you want to support PAP and you
# extract user passwords from the user database (LDAP,SQL, etc).
# You should use the 'files'module to set 'Auth-Type := PAP' for
# this to work.
# authtype PAP {
# pap
# }
#
}

users

Add lines that reference to your client certificates

"<clientusersfullname>" Auth-Type := EAP

I would also add a test user to make sure that RADIUS is working properly. This can be removed later.

"test" Auth-Type := Local, User-Password =="test"

RANDOM FILES

Two random files need to be created for session key management. These files only need contain random characters which can be generated using your preferred method. They need to be stored as /etc/1x/random and /etc/1x/DH. Some examples I have seen show generating these files as simply as by issuing the following two commands

date > /etc/1x/random

date >/etc/1x/DH

Alternately, you could buy a monkey and have him bash out characters on the keyboard. There are many different options out there. I personally enjoy the bashing the keyboard one. Maybe its not 100% truly random, but it sure is a lot of fun!

8) Running and Testing FreeRADIUS

If everything has been installed and configured correctly at this point, FreeRADIUS should be ready to run and authenticate users. You will need a wrapper script to run FreeRADIUS to make sure that it uses the SSL libraries from the SNAP version of openSSL. Script should look like this

run-radiusd

#!/bin/sh -x

LD_LIBRARY_PATH=/usr/local/openssl/lib
LD_PRELOAD=/usr/local/openssl/lib/libcrypto.so

export LD_LIBRARY_PATH LD_PRELOAD

/usr/local/radius/sbin/radiusd $@

Copy this script to /usr/local/sbin (or wherever you installed radiusd) and make executable. (chmod 700 ./run-radiusd)

If you installed the SNAP version of openSSL in a different location than /usr/local/openssl then you will need to edit this script to reflect that.

RUNNING FreeRADIUS FOR THE FIRST TIME

Run FreeRADIUS by typing "run-radiusd -X -A" This will run radiusd in debug mode with the proper SSL libraries. If everything is configured correctly, the server should inform you that it is listening for requests. In another session type "radtest test test localhost 0 test". If the RADIUS server is working correctly, an Access-Accept should be returned. (at this point you can delete the test user line from the FreeRADIUS users file) If you get an Access-Reject or no response, than recheck to make sure you configured FreeRADIUS correctly by reviewing the previous sections.

RUNNING AT STARTUP

FreeRadius provides some init scripts for debian and redhat systems that can be used for starting the service at startup. These scripts need to be edited to either include the information in the wrapper script or run the wrapper script instead of the binary itself.

9) Access Point Setup

There are quite a few access points out there that will support the required protocols so I cannot cover them all here. The basics of setup are the same across the board so consult your hardware documentation for proper setup. For the ORINOCO AP-2000, setup is as follows

First, make sure you have the latest Flash image installed on the AP. (2.0.2 is current as of this writing for the AP-2000)

Log onto the HTTP interface of the AP (http://accesspointip)

Select the configure button on the left side of the page

Select the Security tab

Select the RADIUS Subtab

Your configuration for the RADIUS server should look like this

Authorization Lifetime can be edited to suit your security needs. The key settings that need to be correct are the IP Address and the Shared Secret. The IP Address here is the address of the FreeRADIUS server. The Shared Secret is the password specified in the clients.conf file on the server.

You will only need to configure the Encryption subtab if you wish to allow non 802.1x authenticated clients.

Select the 802.1x subtab

If you want to allow both WEP and 802.1x clients select mixed otherwise select 802.1x from the 802.1X Security Mode. Obviously use 128 bit keys unless you have a good reason not to

10) XP Client (Supplicant) Setup

Before you begin this portion of setup, be sure that FreeRADIUS is running on the server in debug mode (run-radiusd -X -A)

XP has all the software needed for 802.1X authentication so no additional software is needed. You will need to install the previously generated certificates root.der and <username>.p12. Copy those files to your client hard drive and double click on root.der

IMPORTING THE CERTIFICATES

Click on Install Certificate - The Certificate import Wizard Appears. Click Next

Select "Place all Certificates in the following store" and click browse

Select "Trusted Root Certification Authority" and click OK

Click Next

Click Finish

You will be asked if you wish to import the certificate. Select yes and you should get a message that the import was successful

Now double click on <username>.p12

The certificate wizard appears. Click next.

The wizard asks to verify the file name. Leave as is and click next.

Enter the challenge password you specified when generating the certificates and click next.

Select "Automatically select the certificate store based on type of certificate" and click next.

Click finish to complete the import. The system should notify you that the import was successful

XP WIRELESS NETWORK CONFIGURATION

The following windows apply only to XP SP1. The original XP windows are a bit different but similar. I would STRONGLY recommend that you update to SP1 as I have heard the 802.1X client components of original XP are a bit unstable at times.

If you have never setup wireless networking on your laptop before, you will likely receive this pop up bubble when enabling your wireless card.

At this point, you can click on this box to open the configuration window. If you are running a closed system that doesn't broadcast the network name, right click on the interface in the systray and click on "View Available Wireless Networks"

The wireless configuration window will appear

Once again, if you are running a closed system, no networks will appear. Click advanced

Click on Add.

Type in your network SSID (This is the network name configured on the AP). Be sure that "Data encryption (WEP enabled)" and "The key is provided for me automatically" is checked.

Now select the Authentication tab

Make sure "Enable IEE 802.1x authentication for this network" is checked, EAP type is "Smart Card or other Certificate", and "Authenticate as computer when computer information is available" is checked.

Click on properties

Select "Use a certificate on this computer", "Use simple certificate select (Recommended)", and "Validate server certificate".

Select your Trusted Root Certification Authority. This is the Common Name specified in your openssl.cnf file.

Click OK to close that window. Click OK to close the Wireless Network Properties windows, and finally click ok to close wireless properties

If your FreeRADIUS server is running, APs properly configured, and all XP setup instructions are setup properly, you should now be connected to your network

11) Troubleshooting

If FreeRADIUS is setup and running properly, you should see similar output during startup of the FreeRADIUS server and authentication of a wireless client.

run-radiusd -X -A
+ LD_LIBRARY_PATH=/usr/local/openssl/lib
+ LD_PRELOAD=/usr/local/openssl/lib/libcrypto.so
+ export LD_LIBRARY_PATH LD_PRELOAD
+ /usr/local/sbin/radiusd -X -A
Starting - reading configuration files ...
reread_config: reading radiusd.conf
Config: including file: /etc/raddb/proxy.conf
Config: including file: /etc/raddb/clients.conf
Config: including file: /etc/raddb/snmp.conf
Config: including file: /etc/raddb/sql.conf
main: prefix = "/usr/local"
main: localstatedir = "/var"
main: logdir = "/var/log/radius"
main: libdir = "/usr/local/lib"
main: radacctdir = "/var/log/radius/radacct"
main: hostname_lookups = no
read_config_files: reading dictionary
read_config_files: reading naslist
read_config_files: reading clients
read_config_files: reading realms
main: max_request_time = 30
main: cleanup_delay = 5
main: max_requests = 1024
main: delete_blocked_requests = 0
main: port = 0
main: allow_core_dumps = no
main: log_stripped_names = no
main: log_file = "/var/log/radius/radius.log"
main: log_auth = no
main: log_auth_badpass = no
main: log_auth_goodpass = no
main: pidfile = "/var/run/radiusd/radiusd.pid"
main: user = "(null)"
main: group = "(null)"
main: usercollide = no
main: lower_user = "no"
main: lower_pass = "no"
main: nospace_user = "no"
main: nospace_pass = "no"
main: checkrad = "/usr/local/sbin/checkrad"
main: proxy_requests = yes
proxy: retry_delay = 5
proxy: retry_count = 3
proxy: synchronous = no
proxy: default_fallback = yes
proxy: dead_time = 120
proxy: servers_per_realm = 15
security: max_attributes = 200
security: reject_delay = 1
main: debug_level = 0
read_config_files: entering modules setup
Module: Library search path is /usr/local/lib
Module: Loaded System
unix: cache = yes
unix: passwd = "/etc/passwd"
unix: shadow = "/etc/shadow"
unix: group = "/etc/group"
unix: radwtmp = "/var/log/radius/radwtmp"
unix: usegroup = no
unix: cache_reload = 600
HASH: Reinitializing hash structures and lists for caching...
HASH: user root found in hashtable bucket 11726
HASH: user bin found in hashtable bucket 86651
HASH: user daemon found in hashtable bucket 11668
HASH: user adm found in hashtable bucket 26466
HASH: user lp found in hashtable bucket 54068
HASH: user sync found in hashtable bucket 42895
HASH: user shutdown found in hashtable bucket 71746
HASH: user halt found in hashtable bucket 7481
HASH: user mail found in hashtable bucket 79471
HASH: user news found in hashtable bucket 5375
HASH: user uucp found in hashtable bucket 38541
HASH: user operator found in hashtable bucket 21748
HASH: user games found in hashtable bucket 47657
HASH: user gopher found in hashtable bucket 47357
HASH: user ftp found in hashtable bucket 56226
HASH: user nobody found in hashtable bucket 99723
HASH: user ntp found in hashtable bucket 21418
HASH: user rpc found in hashtable bucket 72373
HASH: user vcsa found in hashtable bucket 25959
HASH: user nscd found in hashtable bucket 36306
HASH: user sshd found in hashtable bucket 71560
HASH: user rpm found in hashtable bucket 72383
HASH: user mailnull found in hashtable bucket 78086
HASH: user smmsp found in hashtable bucket 13600
HASH: user rpcuser found in hashtable bucket 552
HASH: user nfsnobody found in hashtable bucket 51830
HASH: user pcap found in hashtable bucket 55326
HASH: user xfs found in hashtable bucket 17213
HASH: user named found in hashtable bucket 7729
HASH: user apache found in hashtable bucket 26582
HASH: user postfix found in hashtable bucket 23093
HASH: Stored 31 entries from /etc/passwd
HASH: Stored 41 entries from /etc/group
Module: Instantiated unix (unix)
Module: Loaded eap
eap: default_eap_type = "tls"
eap: timer_expire = 60
tls: rsa_key_exchange = no
tls: dh_key_exchange = yes
tls: rsa_key_length = 512
tls: dh_key_length = 512
tls: verify_depth = 0
tls: CA_path = "(null)"
tls: pem_file_type = yes
tls: private_key_file = "/etc/1x/fun-wlan01.pem"
tls: certificate_file = "/etc/1x/fun-wlan01.pem"
tls: CA_file = "/etc/1x/root.pem"
tls: private_key_password = "whatever"
tls: dh_file = "/etc/1x/DH"
tls: random_file = "/etc/1x/random"
tls: fragment_size = 1024
tls: include_length = yes
rlm_eap_tls: conf N ctx stored
rlm_eap: Loaded and initialized the type tls
Module: Instantiated eap (eap)
Module: Loaded preprocess
preprocess: huntgroups = "/etc/raddb/huntgroups"
preprocess: hints = "/etc/raddb/hints"
preprocess: with_ascend_hack = no
preprocess: ascend_channels_per_line = 23
preprocess: with_ntdomain_hack = no
preprocess: with_specialix_jetstream_hack = no
preprocess: with_cisco_vsa_hack = no
Module: Instantiated preprocess (preprocess)
Module: Loaded realm
realm: format = "suffix"
realm: delimiter = "@"
Module: Instantiated realm (suffix)
Module: Loaded files
files: usersfile = "/etc/raddb/users"
files: acctusersfile = "/etc/raddb/acct_users"
files: preproxy_usersfile = "/etc/raddb/preproxy_users"
files: compat = "no"
Module: Instantiated files (files)
Module: Loaded detail
detail: detailfile = "/var/log/radius/radacct/%{Client-IP-Address}/detail"
detail: detailperm = 384
detail: dirperm = 493
detail: locking = no
Module: Instantiated detail (detail)
Module: Loaded radutmp
radutmp: filename = "/var/log/radius/radutmp"
radutmp: username = "%{User-Name}"
radutmp: perm = 384
radutmp: callerid = yes
Module: Instantiated radutmp (radutmp)
Listening on IP address *, ports 1812/udp and 1813/udp, with proxy on 1814/udp.
Ready to process requests.
rad_recv: Access-Request packet from host 10.129.220.26:6001, id=188, length=140
User-Name = "Raymond McKay"
NAS-IP-Address = 10.129.220.26
Called-Station-Id = "00-02-2d-48-49-b2"
Calling-Station-Id = "00-02-2d-34-cf-c2"
NAS-Identifier = "FBI-AP-B4"
Framed-MTU = 1400
NAS-Port-Type = Wireless-802.11
EAP-Message = "\002Z\000\022\001Raymond McKay"
Message-Authenticator = 0x8fd68e8090437f704473b277b2572879
modcall: entering group authorize
modcall[authorize]: module "preprocess" returns ok
modcall[authorize]: module "eap" returns updated
rlm_realm: No '@' in User-Name = "Raymond McKay", looking up realm NULL
rlm_realm: No such realm NULL
modcall[authorize]: module "suffix" returns noop
users: Matched DEFAULT at 152
users: Matched Raymond McKay at 217
modcall[authorize]: module "files" returns ok
modcall: group authorize returns updated
rad_check_password: Found Auth-Type EAP
auth: type "EAP"
modcall: entering group authenticate
rlm_eap: processing type tls
modcall[authenticate]: module "eap" returns ok
modcall: group authenticate returns ok
Sending Access-Challenge of id 188 to 10.129.220.26:6001
EAP-Message = "\001[\000\006\r "
Message-Authenticator = 0x00000000000000000000000000000000
State = 0xaf77d5604503ae127b3b4d6df9a20ccc6f73bf3d3e655eb60bf0a74afed41935698d7288
Finished request 0
Going to the next request
--- Walking the entire request list ---
Waking up in 6 seconds...
rad_recv: Access-Request packet from host 10.129.220.26:6001, id=189, length=272
User-Name = "Raymond McKay"
NAS-IP-Address = 10.129.220.26
Called-Station-Id = "00-02-2d-48-49-b2"
Calling-Station-Id = "00-02-2d-34-cf-c2"
NAS-Identifier = "FBI-AP-B4"
State = 0xaf77d5604503ae127b3b4d6df9a20ccc6f73bf3d3e655eb60bf0a74afed41935698d7288
Framed-MTU = 1400
NAS-Port-Type = Wireless-802.11
EAP-Message = "\002[\000p\r\200\000\000\000f\026\003\001\000a\001\000\000]\003\001=\300\036\037\262t\315\034\034\rP\354\222\010HMr\200:g\2564u\204\342\201gQr\232\032\021 \205U\337\314\374\326\350=\\w\355B\323%+\r\303\220\377\222\301\272\253\351\216\216\343\n\200c\036j\000\026\000\004\000\005\000\n\000\t\000d\000b\000\003\000\006\000\023\000\022\000c\001"
Message-Authenticator = 0x679e88f88eafd40526bbe40122572c6d
modcall: entering group authorize
modcall[authorize]: module "preprocess" returns ok
modcall[authorize]: module "eap" returns updated
rlm_realm: No '@' in User-Name = "Raymond McKay", looking up realm NULL
rlm_realm: No such realm NULL
modcall[authorize]: module "suffix" returns noop
users: Matched DEFAULT at 152
users: Matched Raymond McKay at 217
modcall[authorize]: module "files" returns ok
modcall: group authorize returns updated
rad_check_password: Found Auth-Type EAP
auth: type "EAP"
modcall: entering group authenticate
rlm_eap: Request found, released from the list
rlm_eap: EAP_TYPE - tls
rlm_eap: processing type tls
rlm_eap_tls: Length Included
undefined: before/accept initialization
TLS_accept: before/accept initialization
<<< TLS 1.0 Handshake [length 0061], ClientHello

TLS_accept: SSLv3 read client hello A
>>> TLS 1.0 Handshake [length 004a], ServerHello

TLS_accept: SSLv3 write server hello A
>>> TLS 1.0 Handshake [length 0711], Certificate

TLS_accept: SSLv3 write certificate A
>>> TLS 1.0 Handshake [length 00cc], CertificateRequest

TLS_accept: SSLv3 write certificate request A
TLS_accept: SSLv3 flush data
TLS_accept:error in SSLv3 read client certificate A
rlm_eap_tls: SSL_read Error
Error code is ..... 2
SSL Error ..... 2
modcall[authenticate]: module "eap" returns ok
modcall: group authenticate returns ok
Sending Access-Challenge of id 189 to 10.129.220.26:6001
EAP-Message = "\001\\\004\n\r\300\000\000\0106\026\003\001\000J\002\000\000F\003\001=\277so\303\267<\304y{\360\361\2055\257\365S\247\210\321\243\334Hj@\013\304\251\347\256\326N \330\244\246\346'\212?\353Q\227)\2530\352k`\264$\271\246\231\364\237\215Z\215\036\346\232\252\351\335\000\004\000\026\003\001\007\021\013\000\007\r\000\007\n\000\002\3720\202\002\3660\202\002_\240\003\002\001\002\002\001\0010\r\006\t*\206H\206\367\r\001\001\004\005\0000\201\2711\0130\t\006\003U\004\006\023\002CT1\0240\022\006\003U\004\010\023\013"
EAP-Message = "tive1\0360\034\006\003U\004\003\023\025Funnybone Wireless CA1!0\037\006\t*\206H\206\367\r\001\t\001\026\022rmckay@vugames.com0\036\027\r021029074911Z\027\r031029074911Z0\201\2561\0130\t\006\003U\004\006\023\002CT1\0240\022\006\003U\004\010\023\013Connecticut1\0170\r\006\003U\004\007\023\006Canton1 0\036\006\003U\004\n\023\027Vivendi Universal Games1\0360\034\006\003U\004\013\023\025Funnybone Interactive1\0230\021\006\003U\004\003\023\nfun-wlan011!0\037\006\t*"
EAP-Message = "\206H\206\367\r\001\t\001\026\022rmckay@vugames.com0\201\2370\r\006\t*\206H\206\367\r\001\001\001\005\000\003\201\215\0000\201\211\002\201\201\000\255\221\345d\337\324\001\276Y\267\252\270\206\326qGa\316\206\312\034CP \231\310\331e\315\201rq}\341jdluBM\365\2437\212\236\214\0055\314\251\377\360g\007\232\265\327^\274~F\333\212\314\355\235\031[3]\372\362\260\203\005[\206\017,\320\244\261^\205PL\031,'\027\262\351\223\3769\202\247\006\277qUjP`\234\014l\367\337<\222x\271\313\226%~+\353U\346\031{\205\311O\342m\002"
EAP-Message = "\302^?\344\324CG\317'W$o\225!\332N0 \225\343\235\033n\0308xgu\332a_\305x(\004%\367\264#%\256~%\315\232\350\346!\320\030\026\227s&\307ws\334\321s`\267^r\214r\031"\203\246`\036\007\307E\204"\3148\363\203\336\336\206>n`\203R\365\314O\334m\232\316\33090\262\317\035\006Rh\370\217\233\274G\000\004\n0\202\004\0060\202\003o\240\003\002\001\002\002\001\0000\r\006\t*\206H\206\367\r\001\001\004\005\0000\201\2711\0130\t\006\003U\004\006\023\002CT1\0240\022\006\003U\004\010\023\013Connecticut1\0170\r\006\003U\004\007\023"
EAP-Message = "e Interactive1\0360\034\006\003U\004\003\023\025Fu"
Message-Authenticator = 0x00000000000000000000000000000000
State = 0x74f734504078558933755f353497a4076f73bf3dc23b43a1d868a0cbdfd996d9eadc4dce
Finished request 1
Going to the next request
Waking up in 6 seconds...
rad_recv: Access-Request packet from host 10.129.220.26:6001, id=190, length=166
User-Name = "Raymond McKay"
NAS-IP-Address = 10.129.220.26
Called-Station-Id = "00-02-2d-48-49-b2"
Calling-Station-Id = "00-02-2d-34-cf-c2"
NAS-Identifier = "FBI-AP-B4"
State = 0x74f734504078558933755f353497a4076f73bf3dc23b43a1d868a0cbdfd996d9eadc4dce
Framed-MTU = 1400
NAS-Port-Type = Wireless-802.11
EAP-Message = "\002\\\000\006\r"
Message-Authenticator = 0x4a2507ef82e0af4312db9eba2bfc3b77
modcall: entering group authorize
modcall[authorize]: module "preprocess" returns ok
modcall[authorize]: module "eap" returns updated
rlm_realm: No '@' in User-Name = "Raymond McKay", looking up realm NULL
rlm_realm: No such realm NULL
modcall[authorize]: module "suffix" returns noop
users: Matched DEFAULT at 152
users: Matched Raymond McKay at 217
modcall[authorize]: module "files" returns ok
modcall: group authorize returns updated
rad_check_password: Found Auth-Type EAP
auth: type "EAP"
modcall: entering group authenticate
rlm_eap: Request found, released from the list
rlm_eap: EAP_TYPE - tls
rlm_eap: processing type tls
rlm_eap_tls: Received EAP-TLS ACK message
modcall[authenticate]: module "eap" returns ok
modcall: group authenticate returns ok
Sending Access-Challenge of id 190 to 10.129.220.26:6001
EAP-Message = "\001]\004\n\r\300\000\000\0106nnybone Wireless CA1!0\037\006\t*\206H\206\367\r\001\t\001\026\022rmckay@vugames.com0\036\027\r021029074826Z\027\r021128074826Z0\201\2711\0130\t\006\003U\004\006\023\002CT1\0240\022\006\003U\004\010\023\013Connecticut1\0170\r\006\003U\004\007\023\006Canton1 0\036\006\003U\004\n\023\027Vivendi Universal Games1\0360\034\006\003U\004\013\023\025Funnybone Interactive1\0360\034\006\003U\004\003\023\025Funnybone Wireless CA1!0"
EAP-Message = "\037\006\t*\206H\206\367\r\001\t\001\026\022rmckay@vugames.com0\201\2370\r\006\t*\206H\206\367\r\001\001\001\005\000\003\201\215\0000\201\211\002\201\201\000\321\347\036\275\321\356r\370\n0A|\273\253C\234^K\256m\000\264\237R\353\307R\264\0325\270\212\205\026frg,\256*b\351\216\327\226;\250\334\357J\035\302x\374\030\r\314\337$\r;\374/\345\\YD-\303\260\337\020\276\014\2461U\031\027\356\\JP\256lp\256\357\220\277]\255\272\013-8d#\275K\224\254Y~\307\351,\225\224\320]\255\356\021\316j%\275\240\215fY\303?\275\330"
EAP-Message = ".\210 \201k\0276*\370\202&\303\30691\035|\241\201\277\244\201\2740\201\2711\0130\t\006\003U\004\006\023\002CT1\0240\022\006\003U\004\010\023\013Connecticut1\0170\r\006\003U\004\007\023\006Canton1 0\036\006\003U\004\n\023\027Vivendi Universal Games1\0360\034\006\003U\004\013\023\025Funnybone Interactive1\0360\034\006\003U\004\003\023\025Funnybone Wireless CA1!0\037\006\t*\206H\206\367\r\001\t\001\026\022rmckay@vugames.com\202\001\0000\014\006\003U\035\023\004\0050\003\001\001\3770\r\006\t*\206H\206\367\r\001"
EAP-Message = "\366\025&\353\242\033\341\334^\322=K\007\321\2235%KvJ\364\240\022\244:\273\3234I2\373\037R\226-\333\030N\257\345\327\242\316\3342Y\217 \274\206i\354\272\350\n_\275S\306\010\267\357,\002P\211A\237\256B\312\374~6\310\2778\303\333R\216\256\225\313\236\325\201Z\343\2369uD\325\303\213\302R\315\347\202\\\375\300i\361u\267\222\355\256nf\202:\2730\315\221\354X\3503\026\003\001\000\314\r\000\000\304\003\001\002\005\000\276\000\2740\201\2711\0130\t\006\003U\004\006\023\002CT1\0240\022\006\003U\004\010\023\013Connec"
EAP-Message = "teractive1\0360\034\006\003U\004\003\023\025Funnyb"
Message-Authenticator = 0x00000000000000000000000000000000
State = 0xf6fa05ff508466a331fdd0f85797cc946f73bf3d0cc5c68fb7153303266671a64125d58f
Finished request 2
Going to the next request
Waking up in 6 seconds...
rad_recv: Access-Request packet from host 10.129.220.26:6001, id=191, length=166
User-Name = "Raymond McKay"
NAS-IP-Address = 10.129.220.26
Called-Station-Id = "00-02-2d-48-49-b2"
Calling-Station-Id = "00-02-2d-34-cf-c2"
NAS-Identifier = "FBI-AP-B4"
State = 0xf6fa05ff508466a331fdd0f85797cc946f73bf3d0cc5c68fb7153303266671a64125d58f
Framed-MTU = 1400
NAS-Port-Type = Wireless-802.11
EAP-Message = "\002]\000\006\r"
Message-Authenticator = 0xd9fafc444767cfd6ac8decf6cb0b40d6
modcall: entering group authorize
modcall[authorize]: module "preprocess" returns ok
modcall[authorize]: module "eap" returns updated
rlm_realm: No '@' in User-Name = "Raymond McKay", looking up realm NULL
rlm_realm: No such realm NULL
modcall[authorize]: module "suffix" returns noop
users: Matched DEFAULT at 152
users: Matched Raymond McKay at 217
modcall[authorize]: module "files" returns ok
modcall: group authorize returns updated
rad_check_password: Found Auth-Type EAP
auth: type "EAP"
modcall: entering group authenticate
rlm_eap: Request found, released from the list
rlm_eap: EAP_TYPE - tls
rlm_eap: processing type tls
rlm_eap_tls: Received EAP-TLS ACK message
modcall[authenticate]: module "eap" returns ok
modcall: group authenticate returns ok
Sending Access-Challenge of id 191 to 10.129.220.26:6001
EAP-Message = "\001^\000@\r\200\000\000\0106one Wireless CA1!0\037\006\t*\206H\206\367\r\001\t\001\026\022rmckay@vugames.com\016\000\000"
Message-Authenticator = 0x00000000000000000000000000000000
State = 0xea0c1c97b2423b448d03b076e7a0ae466f73bf3d4b434028d9b7534754be154a0937fc1c
Finished request 3
Going to the next request
Waking up in 6 seconds...
rad_recv: Access-Request packet from host 10.129.220.26:6001, id=192, length=1269
User-Name = "Raymond McKay"
NAS-IP-Address = 10.129.220.26
Called-Station-Id = "00-02-2d-48-49-b2"
Calling-Station-Id = "00-02-2d-34-cf-c2"
NAS-Identifier = "FBI-AP-B4"
State = 0xea0c1c97b2423b448d03b076e7a0ae466f73bf3d4b434028d9b7534754be154a0937fc1c
Framed-MTU = 1400
NAS-Port-Type = Wireless-802.11
EAP-Message = "\002^\004M\r\200\000\000\004C\026\003\001\004\023\013\000\003\003\000\003\000\000\002\3750\202\002\3710\202\002b\240\003\002\001\002\002\001\0020\r\006\t*\206H\206\367\r\001\001\004\005\0000\201\2711\0130\t\006\003U\004\006\023\002CT1\0240\022\006\003U\004\010\023\013Connecticut1\0170\r\006\003U\004\007\023\006Canton1 0\036\006\003U\004\n\023\027Vivendi Universal Games1\0360\034\006\003U\004\013\023\025Funnybone Interactive1\0360\034\006\003U\004\003\023\025Funnybone Wireless CA1!0\037\006\t*\206H\206\367"
EAP-Message = "9074936Z\027\r031029074936Z0\201\2611\0130\t\006\003U\004\006\023\002CT1\0240\022\006\003U\004\010\023\013Connecticut1\0170\r\006\003U\004\007\023\006Canton1 0\036\006\003U\004\n\023\027Vivendi Universal Games1\0360\034\006\003U\004\013\023\025Funnybone Interactive1\0260\024\006\003U\004\003\023\rRaymond McKay1!0\037\006\t*\206H\206\367\r\001\t\001\026\022rmckay@vugames.com0\201\2370\r\006\t*\206H\206\367\r\001\001\001\005\000\003\201\215\0000\201\211\002\201\201\000\260\360\373\203\205\332\271`\031\037<\375"
EAP-Message = "\243\027\324\200k:T\016\3217\351\252\263\240\317}8\022\263\001\313\230\252\362\261q\351I,\266ZT\365\262\334F\260O\353!5(\351[\005\245\005hQ+\024\303\2002e%\310f\371\330\326o+\264\244\336=\371\225\224\332f\330\202\357+\027\006\277\3568\314X\364\007\336bl\223\367R\340\253\326\3472\240\216Q\261yM\240\036\201\207\323\002\003\001\000\001\243\0270\0250\023\006\003U\035%\004\0140\n\006\010+\006\001\005\005\007\003\0020\r\006\t*\206H\206\367\r\001\001\004\005\000\003\201\201\000\212M\rL\010Q\246\207\371\215\203\236"
EAP-Message = "\273:\327\034F\220\203 \344%\023@\r~u\203Z[\354\t-\366\031?\257V\262\231\322\362\240\020\000\000\202\000\20082\341\301R\311\022\206cA\007\306\215\351\257\200\327\250{(\322\024"\231\350\360o\0070\265\356x\320\303\211\366\037?\370'\334|\030\275A\013\252\275\2407\212\331\301\303\347O\270\240\234\274\016\223C\331\3233\267)v\356\324M\312\014\207\2326\3145"\2132\333b\n\217h\367\004\341\217g\3570\240\202\303\027\305,\365L\301\341y\302'$\305\226\224\306;\361\006\350H\236\374Y\033nW<;\227iy\017\000\000\202\000\200"
EAP-Message = "\013#"\007\361\353\036\206\274\023\027D\021c/\022\244k^\343\016$:\340\010\250\326\246T\240\224Q\325U\037\323\310I\206\204\244\211S5"}\024\003\001\000\001\001\026\003\001\000 d\333\302\225p\224\340)I\355\206\272[\212\351\370\267\320\342\227\307B\246.-\023\252Y\265\225\013\200"
Message-Authenticator = 0xc82c27abd1ae24d375548e2dfe9a6cda
modcall: entering group authorize
modcall[authorize]: module "preprocess" returns ok
modcall[authorize]: module "eap" returns updated
rlm_realm: No '@' in User-Name = "Raymond McKay", looking up realm NULL
rlm_realm: No such realm NULL
modcall[authorize]: module "suffix" returns noop
users: Matched DEFAULT at 152
users: Matched Raymond McKay at 217
modcall[authorize]: module "files" returns ok
modcall: group authorize returns updated
rad_check_password: Found Auth-Type EAP
auth: type "EAP"
modcall: entering group authenticate
rlm_eap: Multiple EAP_Message attributes found
rlm_eap: Request found, released from the list
rlm_eap: EAP_TYPE - tls
rlm_eap: processing type tls
rlm_eap_tls: Length Included
<<< TLS 1.0 Handshake [length 0307], Certificate

chain-depth=1,
error=0
--> User-Name = Raymond McKay
--> BUF-Name = Funnybone Wireless CA
--> subject = /C=CT/ST=Connecticut/L=Canton/O=Vivendi Universal Games/OU=Funnybone Interactive/CN=Funnybone Wireless CA/emailAddress=rmckay@vugames.com
--> issuer = /C=CT/ST=Connecticut/L=Canton/O=Vivendi Universal Games/OU=Funnybone Interactive/CN=Funnybone Wireless CA/emailAddress=rmckay@vugames.com
--> verify return:1
chain-depth=0,
error=0
--> User-Name = Raymond McKay
--> BUF-Name = Raymond McKay
--> subject = /C=CT/ST=Connecticut/L=Canton/O=Vivendi Universal Games/OU=Funnybone Interactive/CN=Raymond McKay/emailAddress=rmckay@vugames.com
--> issuer = /C=CT/ST=Connecticut/L=Canton/O=Vivendi Universal Games/OU=Funnybone Interactive/CN=Funnybone Wireless CA/emailAddress=rmckay@vugames.com
--> verify return:1
TLS_accept: SSLv3 read client certificate A
<<< TLS 1.0 Handshake [length 0086], ClientKeyExchange

TLS_accept: SSLv3 read client key exchange A
<<< TLS 1.0 Handshake [length 0086], CertificateVerify

TLS_accept: SSLv3 read certificate verify A
<<< TLS 1.0 ChangeCipherSpec [length 0001]

<<< TLS 1.0 Handshake [length 0010], Finished

TLS_accept: SSLv3 read finished A
>>> TLS 1.0 ChangeCipherSpec [length 0001]

TLS_accept: SSLv3 write change cipher spec A
>>> TLS 1.0 Handshake [length 0010], Finished

TLS_accept: SSLv3 write finished A
TLS_accept: SSLv3 flush data
undefined: SSL negotiation finished successfully
rlm_eap_tls: SSL_read Error
Error code is ..... 2
SSL Error ..... 2
modcall[authenticate]: module "eap" returns ok
modcall: group authenticate returns ok
Sending Access-Challenge of id 192 to 10.129.220.26:6001
EAP-Message = "\001_\0005\r\200\000\000\000+\024\003\001\000\001\001\026\003\001\000 G\343\024\264\3519!\t\3544@\207\344q\351\244\3054\337"\265\266\207\366\375\211\223\355O\321%\255"
Message-Authenticator = 0x00000000000000000000000000000000
State = 0x9c500fb74955bb2eb75e1a58974700a26f73bf3dcdac0d42841fa4f8005481af8abf5070
Finished request 4
Going to the next request
Waking up in 6 seconds...
rad_recv: Access-Request packet from host 10.129.220.26:6001, id=193, length=166
User-Name = "Raymond McKay"
NAS-IP-Address = 10.129.220.26
Called-Station-Id = "00-02-2d-48-49-b2"
Calling-Station-Id = "00-02-2d-34-cf-c2"
NAS-Identifier = "FBI-AP-B4"
State = 0x9c500fb74955bb2eb75e1a58974700a26f73bf3dcdac0d42841fa4f8005481af8abf5070
Framed-MTU = 1400
NAS-Port-Type = Wireless-802.11
EAP-Message = "\002_\000\006\r"
Message-Authenticator = 0x846ca1596b3a896cabaf761ebabeb544
modcall: entering group authorize
modcall[authorize]: module "preprocess" returns ok
modcall[authorize]: module "eap" returns updated
rlm_realm: No '@' in User-Name = "Raymond McKay", looking up realm NULL
rlm_realm: No such realm NULL
modcall[authorize]: module "suffix" returns noop
users: Matched DEFAULT at 152
users: Matched Raymond McKay at 217
modcall[authorize]: module "files" returns ok
modcall: group authorize returns updated
rad_check_password: Found Auth-Type EAP
auth: type "EAP"
modcall: entering group authenticate
rlm_eap: Request found, released from the list
rlm_eap: EAP_TYPE - tls
rlm_eap: processing type tls
rlm_eap_tls: Received EAP-TLS ACK message
modcall[authenticate]: module "eap" returns ok
modcall: group authenticate returns ok
Sending Access-Accept of id 193 to 10.129.220.26:6001
MS-MPPE-Recv-Key = 0xe032765ca06c052e5fe7c2a7534a4252daec44a08505bdb459d4fa81e70390f2221d2b06071eb0625e0ba67452a890909662
MS-MPPE-Send-Key = 0xe03131ce085bc266127528e749bd4753d3e1702df2d4d8c080351380f52eae2c24a9fa78015c24e0d140bcd01b23d6c0cacc
EAP-Message = "\003_\000\004"
Message-Authenticator = 0x00000000000000000000000000000000
Finished request 5
Going to the next request
Waking up in 6 seconds...
--- Walking the entire request list ---
Cleaning up request 0 ID 188 with timestamp 3dbf736f
Cleaning up request 1 ID 189 with timestamp 3dbf736f
Cleaning up request 2 ID 190 with timestamp 3dbf736f
Cleaning up request 3 ID 191 with timestamp 3dbf736f
Cleaning up request 4 ID 192 with timestamp 3dbf736f
Cleaning up request 5 ID 193 with timestamp 3dbf736f

If the last message you see is "Listening on IP Address *" even after you have tried to enable a wireless client, chances are you have configured the AP incorrectly. Go back and verify that you have entered the IP address of the RADIUS server along with the shared password correctly.

If you received an Access-Reject, verify that the name you specified in users on the FreeRADIUS server (/etc/raddb/users) exactly matches what is on the certificate. Also verify that you have imported both the root.der and <username>.p12 files correctly

If your client connects to the network successfully then disconnects, check FreeRADIUS output to make sure you see a MS-MPPE-Recv-Key and MS-MPPE-Send-Key line. If you don't see these lines, either your access point doesn't support EAP/TLS with the MPPE extensions fully OR you used a release version of FreeRADIUS instead of a recent snapshot.

If all else fails join the freeradius-users list at http://www.freeradius.org/list/users.html

 

REFERENCES

Adam Sulmicki's HOWTO on EAP/TLS authentication between FreeRADIUS and XSupplicant
http://www.missl.cs.umd.edu/wireless/eaptls/

Ken Roser's HOWTO: EAP//TLS Setup for FreeRADIIUS and Windows XP Supplliicant
http://www.freeradius.org/doc/EAPTLS.pdf