Quick Start Guide to Debian and WPA Wireless Security

Mike Shuey (shuey@fmepnet.org)

$Date: 2006/05/23 21:08:10 $

This document describes the basic elements of WPA wireless security, mainly because it's somewhat confusing and the necessary information is scattered around the Internet. For implementation, I'm primarily concerned with Debian Linux - especially the current unstable (note: appropriate packages will likely be in "etch", which is currently the testing release).

*BSD users are, unfortunately, screwed.


1. Introduction

2. WPA basics (aka, what the hell is this?)

3. Debian Installation


1. Introduction

Recently my employer changed their campus-wide wireless network. While the previous authentication system is still maintained, it requires setting a machine's ESSID explicitly, and will likely not be maintained for much longer. The new authentication scheme is based on 802.1x and WPA, necessitating some end-user self-education. Given that the new system allows for seamless roaming, and supports 802.11g (as opposed to just 802.11b), learning about WPA seemed prudent. Since others at work also have Debian laptops, this little guide was born.

Much of the text below constitutes some personal notes on WPA in general. If you're looking for just the basic information, and you're in a rush to just turn things on, you may want to skip to section 3.


2. WPA Basics (aka, what the hell is this?)

2.1 Overview

In the beginning, there was WEP - Wired Equivalent Privacy. Problem is, it really wasn't (equivalent to wired). The crypto used to ensure privacy wasn't very robust, was deployed in an extremely poor manner, and relied on shared secrets for any authentication. Not quite what you'd want for a robust wireless system.

This deficiency led to the development of 802.1x - an authentication protocol for ethernet (wired or wireless). It allows for a few different mechanisms for password comparison, several types of encryption (including key rotation plans, where necessary) and much other goodness. Unfortunately, this took a while to develop. Companies developing wireless products grew somewhat impatient and decided to start shipping an agreed-upon subset of 802.1x's capabilities. This is now known as WPA - basically 802.1x, but missing a few authentication mechanisms and lacking heavy crypto for packet encryption (like AES, for example). Upcoming wireless products will (eventually) support WPA2, which is basically full-blown 802.1x.

Today's WPA offers both a shared secret and support for real user authentication, usually through a RADIUS server on the backend. While packet encryption options are a bit limited, it does offer extended key lengths over plain ol' WEP, and provides a key rotation procedure (called TKIP) to avoid weaknesses inherent in both WEP's crypto and its implementation. It's generally considered to be a good enough solution for now, and should last until well after WPA2 support starts appearing in commercial products.

2.2 Hardware Requirements

Like WEP, WPA requires hardware support to help with the packet encryption. Unfortunately, that means only newer 802.11[abg] equipment will work with WPA - older gear won't work, for a variety of reasons (key length, key rotation schedules, encryption types, etc.) 802.11g gear is likely to be a safer bet, although some of the very first 802.11g equipment predates WPA support.

The Atheos 802.11abg NIC (using the "madwifi" driver) in my IBM ThinkPad X40 works just fine with WPA.

Naturally, WPA support must be present on both the NIC (wireless adapter) and on the access point. As this page is solely focused on the client drivers, I'll assume whoever operates your favorite access points (you, perhaps) already knows what he or she is doing.

2.3 Software Requirements

Obviously, you'll need a Linux driver for your WPA-enabled wireless card that supports the WPA features. I use the madwifi drivers for my Altheos 802.11[abg] card, but that's just me. You'll also need a recent Linux kernel, with a fairly recent wireless ethernet API. As of this writing, I'm using 2.6.13, so anything around that vintage (or newer) should work.

You'll also need a supplicant - a daemon program that authenticates your ethernet (wired or wireless) connection. The supplicant will set up all aspects of an authentication connection, and convince the authenticator on the network that your network port is valid. Since this occurs at the ethernet layer, you will probably need to DHCP after authenticating (unless your network uses static IP addressing) - but any standard DHCP client (pump or dhclient, for example) will work at that point.

Like most things in the open-source world, there are two different packages to choose from for a supplicant: wpa_supplicant and open1x.

2.3.1 wpa_supplicant

wpa_supplicant started life as a WPA layer for open1x's xsupplicant. It's since evolved into its own 802.1x-compatible supplicant, and no longer needs (in fact, no longer even supports) open1x. wpa_supplicant supports nearly every WPA and WPA2 (and 802.1x) authentication mode, and is the supplicant described in the text below.

