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
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
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 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:
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
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
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
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,
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.
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
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.
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
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.
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:
# 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.
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
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
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
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
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
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
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.
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: email@example.com.