Cover V11, I05

Article
Sidebar

may2002.tar

Configuring a FreeBSD Access Point for your Wireless Network

Michael S. DeGraw-Bertsch

An access point is akin to a cell phone tower -- it's a link from the wireless LAN to the wired network and the Internet beyond. Many commercial access points are available, even integrated with a cable modem or DSL router and firewall. These special-purpose devices are convenient, but they tend to be inflexible and sometimes insecure. Most commercial access points are subject to the limitations of the WEP protocol. (For more information, see "Wireless (In)Security," by Ido Dubrawsky, in this issue of Sys Admin.) Few, if any, support IPsec or IPv6, and the firewall rules, while adequate, are not nearly as powerful as the firewall or IP filters of a real UNIX system.

This article describes how to configure a PC running FreeBSD to serve as an access point (AP) for your wireless network. This FreeBSD access point does not need to be a server or desktop machine. Indeed, many people recommend using an old laptop. You don't need much processing power either; a 386 or 486 will do. Thanks to FreeBSD's excellent installation program, you don't even need a working monitor -- just use the serial port instead. A laptop doesn't require a PCI- or ISA-to-PCMCIA adapter, and already has a built-in backup power supply. Also, long cable runs to an external antenna drop the signal output power significantly, and laptops can often be put closer to the antenna, in places a desktop would be hard pressed to fit.

Finding the Hardware

Once you have your access point machine selected, you'll need wireless cards. Many companies make these cards now, including Orinoco (a.k.a., WaveLAN, Lucent, or Agere), Cisco, and LinkSys. The Orinoco cards are widely available, inexpensive, reliable, and have a built-in external antenna connector. Their 30mW of output power is sufficient for most applications with an external antenna. The Cisco 350 Aironet line puts out 100mW, but is rather pricey. All card-specific examples in this article are based on Orinoco cards, but they translate readily for other cards.

There is one unfortunate note about the Orinoco cards -- older cards, labeled WaveLAN instead of Orinoco, will need a BIOS upgrade before they'll work properly with FreeBSD. The upgrade is freely available from the Orinoco Web page (http://www.wavelan.com). The problem is that the update utility only works under Microsoft Windows. You'll need to jump onto a laptop running Windows or install the PCMCIA adapter in a Windows desktop to update the card.

You might also consider getting an external antenna or two. Since line-of-sight connections work best, if your access point placement is poor, you can install and move an antenna to a better location. Remember that long cable runs dramatically reduce output power, so keep the cable as short as possible.

External antennas are also used to control radiation patterns. PCMCIA cards' radiation pattern is almost vertical, which isn't very powerful if your AP isn't above you. An external antenna will provide a more useful (horizontal) radiation pattern, and can further shape the pattern to provide signal gains. This is achieved by focusing the signal into a specific pattern, increasing the signal's power in that pattern.

In regard to security, wireless cards come with either 128-bit WEP or 40-bit WEP. WEP is the Wired Equivalency Protocol that keeps prying eyes away from your data. It's flawed and doesn't really work (as I'll discuss in detail later) -- meaning the extra money you'd spend on a 128-bit WEP card isn't worth it. Stick with 40-bit WEP cards and save your money.

Finally, if your access point is a desktop machine, you may also need a PCI- or ISA-to-PCMCIA adapter, as some wireless cards are only sold as PCMCIA cards. Both adapters work with FreeBSD, though the Orinoco PCI card requires a more recent version of FreeBSD than its ISA counterpart (i.e., at least 4.4-RELEASE). See the loader.conf section for options you may need if you use a PCI adapter. To avoid any trouble, you might want to just use an ISA adapter.

Setting Up FreeBSD

Once all the necessary equipment is properly installed, you can configure FreeBSD. With some kernel changes, a custom configuration script, and a few odds and ends, you'll be ready to go. The following sections walk you through the changes you need to make.

The Kernel

The first step is to configure the kernel. If you've done this before, great, just skip to the next section for the options you need to add (or make sure you didn't remove). If you haven't done this before, don't worry! It's really easy. For detailed coverage, read chapter 9 of the FreeBSD Handbook (http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig.html). A short primer follows here to get you started.