2.3.2 open1x and xsupplicant

Open1x is still maintained, and now includes proper WPA support (now that it is independent from wpa_supplicant). The open1x developers have made some progress toward a GUI to manage the supplicant, but open1x's xsupplicant supposedly supports fewer authentication modes than wpa_supplicant.

2.4 Links


3. Debian Installation

If you're using Debian, congratulations. The good news is, wpa_supplicant is already in Debian's package repository. The bad news is, you may need to get it from Debian unstable (aka "sid"). It's not in the sarge release, but will likely be in the upcoming etch release.

If you're not using Debian, well, good luck. :-)

3.1 Necessary Packages

apt-get install wpasupplicant

Make sure /etc/init.d/wpasupplicant starts at boot-time. As I write this, 0.4.4 is the current version. Earlier versions of the wpasupplicant package will have problems (with madwifi cards, at least).

3.2 /etc/wpa_supplicant.conf

wpa_supplicant uses a single config file to store descriptions of all wireless networks, along with (optionally) the credentials used to access each. Wireless networks are listed in order of increasing priority; SSIDs near the bottom of the file are preferred to those listed near the top. As an example, let's consider the following config file:

# Minimal /etc/wpa_supplicant.conf to associate with open
#  access points. Please see
#  /usr/share/doc/wpasupplicant/wpa_supplicant.conf.gz for more complete
#  configuration parameters.

ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=20

#ap_scan=1
#eapol_version=2
#fast_reauth=1

### Associate with any open access point
###  Scans/ESSID changes can be done with wpa_cli
network={
        ssid=""
        key_mgmt=NONE
}

network={
        ssid="PAL2.0"
        scan_ssid=1
        key_mgmt=WPA-EAP
        eap=PEAP
        identity="someguy"
        password="somepass"
        ca_cert="/etc/ssl/certs/ca-certificates.crt"
}

Ignoring the comment lines, here's what everything means.

ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=dialout

wpa_supplicant uses a named pipe to communicate with a text-based client interface, wpa_cli. wpa_cli can be used to select networks, to provide authentication credentials (if they aren't already in the config file), and to force the supplicant to jump through a variety of hoops. The above two lines indicate that the pipe will be named /var/run/wpa_supplicant, and that it will be owned by group "dialout". The group ownership is merely personal preference on my part - the supplicant runs as root, so any group can be used for the pipe.

#ap_scan=1
#eapol_version=2

These are a few useful global options. These just restate default settings, but are worth mentioning.

Modern access points (like those my employer has deployed) are able to broadcast more than one network ID (SSID), and potentially respond to several more. To find these alternate SSIDs, the supplicant must poll access points. ap_scan=1 turns on this capability, and indicates that wpa_supplicant (not the driver) should handle AP scanning. eapol_version indicates which version of the polling protocol should be used. Version 2 exists (and is defined in the 802.1x spec), but not many access points support it yet - hence using version 1.

If you operate in an environment with many hidden SSIDs, you'll probably want to set ap_scan=2. With that, when a new access point is detected the supplicant will iterate through every network defined in the config file to see if a proper network connection can be made (rather than just relying on broadcasted SSIDs).

#fast_reauth=1

Reauthenticate quickly, when asked. The default is to enable this, but it's a useful tweakable parameter (which is why I'm mentioning it here).

network={
        ssid=""
        key_mgmt=NONE
}

This stanza defines a network without an SSID. Without an SSID, this will bond to any open broadcast network. Without a key_mgmt scheme, no authentication will be attempted. Since this is the first network defined in the config, any other networks will take priority over this one.

network={
        ssid="PAL2.0"
        scan_ssid=1
        key_mgmt=WPA-EAP
        eap=PEAP
        identity="someguy"
        password="somepass"
        ca_cert="/etc/ssl/certs/ca-certificates.crt"
}

This defines a network requiring authentication. Obviously, this network is named "PAL2.0", and requires WPA-EAP to set up the authentication connection. Credentials are exchanged using the PEAP method (one of several options with WPA-EAP). WPA-EAP uses an X509 certificate to protect the authentication session. This certificate should be verified by the supplicant - otherwise you may be sending your credentials to any network with a matching SSID. Not good. That's why you point ca_cert to Debian's CA certificate file.

