Securing a Linux Wireless Access Point

In this third part of a five-part series on building a Linux wireless access point, you’ll learn several different ways to secure your servers, so you can choose the level of security that best suits your needs. This article is excerpted from chapter four of the Linux Networking Cookbook, written by Carla Schroder (O’Reilly; ISBN: 0596102488). Copyright © 2008 O’Reilly Media, Inc. All rights reserved. Used with permission from the publisher. Available from booksellers or direct from O’Reilly Media.

4.7 Making WPA2-Personal Almost As Good As WPA-Enterprise


You’re nervous about sitting there with an unsecured wireless access point, and you really want to lock it up before you do anything else. You’ve made sure that all of your wireless network interfaces support WPA2, so you’re ready to go. You don’t want to run a RADIUS authentication server, but using the same shared key for all clients doesn’t seem very secure. Isn’t there some kind of in-between option?


Yes, there is. Pyramid Linux comes with hostapd, which is a user space daemon for access point and authentication servers. This recipe will show you how to assign different pre-shared keys to your clients, instead of everyone using the same one. And, we’ll use a nice strong AES-CCMP encryption, instead of the weaker RC4-based ciphers that WPA and WEP use.

First, run /sbin/rw to make the Pyramid filesystem writeable, then create or edit the /etc/hostapd.conf file:

  ##/etc/hostapd.con f

Next, create /etc/hostapd_wpa_psk, which holds the shared plaintext passphrase:

  00:00:00:00:00:00 waylongpassword

Then, edit /etc/network/interfaces so that hostapd starts when the br0 interface comes up. Add these lines to the end of your br0 entry:

  up hostapd -B /etc/hostapd.conf
  post-down killall hostapd

Run /sbin/ro , then restart networking:

  pyramid:~# /etc/init.d/networking restart

Now, grab a Linux client PC for testing. On the client, create an /etc/wpa_supplicant.conf file with these lines, using your own ESSID and super-secret passphrase from /etc/hostapd_wpa_psk:


Shut down the client’s wireless interface, then test the key exchange:

  # ifdown ath0
  # wpa_supplicant -iath0 -c/etc/wpa_supplicant.conf -Dmadwifi -w
    Trying to associate with 00:ff:4a:1e:a7:7d (SSID=’alrac-net’ freq=2412 MHz)
    Associated with 00:ff:4a:1e:a7:7d
    WPA: Key negotiation completed with 00:ff:4a:1e:a7:7d [PTK=CCMP GTK=CCMP] 
CTRL-EVENT-CONNECTED – Connection to 00:2b:6f:4d:00:8e

This shows a successful key exchange, and it confirms that the CCMP cipher is being used, which you want to see because it is much stronger than the RC4 stream encryption used by WEP. Hit Ctrl-C to end the key exchange test. So, you can add more clients, giving each of them a unique key. All you do is line them up in /etc/hostapd_wpa_psk, and match their passphrases to their MAC addresses:

  00:0D:44:00:83:CF    uniquetextpassword
  00:22:D6:01:01:E2    anothertextpassword
  23:EF:11:00:DD:2E    onemoretextpassword

Now, you have a good strong AES-CCMP based encryption, and if one user compro mises her key, you don’t have to change all of them. Revoking a user’s access is as easy as commenting out or deleting their key.

You can make it permanent on the clients by configuring their wireless interfaces to call wpa_supplicant when they come up. On Debian, do this:

  auto ath0
  iface ath0 inet dhcp
  pre-up wpa_supplicant -iath0 -Dmadwifi -Bw -c/etc/wpa_supplicant/wpa_supplicant.conf
  post-down killall -q wpa_supplicant

On Fedora, add this line to /etc/sysconfig/network-scripts/ifup-wireless:

  wpa_supplicant -ieth0 -c/etc/wpa_supplicant/wpa_supplicant.conf -Dmadwifi -Bw