To begin, you need the kernel source on your machine. If /usr/src/sys/ doesn't exist on your system, you'll need to put it there. The easiest way to add it is to run /stand/sysinstall as root, choose "Configure", then "Distributions", then "src", then "sys". A few okays later, the kernel source will be on your machine.

With the source installed, change to /usr/src/sys/i386/conf. Copy GENERIC to a new file, such as MYKERNEL. Edit the file, adding the options from the next section. When done, save the file and run:

config MYKERNEL
cd ../../compile/MYKERNEL
make depend && make && make install
Reboot, and you're using your new kernel! (If you run into problems and your new kernel won't boot when prompted at boot time, press a key, then type "boot kernel.old" [enter] to use your old kernel. If this happens, read chapter 9 of the FreeBSD Handbook mentioned previously.)

The Kernel's Options

If you're using the generic kernel, there are only a few options you need to add; everything else is there by default. If you have a custom kernel, verify that you have all of the appropriate lines.

First, you must add support for your wireless card. If you removed it, add device <wi|an|awi>, where wi is for Orinoco cards, an is for Aironet cards, and awi is for PRISM cards.

Second, if necessary, add PCMCIA support with the following three lines:

device card
device pcic0   at isa? irq 0 port 0x3e0 iomem 0xd0000
device pcic1   at isa? irq 0 port 0x3e2 iomem 0xd4000 disable
You must also add support for IP filters and IP diverting, with options IPFILTER, options IPDIVERT, device bpf, and, optionally, options IPFILTER_LOG.

While you're at it, you might also add IPsec-related options, for security: options IPSEC, options IPSEC_ESP, and options IPSEC_DEBUG. Their usefulness is briefly discussed in the Wireless Security section. With the appropriate devices and options in place, compile and install your kernel.

loader.conf

If you're using a PCI adapter and you run into trouble (such as FreeBSD hanging on boot, not recognizing your wireless card, or the card simply not working), try adding the following lines to /boot/loader.conf:

hw.pcic.intr_path="1"
hw.pcic.irq="0"
You might also need to tell your BIOS that you're not running a PnP OS, and to allow ISA interrupts to the IRQ that your card is using. (IRQs are also discussed in the section on pccard.conf.) If you have older WaveLAN equipment, you may need to add hw.pcic.ignore_function_1="1" to /boot/loader.conf. The easiest solution, however, is to use either a laptop or an ISA adapter.

rc.conf

Your /etc/rc.conf file needs three changes. First, add the line pccard_enable="YES" to enable the PCMCIA daemon. If you're using a laptop, it should already be there, but it never hurts to double-check. Second, set gateway_enable="YES" to allow your server to pass wireless traffic to the rest of the network. Third, for Network Address Translation (NAT), add ipnat_enable="YES". NAT is discussed in the next section.

Network Address Translation