The scan_ssid=1 line indicates that local access points will probably not broadcast this network by default - that access points must be polled to see if they support this SSID.

Note that both the username and password to be used for this network are stored, in the clear, in the config file. If you'd rather not do this, you can omit one or both of these. You can then use wpa_cli to add an identity and password on a per-network basis at runtime, so they will only be cached in the supplicant daemon. Obviously, authentication won't work until you do this, but it does avoid having cleartext credentials in the config file.

3.3 /etc/network/interfaces

With the latest wpasupplicant packages, Debian controls daemon command-line options through options in your /etc/network/interfaces file. My interfaces file currently has a stanza like this:

# Wireless interface
#auto ath0
iface ath0 inet dhcp
	wpa-driver madwifi
	wpa-conf /etc/wpa_supplicant.conf

Most of this is self-explanatory. Note that ath0 is the network device for my madwifi-powered 802.11 NIC. If you need to change the driver, do so with a different wpa-driver option.

There are a variety of extra options that are supported here. For more info, consult /usr/share/doc/wpasupplicant/README.Debian.gz.

3.4 Using your wireless connection(s)

With your supplicant running, you should be able to ifup <iface> and watch your NIC authenticate. Add an auto ath0 line to your /etc/network/interfaces to automatically bring up ath0 (or whatever your NIC is called) at boot - though that's probably more trouble than it's worth.

At this point you should familiarize yourself with wpa_cli. Start it with no arguments, while wpa_supplicant is running, to get an interactive prompt. A few useful commands:

helpPrints a command summary
scanStarts a scan for new SSIDs/networks
scan_resultsLists the SSIDs wpa_supplicant can currently find
list_networksLists networks defined in your config, and the number wpa_supplicant will use to refer to them
select_network <num>Select a particular network to use. Useful if wpa_supplicant isn't authenticating to the network you want in a busy environment
terminateCauses wpa_supplicant (not wpa_cli) to quit
quitCauses wpa_cli to exit

3.5 Common problems

I've already run into a few frequent hangups with wpa_supplicant, and WPA support in general. If you have problems, and solutions, please let me know and I'll add them to the list below.

3.5.1 wpa_supplicant isn't locking on to my network

If you have several networks defined - especially if one of them is an open broadcast network (no SSID specified) - or if the SSID you're looking for isn't the default broadcast SSID of a nearby access point, wpa_supplicant may not lock onto the network you want. Fire up wpa_cli, use the list_networks command to find the internal number of the network you want, and use the select_network command to choose that network (and disable all others). Then be patient while wpa_supplicant find the network you want and authenticates. To hasten that along, use the scan command to start another SSID scan.

Don't forget that you've selected one network when you later try to use a different net. You'll probably need to select another network, or use the enable_network command if you move to a different wireless coverage area.

3.5.2 wpa_supplicant authenticated to the right network, but I have the wrong IP

If wpa_cli status indicates you've authenticated, and wpa_cli list_networks shows you're using the network you think you should be using, but you've got the wrong IP, then you probably just need to re-DHCP.

wpa_supplicant may not scan or authenticate correctly until the wireless NIC is up (note: I'm referring to the interface being active - it may not yet have an IP address). If you just started DHCPing on that interface, it's possible that DHCP picked up an IP address from a network you weren't intending before wpa_supplicant found and authenticated the correct network. DHCP will keep its erroneous IP until the lease timeout expires, so you'll probably want to re-DHCP.

If this keeps happening (which is likely if the network you want isn't the default broadcast IP on nearby access points) you may want to use the select_network command in wpa_cli to disallow all other networks while you DHCP.

3.5.3 After suspend-to-disk, wpa_supplicant's scan doesn't pick up any new access points

This is most likely a minor driver problem. WPA support for Linux is fairly new, as is suspend-to-disk, so this may happen occaisionally. Remove the driver module for your wireless NIC and reload it (e.g., rmmod ath_pci, modprobe ath_pci). That usually clears things up for me, though your mileage may vary.

If that doesn't work, check wpa_cli list_networks to make sure you haven't inadvertently disabled all the networks that exist at your present location. Frequent use of select_network can cause some confusion.


Mike Shuey
Copyright Mike Shuey, Oct. 2005
$Date: 2006/05/23 21:08:10 $