Make sure your filepath to wpa_supplicant.conf is correct, that you specify the correct interface with -i , and that you specify the correct driver for your wireless interface with the -D option.


When you test the key exchange, you need to specify the driver for your WIC (in the example, it’s – Dmadwifi). man 8 wpa_supplicant lists all options. The wext driver is a generic Linux kernel driver. You’ll see documentation recommending that you use this. It’s better to try the driver for your interface first, then give wext a try if that causes problems.

The example passphrases are terrible, and should not be used in real life. Make yours the maximum length of 63 characters, no words or names, just random jumbles of letters and numbers. Avoid punctuation marks because some Windows clients don’t handle them correctly. There are all kinds of random password generators floating around if you want some help, which a quick web search will find.

Windows XP needs SP2 for WPA support, plus client software that comes with your wireless interfaces. Older Windows may be able to get all the necessary client software with their wireless interfaces. Or maybe not—shop carefully.

It takes some computational power to encrypt a plaintext passphrase, so using plaintext passphrases could slow things down a bit. You can use wpa_password to encrypt your passphrases, then copy the encrypted strings into place:

  $ wpa_passphrase alrac-net w894uiernnfif98389rbbybdbyu8i3yenfig87bfop
#psk= "w894uiernnfif98389rbbybdbyu8i3yenfig87bfop"
psk= 48a37127e92b29df54a6775571768f5790e5df87944 c26583e1576b83390c56f

Now your clients and access point won’t have to expend so many CPU cycles on the passphrase. Encrypted keys do not have quotation marks in wpa_supplicant.conf; plaintext passphrases do.

In our original example, 00:00:00:00:00:00 means “accept all MAC addresses.”

You can see your keys in action with the iwlist ath0 key command on the access point and clients.

Your access point supports virtually all clients: Linux, Mac OS X, Windows, Unix, the BSDs…any client with a supplicant and support for the protocols will work.

NetworkManager and Kwlan are good graphical network management tools for Linux clients. NetworkManager is designed for all Linux desktops and window managers, and comes with Gnome; Kwlan is part of KDE. Both support profiles, key management, and easy network switching.

When you’re using an Ethernet bridge, make sure that you enter your wireless and bridge interfaces in /etc/hostapd.conf.

hostapd.conf supports access controls based on MAC addresses. You’re welcome to use these; however, I think they’re a waste of time because MAC addresses are so easy to spoof your cat can do it.

HostAP was originally a project that supported only Prism wireless chips, but now it supports these drivers:

  1. Host AP driver for Prism2/2.5/3
  2. madwifi (Atheros ar521x)
  3. (Prism GT/Duette/Indigo)
  4. BSD net80211 layer

See Also

  1. Pyramid Linux does not include manpages, so you should install the applications in this chapter on a PC to get the manpages, or rely on Google
  2. wlanconfig is part of MadWiFi-ng 
  3. man 8 wlanconfig
  4. The default hostapd.conf is full of informative comments
  5. The default wpa_supplicant.conf is helpful
  6. 802.11 Wireless Networks: The Definitive Guide, by Matthew Gast (O’Reilly)

{mospagebreak title=4.8 Enterprise Authentication with a RADIUS Server} 


The previous recipe is a slick hack for giving your wireless clients individual keys, but it’s still not a proper Public Key Infrastructure (PKI), which is better for larger deployments, and better for security. You have decided it’s worth running a standalone RADIUS server for your wireless authentication because it offers more security and more flexibility. You’ll be able to use it for all network authentication if you want to, not just wireless, and you can scale up at your own pace. So, how do you use a RADIUS server for wireless authentication?


Use FreeRADIUS together with OpenSSL. There are four steps to this:

  1. Install and configure the FreeRADIUS server
  2. Create and distribute OpenSSL server and client certificates
  3. Configure your wireless access point
  4. Configure client supplicants

Your WAP becomes a Network Access Server (NAS) because it passes along the job of user authentication to the FreeRADIUS server.

