PEAP support on Linux with xsupplicant
by Matthew Gast
Related link: http://www.open1x.org
Of all the methods available to authenticate wireless LAN connections, Protected EAP (PEAP) is possibly the most widely used. Rather than using digital certificates to authenticate users, with all the complexity that implies, PEAP can instead rely on a user password. Most organizations with a predominance of Microsoft clients have standardized on PEAP as the wireless authentication protocol of choice, which means that the slender minority of other operating systems need to conform to that requirement. I spent some time recently helping a few organizations get xsupplicant running PEAP on Linux.
xsupplicant is an implementation of 802.1X only. It depends on the wireless card's drivers to bring the card up, associate with a network, and do all the low-level stuff. The main point of interaction between the two is that xsupplicant will push dynamically generated keys down in to the driver. xsupplicant is still a work in progress. Today, it only supports dynamic WEP, though I imagine that WPA support is coming quickly.
This article describes how to get xsupplicant itself working. There are a few details to worry about with cards, so I'll post further details on the cards that I've used in the future.
I've used two Linux systems with xsupplicant. One is based on the latest Debian unstable distribution ("sid"), and the other was a SuSE 9.0 system. Both use 2.4 series kernels.
I've now used a couple of different cards with xsupplicant. One is an old Hermes-based card (essentially a mini-PCI Orinoco Gold card), and the other was an Atheros-based Linksys dual-band/tri-mode a+b/g card.
The last major packaged release of xsupplicant is 0.8b, which was released on December 11. Newer code has been checked into CVS since then, and a current CVS version is quite a bit different. The configuration file from the CVS version (retrieved March 2004) isn't compatible with the configuration file from the December packaged distribution. I was unable to get the CVS version to run cleanly, but the 0.8b version ran just fine.
1. OpenSSL, version 0.9.7 or later. All the commonly used 802.1X authentication protocols work with TLS. EAP-TLS uses the certificate exchange directly as authentication; TTLS and PEAP use TLS to authenticate the network to the user and provide security for the user-to-network authentication. xsupplicant uses the OpenSSL TLS implementation, so you will need to have a development version of OpenSSL installed. Chances are that you can install this from your distribution's package system.
2. libpcap and libdnet.. xsupplicant 0.8b requires these two libraries, which perform packet capture and miscellaneous network functions. The CVS version has been rewritten so as not to require them, but I had trouble making it work the day that I fetched the CVS tree. Chances are that you can fetch these from your distribution's package system, too. Debian Linux has a name clash--libdnet is the DECnet library, not Dug Song's "dumb" networking library. Due to the name clash, you'll either have to rewrite the xsupplicant configuration script tests, or just install libdnet from source.
3. Perhaps most importantly, 802.11 should already be working!. Many of the "wireless" problems that you will encounter are really PC Card problems. Obviously, you will not be able to attach to an authenticated network until building and configuring xsupplicant, but you should be able to insert your wireless card and have it be recognized by the system. Card Services will generally sound a high-pitched beep when a card is inserted to indicate it is recognized, resources were successfully allocated, and the driver was loaded. (A second low-pitched beep may follow indicating a configuration failure, but that is OK. Chances are that you want your ultimate configuration to run xsupplicant, so it's acceptable at the outset to not have configuration support immediately.) With the driver successfully loaded, you should be able to run iwconfig and obtain statistics from the driver.
4. Driver support for dynamic WEP. One of the biggest things that 802.1X enables to improve the security of wireless networks is that keys for the radio layer can be provisioned dynamically. One of the problems with some earlier cards is that the drivers assumed there would only be one WEP key in use on the network at any time. Therefore, whenever the key is changed, it is obviously time to reset the card to make the new key take effect. Resetting the card on key change is problematic because it can push the card into a vicious loop. After authentication completes, the dynamic key is pushed into the card, which causes the card to reset, which triggers another authentication and key generation, which pushes a new key into the card, and so on...
By definition, any card you want to use with xsupplicant should support the use of dynamic keys. Many modern cards have driver support for dynamic WEP already, but a few older cards require patches. The popular Hermes-based Orinoco 802.11b cards fall into the latter category. Depending on the driver, you may also need to rebuild your kernel (or at least get a copy of your kernel's configuration) in order to compile a driver.
Compiling and installing xsupplicant 0.8b
There isn't much to say about installing the code. Generally speaking, it follows the same routine that any other open-source package. Fetch the code from sourceforge, and compile in the standard Unix way:
# tar -xzvf xsupplicant-0.8b.tar.gz
(output for filenames in the tarball)
# cd xsupplicant
(output for configuration tests)
(output for build)
# make install
(output for install)
As a result of the build, you get three executables installed; the only one you are likely to use is /usr/local/bin/xsupplicant.
When run, Xsupplicant searches for its configuration file in /etc/1x. The config file, /etc/1x/1x.conf, does not get installed by default, but it's easy enough to copy over.
# mkdir -p /etc/1x
# cd etc
# cp xsupplicant.conf /etc/1x/1x.conf
(Note: The CVS version uses a default file name of /etc/xsupplicant.conf, but you can symlink /etc/xsupplicant.conf to /etc/1x/1x.conf)
You specify the user identity, possibly the password, and the root CA certificate in the configuration file. Passwords are stored in cleartext, so you may wish to have the system prompt for the password to avoid putting sensitive information in configuration files. When no password is in the file for the network you are connecting to, xsupplicant will prompt the user.
You must have the CA certificate that will be used to validate that you are connecting to the right network. xsupplicant does not have a configuration option to disable certificate validation. The configuration file appears to request the root CA in PEM format; you may need to use OpenSSL to convert your root certificate into the right format. (See the section at the end for more details.)
In the configuration file, settings can be stored as part of a profile for an SSID. If I were to connect to a network named "batnet", the configuration file might have some entries that looked like this:
batnet:id = msg
batnet:pref = peap
batnet:phase2auth = MS-CHAPv2
# defaults to same as phase 1 ID
# batnet:phase2id = msg
batnet:random_file = /dev/urandom
batnet:root = /etc/1x/MyCA.pem
xsupplicant will need to be integrated into your configuration startup. The PC Card subsystem on Linux can run scripts to configure cards, and you will probably want to integrate the entire startup script to connect to a network, authenticate to it, and run a DHCP client.
Connecting and authenticating to a network
Step 1: Configure the network.You need to use the Linux utilities to connect to a network. The first step is to use iwconfig, or whatever other method your driver may require, to select a network and put in a dummy WEP key. The dummy key is used to indicate to the driver that it should run in encrypted mode; xsupplicant will replace the key after successful authentication. The most common way of configuring the connection is to use iwconfig to plumb a key and configure the network, and then use ifconfig to bring the interface up and start searching for the network:
# iwconfig eth1 key 12345678901234567890123456
# iwconfig essid essid "batnet"
# ifconfig eth1 up
Depending on the driver, your interface name may not be "eth1". Some drivers may use the "wlan" prefix, and the Atheros driver uses a prefix of "ath".
Step 2: Run xsupplicant. Use the "-i" option to indicate which interface it should run on. Although the documentation refers to a "-n (networkname)" option, it did not appear to be implemented in xsupplicant 0.8b.
# xsupplicant -i eth1
Calling do_eapol, with device eth1
Setup on device eth1 complete
Done with init.
Loading profile for batnet from /etc/1x/1x.conf.
Sending EAPOL-Start #1
Connection Established, authenticating...
Please Enter Your Password :
PEAP Version changed to 0
EAPOL Key processed: broadcast  (13 bytes)
Successfully set WEP key 
EAPOL Key processed: unicast  (13 bytes)
Successfully set WEP key 
Successfully set the WEP transmit key 
Note: Certificate conversions
It is not always guaranteed that you will get the CA certificate in the format you want. Many CAs will give you the certificate in DER format, but xsupplicant appears to want the key in PEM foramt. Both of the CAs I have worked with recently handed out the certificate in DER format, so I had to use OpenSSL to convert between the two:
# openssl x509 -inform DER -outform PEM -in MyCA.der -out MyCa.pem
For the curious that wish to see all the fields in the certificate, take a look with the following command:
# openssl x509 -in MyCA.pem -text
OpenSSL converts between certificate formats very well; see the X.509 documentation for full details.
Linux Kernel Programming
We are building a small benchmarking team for the following project in Bay
Area, CA. This is Linux kernel level work. Interested people should email
their RESUMEs to
I've tried everything I found on the internet to authenticateon a wireless network with peap,includingyour tutorial. I've downloaded a certificate (ThawteServerCA.pem) andedited the configfile with my username and password (<--they work on a windows machine, tested).
When I run xsupplicant like this: "/usr/local/sbin/xsupplicant -d A", it starts and the led on my pcmcia card begins to blink (kwifimanager shows connectd to thewireless network, signal strenght: "very good"). But it seems to not be able to connect me to the wlan.
My xsupplocant.log connects successfully tothe network interface in the top area. after, I get nasid/networkid/portid from the gateway. Further the log says: "Got EAP-Request-Identification". Then, it says "Sending EAPOL-Response-Identification" and a frame is sent with my username as the content (the name I enter in identity= in xsupplicant.conf). It seems xsupplicant does not even come to the part where my password is used, under the "eap-mschapv2" section in the config file. Can you tell me what's wrong? Can I exclude that certain things fail, for example my certificate? What works, where does it fail? Any idea would be alot appreciated! Thanks, -Lucas