NAT is one of the great evils of the Internet today. It prevents true end-to-end connectivity and can get so layered that it becomes ridiculous. Unfortunately, IPv6 isn't widely used, and unless you want to spend a good chunk of time configuring it, you'll have to stick with NAT. (If you do want to spend the time configuring IPv6, check out http://www.6bone.net and, if you have a dynamic IP address, http://www.freenet6.net.) NAT on FreeBSD uses the kernel's IP filter code and is very simple to set up.

The previous section enabled NAT at boot, but didn't configure it. The following is an example /etc/ipnat.conf, which is read at boot and enables NAT on outbound interface ep0, translating all traffic from the 10.0.0.0/16 subnet to whatever ep0's address is:

map ep0 10.0.0.0/16 -> 0.0.0.0/32 portmap tcp/udp 40000:65000
map ep0 10.0.0.0/16 -> 0.0.0.0/32
Substitute your external interface ID and your wireless subnet, reboot, and your wireless connections will be routed and NAT'd appropriately.

Wireless Configuration

As I mentioned in the introduction, this article deals only with the Orinoco wireless cards, which are wi devices. The main configuration command, wicontrol, reflects that. Aironet cards, which are an devices, use ancontrol.

There are several parameters that need to be configured for your wireless connection, such as frequency, operating mode, and station name. For convenience, you can create a script named /usr/local/sbin/wireless.sh, which will set all of the parameters at once. The script, with comments inline, should be as follows:

#!/bin/sh
# Run via the sh shell

wicontrol -f 7
# Sets the wireless card's frequency.  Legally, the range is from 1
# (2.412 GHz) to 11 (2.462 GHz) in the US, 1 to 13 (2.472 GHz) in 
# Europe, 10 (2.457 GHz) to 13 in France, and 1 to 14 (2.484 GHz) 
# in Japan.  Choose another frequency if desired.

wicontrol -p 1
# BSS mode, meaning clients must associate with an access point, 
# and cannot directly connect to one another.

wicontrol -c 1
# IBSS mode, an extention of BSS mode.

wicontrol -s "servername"
# Sets the station name.  Does not have to match host's DNS name.

wicontrol -k "12345"
# The WEP key.  Change to something a bit less obvious.

wicontrol -e 1
# Enables WEP security.

ifconfig wi0 ssid "frfa"
# Sets the name of the wireless network.

ifconfig wi0 inet 10.0.0.77 netmask 255.255.255.0
# Sets the IP address and netmask of the wireless device.  Change 
# the device name if necessary.
Additional wicontrol options are available, but are not immediately necessary. They are well documented in wicontrol(8). The next section covers how the configuration script is run dynamically.

pccard.conf

Do not statically configure the wireless configuration script to run at boot, because your card might not be initialized when the script runs. Running it by hand, however, is annoying at best and means you must have physical access to the box if it should ever crash.

The simplest solution is to add a line to the PC card configuration file. The file is typically in /etc/defaults/pccard.conf, but its actual location is defined by the pccard_conf variable. If you defined this in /etc/rc.conf, use that value. Otherwise, the default applies.

Edit the file, and look for the section with the header:

card "Lucent Technologies" "WaveLAN/IEEE"
Now add insert /usr/local/sbin/wireless after the last insert in that block (right before the first remove block). This will run your wireless script whenever the card is inserted, ensuring your connection is always properly configured. Note that if you're using a different wireless card, the section header will be different -- such as card "Aironet" "PC4800". The change remains the same.

If your box hangs when pccardd runs, it may be grabbing an IRQ for your wireless card that's already in use. Remove the card and reboot, and find a free IRQ from dmesg's output. Now edit the configuration file again, revisiting the appropriate card section. On that section's config line, change the trailing "?" to the free IRQ number. This will force pccardd to give your wireless card the free IRQ, thereby preventing conflicts.

Client Configuration

Client configuration is nearly identical to the access point's configuration. The kernel configuration is the same, except for the IPDIVERT and IPFILTER options and the bpf device. In /etc/rc.conf, simply ensure that pccard_enable="YES". NAT and the gateway features are not needed.

Changes to pccard.conf are identical. The wireless configuration script must be identical on both the client and the server. If you use a different mode, frequency, network name, or WEP key, your machines will not see each other, and cannot connect.

There is one line to add to your /usr/local/sbin/wireless.sh script. At the very end, add:

route add default a.b.c.d
Replace a.b.c.d with the IP address of your wireless access point. Finally, if your client is a desktop using a PCI adapter, you may need the loader.conf changes discussed earlier.

Is This Secure?

At this point, you're almost finished; the access point and clients are working. You may have configured your wireless network at home, and perhaps even set one up in the office. You're happily working from your living room or the local coffee shop. As you log in to check your email over telnet, however, you may start wondering if maybe broadcasting your plaintext password for anyone with an antenna to see wasn't the best idea in the world.

And that shouldn't be your only concern. Wireless connectivity adds worlds of new security headaches just as soon as your AP is up and running. For example, what's to prevent someone from walking by your apartment, stealing an IP address, and sending out thousands of spam messages? Nothing. Even if you filter traffic by MAC address, it's trivial for a cracker to scan the airwaves, pick up a valid MAC, and use it as his own.

What about WEP, the Wired Equivalency Protocol? WEP was adopted from the 802.11 standard without any changes, and it's slightly better than nothing. WEP uses the RC4 encryption algorithm, which XORs a data stream with a pseudo-random key stream. This algorithm is pretty easy to crack statistically, especially as more cipher text with the same key is intercepted. Although a new secret key is generated for each packet to avoid multiple packets being encrypted with the same key, the implementation is flawed, rendering the added security moot and making WEP's encryption vulnerable.

WEP is also supposed to provide data integrity: change a bit in RC4 cipher text, and it'll flip the same bit in the plaintext. To guard against exploits, WEP adds a CRC-32 checksum as part of the packet's encrypted payload. However, many different strings yield the same CRC-32 checksum. Since it's mathematically simple to change the message and keep the CRC the same, the integrity of each WEP-protected packet is far from guaranteed.

So, is WEP completely worthless? Not really. Remember that it is simply the Wired Equivalency Protocol, and as such it provides about as much security as a wired LAN. The hour or day that a cracker would need to get at your wireless data is probably akin to how long it would take someone to gain access to your wired LAN, if they tried really, really hard.

So, what's a wireless user to do? Risk it all and just go with WEP? No way! Although it won't protect your wireless data, you can create a DMZ just for your wireless traffic. If users need access to internal resources like an intranet, make them VPN in, just like they're at home. This prevents intruders from gaining immediate access to your local network. If the FreeBSD box you're using as your wireless gateway is also your router, a firewall or IP filter rule will keep insecure traffic from traveling between the wireless and wired worlds.

Next, to secure your data, mandate secure protocols. While this is a good idea in general, it becomes vitally important when networking without wires. SSH (version 2) will provide nearly hack-proof security for your terminal needs. Better still, you can run insecure protocols over SSH port-forwarding tunnels. For example, to tunnel POP3 traffic between your client, 192.168.77.12, and your mail server, 192.168.1.25, run the following on your client:

ssh -L 110:192.168.1.25:110 192.168.77.12
Now point your mail client to localhost, and your password and email are safe.

As great as SSH is, however, it's not perfect. You must create a tunnel, on a unique port, for every secure connection you want to make. This quickly becomes impractical -- especially if you don't have access to a server you want to securely connect to.

Enter IPsec. Mandate IPsec tunneling with Encapsulated Security Payload (ESP) between your clients and the access point. That way, all traffic between the boxes is encrypted. When traffic from your clients is headed beyond the access point, it is still encrypted between the clients and the AP. Similarly, all inbound traffic, regardless of source, is encrypted between the access point and the client. This setup keeps prying antennas from collecting your traffic.

IPsec has the added advantage of providing strong authentication. Since connecting machines must either have a pre-shared key or a good X.509 certificate, only authorized hosts can connect. Configuring IPsec is beyond the scope of this article, and I recommend checking out the KAME project (http://www.kame.net). They develop IPsec and IPv6 code for the BSDs, and have links to more information on their site. Also, be sure to read racoon(8), ipsec(4), and setkey(8). See "OpenBSD as a VPN Solution" by Alex Withers (Sys Admin, September 2000, http://www.samag.com/documents/s=1161/sam0009e/sam0009e.htm) for a discussion of IPSec with OpenBSD.

Conclusion

In this article, I've provided an introduction to the wonderful world of 802.11b wireless networking. I've shown how to create an inexpensive access point, how to configure FreeBSD clients, and how to secure the whole setup. The only thing that's left for you to do is to go out, buy some equipment, set it up, and start working from your couch.

Mike DeGraw-Bertsch is a security and UNIX writer and consultant in the Boston, Massachusetts area. When he's not at a job, writing, hacking with Perl, or playing with his wireless network, he can usually be found playing goal in ice hockey. Mike can be contacted at: mbertsch@radioactivedata.org.