To ensure the least hair loss and lowest blood pressure, use your distribution’s package manager to install FreeRADIUS. If you prefer a source installation, refer to the INSTALL document in the source tarball.

This recipe requires a PKI using Extensible Authentication Protocol-Transport Layer Security (EAP-TLS) authentication, which means the server and client must authenticate to each other with X.509 certificates. So, you’ll need:

  1. Your own certificate authority
  2. Server private key and CA-signed certificate
  3. A unique private key and a CA-signed certificate for each client

This is the strongest authentication you can use. See Recipe 9.5 to learn how to do this the easy way, with OpenVPN’s excellent helper scripts. If you don’t have OpenVPN, you can get the scripts from (

There are two things you will do differently. First, use password-protected client certificates:

  # ./build-key-pass [client hostname]

And, you will have to create PK12 certificates for Windows clients:

  # ./build-key-pkcs12 [client hostname]

In this recipe, the certificate authority, private server key, and public server key are kept in /etc/raddb/keys. This directory should be mode 0750, and owned by root and the FreeRADIUS group created by your Linux distribution. On Debian, this is root:freerad. On Fedora, root:radiusd. You’ll be editing these FreeRADIUS files:


Debian users, look in /etc/freeradius instead of /etc/raddb.

First, tell FreeRADIUS about your wireless access point or points in clients.conf, using one section per WAP. You can start over with a clean new file instead of adding to the default file:

  client {
         secret = superstrongpassword
         shortname = wap1
         nastype = other

Then, make a list of authorized users’ login names in the users file, and a nice reject message for users who are not in this file. The usernames are the Common Names on their client certificates. Add them to the existing users file:

  "alrac sysadmin" Auth-Type := EAP
  "terry rockstar" Auth-Type := EAP
  "pinball wizard" Auth-Type := EAP

  DEFAULT Auth-Type := Reject
          Reply-Message = "I hear you knocking, but you can’t come in"

Now, create two files containing random data, which EAP needs to do its job. These must be owned by root and the FreeRADIUS group, and readable only to the file owners:

  # openssl dhparam -check -text -5 512 -out /etc/raddb/dh
  # dd if=/dev/random of=/etc/raddb/random count=1 bs=128
  # chown root:radiusd /etc/raddb/dh
  # chown root:radiusd /etc/raddb/random
  # chmod 0640 /etc/raddb/dh
  # chmod 0640 /etc/raddb/random

Make sure you use the correct RADIUS group for your distribution.

eap.conf is where you configure the EAP module. Find and edit these lines in your existing file, using your own filenames:

  default_eap_type = tls
  ls {
      private_key_password = [your password]
      private_key_file = /etc/raddb/keys/xena.crt
      certificate_file = /etc/raddb/keys/xena.key
      CA_file = /etc/raddb/keys/ca.crt

      dh_file = /etc/raddb/keys/dh2048.pem
      random_file = /etc/raddb/keys/random
      fragment_size = 1024
      include_length = yes

radiusd.conf is huge and replete with helpful comments, so I will show just the bits you may need to change. In the Authorization module, make sure the eap line is uncommented:

  # Authorization. First preprocess (hints and huntgroups files),
  authorize {

Then, in the Authentication module, make sure the eap line is uncommented:

  # Authentication.
  authenticate {

Finally, make sure these lines are uncommented and the correct user and group are entered. These vary, so check your own distribution:

  user = radiusd
  group = radiusd

Shut down FreeRADIUS if it is running, then run these commands to test it:

  # freeradius -X
  "Ready to process requests"
  # radtest test test localhost 0 testing123

The first command starts it in debugging mode. The second command sends it a fake authentication test, which should fail. What you want to see is FreeRADIUS responding to the test. Debugging mode emits reams of useful output, so if there are any errors in your configurations, you’ll be able to track them down.


The trickiest bit is getting your certificates right, but fortunately, the Easy-RSA scripts make the process easy. A good alternative is the excellent graphical PKI manager TinyCA (

A slick FreeRADIUS feature is that you don’t need to use a Certification Revocation List (CRL), though nothing’s stopping you if you want to because revoking a user is as simple as removing them from the users file.

The various Linux distributions handle the FreeRADIUS user and group in different ways. Some use nobody. Debian creates a freerad user and group. It’s important to run FreeRADIUS as an unprivileged user, so make sure that the user and group lines in radiusd.conf are configured correctly.

If you have several WAPs, you may control access by subnet instead of individual WAP:

client {
     secret = superstrongpassword
     shortname  = wap_herd
     nastype  = other

This is less secure because it uses the same secret for all access points, but it’s easier to manage.

See Also

  1. man 1 openssl
  2. man dhparam
  3. The default eap.conf, radiusd.conf, clients.conf, and users files are excellent help references
  4. RADIUS, by Jonathan Hassell (O’Reilly) for a good in-depth tour of running a RADIUS server
  5. The FreeRADIUS Wiki:
  6. TinyCA ( is a nice graphical tool for creating and man aging PKIs, and for importing and exporting certificates and keys
  7. Recipe 9.5

{mospagebreak title=4.9 Configuring Your Wireless Access Point to Use FreeRADIUS}


OK, setting up FreeRADIUS was fun, now what do you do to make your WAP use it?


Your nice Pyramid Linux-based WAP needs but a few lines in /etc/hostapd.conf. In this example, the IP address of the FreeRADIUS server is


  auth_server_shared_secret= superstrongpassword


Edit /etc/network/interfaces so that hostapd starts when your LAN interface comes up. Add these lines to the end of your LAN interface stanza:

  pre-up hostapd -B /etc/hostapd.conf
  post-down killall hostapd

Restart networking:

  pyramid:~# /etc/init.d/networking restart

And you’re almost there. See the next recipe for client configuration.


All the different wireless access points are configured in different ways. The three things common to all of them are:

  1. FreeRADIUS Server IP Address
  2. FreeRADIUS Port: 1812 is the default
  3. FreeRADIUS Key: shared secret

Remember, you don’t have to worry about keys and certificates on the access point. It’s just a go-between.

See Also

  1. RADIUS, by Jonathan Hassell (O’Reilly) for a good in-depth tour of running a RADIUS server

  2. The FreeRADIUS Wiki:
  3. The example hostapd.conf

{mospagebreak title=4.10 Authenticating Clients to FreeRADIUS}


Now that you have your access point and FreeRADIUS server ready to go to work, how do your clients talk to it?


All clients need a copy of ca.crt. Mac and Linux clients get their own [hostname].crt and [hostname].key files. Windows clients use [hostname].p12.

Your Windows and Mac clients have built-in graphical tools for importing and manag ing their certificates, and configuring their supplicants. What do you do on Linux? I haven’t found anything that makes the job any easier than editing plain old text files. Go back to Recipe 4.7, and start with the configuration for /etc/wpa_supplicant.conf. Change it to this:

  ## /etc/wpa_supplicant.conf
  network= {
      pairwise=CCMP TKIP
      group=CCMP TKIP
      identity="alice sysadmin"
      private_key_passwd= "verysuperstrongpassword"

The value for identity comes from /etc/raddb/users on the FreeRADIUS server. Certifi cates and keys can be stored anywhere, as long as wpa_supplicant.conf is configured correctly to point to them.

Continue with the rest of Recipe 4.7 to test and finish configuring wpa_supplicant.


Be sure that .key files are mode 0400, and owned by your Linux user. .crt files are 0644, owned by the user.

You can have multiple entries in wpa_supplicant.conf for different networks. Be sure to use the:

  network {

format to set them apart.

NetworkManager ( is the best Linux tool for painlessly managing multiple network profiles. It is bundled with Gnome, and is available for all Linux distributions.

See Also

  1. man 8 wpa_supplicant
  2. man 5 wpa_supplicant.conf

Please check back for the next part of this article.

Google+ Comments

Google+ Comments