Quick Start Guide to Debian and WPA Wireless Security


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.