Purpose:
WARNING!
Please note
that this document requires more than a basic knowledge
of networking and the FreeBSD system in general. As suggestions
for improvement come to me, I will attempt to clarify issues and
nomenclature to the best of my abilities. The intention of this
document is to deal with many of the issues I had while using other's
howto's and articles. If you are looking for an easy to follow instruction
manual on how to build your own AP (Access Point) with an old(er)
computer and wireless interfaces, then this probably is not it -
at this point. It would take a significant amount of time and writing
to produce such a document. Although I hope to make this happen
someday, I am lacking in a very important commodity - time. Good
luck and thanks for reading!
I originally set out to make some use out
of an older ThinkPad 770ED that I am no longer using. Since I have
been experimenting with setting up a wireless network in my neighborhood,
I thought this would be a chance to introduce an ultra-controllable
AP into the network, but also allow me to work on adding IPSEC security
for my clients. I found that a few of the sources on the web for
setting up FreeBSD as a wireless AP were lacking (severely, in my
opinion). I scratched around for about 5 days and finally was able
to get the setup to work as desired. One of the major issues I had
to deal with is having the right settings applied to the PC Cards.
Because a lot of firewall and NAT scripts are run quite early in
the boot process, the cards fail to set up properly. This forced
me to figure out how to wait to apply the proper configurations
to the PC Cards until they were actually recognized by the system.
There is still work to do on setting up proper startup scripts,
but since I am not a script writer, I hope someone with better skills
will be able to help me with this.
Needed Materials:
This article specifically discusses
the setup using a ThinkPad laptop, but the following would be necessary
for a generic setup.
• Computer (486 or better - I would really start with a Pentium
or better) w/ at least 16 MB RAM (depending on your network usage,
you can get away with this or might need more). I would also go
for a 1GB hard drive, but I know you can do this with less. I am
in the process of seeing whether I can do this with a solid state
drive (something like 512 MB or less).
• Wired Ethernet Card
• Wireless Card
Experimentation:
One thing I am working on experimenting
with is getting an old P150 or something around that level set up
with an ISA to PCMCIA card reader so that you could essentially
make an old desktop work the same as a laptop. I found that FreeBSD
5.0 is currently the only FreeBSD OS to support the PCI to PCMCIA
reader, so until 5.0 is mainstream, you really need to stick with
the ISA to PCMCIA readers. They are cheaper (the ISA version), but
I found that a lot of newer computers (like my latest Intellistation
M Pro) do not come with any ISA slots (this tells you how old most
of my computers are...) But, since my purpose is really to re-use
old equipment, that point is mute anyway.
My Setup:
• ThinkPad 770ED PII 366 MHz, 223 MB Ram, 8 GB Hard Drive
• 3Com 3C559 PC Card Ethernet Adapter
• Orinoco Gold Wireless PC Card
Installation:
Make sure your installation of FreeBSD allows for creating a custom
kernel - eg you should have installed the kernel sources and headers.
You will need the following options in your kernel:
options
IPFIREWALL # IP Firewall
options IPFIREWALL_VERBOSE # Set Firewall to "talk"
options IPDIVERT # Network Address Translation
options IPFIREWALL_VERBOSE_LIMIT=100 # Limit FW Verbosity
options TCP_DROP_SYNFIN #***
options ICMP_BANDLIM #***
options HZ=1000 # Necessary per LINT for DUMMYNET (used
in the future)
|
Some of these options are not absolutely
necessary and are marked by #***. I am not going to get into the
detailed reasons why all of these options are necessary or recommended.
I am not really the expert on this and you should really consult
some of the resources for firewalling and creating good NAT boxes
on the web and in your bookstore. I will eventually append this
article with recommendations as to books you might want to look
at, but for now, I simply would like to describe the process I have
found to work.
We are going to use ipfw for all of
the firewalling and NAT processes. This is different from most of
the HOWTO's or other articles I have seen on the market at this
time - they use ipnat. I have really grown up using FreeBSD with
the ipfw sort of firewalling, so I tried to stick with what I was
comfortable with.
The following additions should be made to your rc.conf file:
# Misc. controls that might or might not already be enabled
gateway_enable="YES"
pccard_enable="YES"
#Firewall config options for startup:
firewall_enable="YES"
firewall_script="/etc/rc.firewall"
firewall_type="open"
firewall_quiet="NO"
tcp_drop_synfin="YES"
# NAT configuration settings for startup:
natd_enable="NO"
|
I do not configure the default route
or any of the interfaces at startup because the PC Cards have not
yet been recognized. I also do not have the firewall actually doing
any firewalling, nor do I have NAT turned on. This really doesn't
matter, however, because it can take a minute or so before the interfaces
are up and running (this is quite different than having integrated
or PCI/ISA NIC's being configured during the boot process).
Following a HOWTO I found a long time
ago from Dan O'Conner at http://www.mostgraveconcern.com/freebsd,
I created a separate firewall script that is run after the network
interfaces are active. There are essentially three scripts that
need to be run after the PC Cards have been recognized and are up
and running. I have named them as follows (please be sure to read
the comments in the headers of each script, as it contains more
important information):
wireless.sh
wired.sh
rc.ipfw
#!/bin/sh
#
Created: 10 July 2002
# Maintained by: Steven N. Fettig - freebsd-ap@stevenfettig.com
# Last modified: 23 July 2002
# This script was created off suggestions found in:
# http://www.samag.com/documents/s=7121/sam0205a/sam0205a.htm
# For more information on the controls used in this script,
PLEASE
# 'man wicontrol' - it is chock full of important settings/info.
# Remember also that 'wicontrol' is used for wi based PC
Cards. If
# for example, you are using an Aeronet card, your actual
command
# will be 'ancontrol'. Again, make sure to man xxxcontrol
for the
# proper documentation.
# Set the channel of the wireless network to 5
wicontrol -f 5
# Set the wifi adapter to infrastructure mode - i.e. we
do not
# want the network set in ad hoc mode.
wicontrol -p 1
# Set the extension of BSS to IBSS. Currently, the switch
-c that
# changes that setting doesn't completely work for wicontrol
but
# should in the future. Refer to 'man wicontrol' for more
information.
wicontrol -c 1
# name the server and AP (this is primarily used for diagnostic
# controls see 'man wicontrol').
wicontrol -s "myap"
# Set the WEP key (change this accordingly)
wicontrol -k "123456"
# Enable WEP
wicontrol -e 1
# set the SSID of your AP
ifconfig wi0 ssid "myap"
# set the IP and netmask of the wifi card - this is going
# to be the gateway ip
ifconfig wi0 inet 10.2.3.1 netmask 255.255.255.0
|
#!/bin/sh
# Created: 10 July 2002
# Created By: Steven N. Fettig
# Maintained by: Steven N. Fettig - freebsd-ap@stevenfettig.com
# Last Modified: 23 July 2002
# This script may or may not be necessary. If you have an
integrated
# NIC on your desktop or laptop, then it should/will actually
be
# configured during the bootstrap process and makes this
script
# unnecessary (as far as setting IP, etc. goes). You will,
however,
# need some way to enable NAT and the firewall once all
the
# interfaces are configured on your system.
# Set your IP in this statement (this should match
# the IP settings for your static IP)
ifconfig ep0 inet 24.2.3.186 netmask 255.255.255.252
# make sure you let your interface know about your
# gateway/router. I have had problems with allowing automatic
# discovery, so I explicitly define my gateway with this
statement
route add default 24.2.3.185
# Because wired.sh is the script that is really responsible
# for setting up the important parameters for your firewall
# and nat requirements, I will use it for starting the nat
# daemon and setting the firewall parameters. Make sure
# you are using the correct interface for the -n switch
for natd
'/sbin/natd -s -m -n ep0'
'/etc/rc.ipfw'
|
# rc.ipfw - Firewall Rules
#
# This file is a modified version of /etc/rc.firewall.
#
# Originally by: D. O'Conner
# Maintained/Modified by: Steven N. Fettig - freebsd-ap@stevenfettig.com
# Modified: 23 July 2002
#
# Suck in the configuration variables.
# The reason is that the defaults in rc.conf are set too
early
# for setting up NAT and routing on this laptop (TP 770ED),
so
# I enable the firewall AFTER the interfaces have been brought
# up
if [ -r /etc/defaults/rc.conf ]; then
. /etc/defaults/rc.conf
source_rc_confs
elif [ -r /etc/rc.conf ]; then
. /etc/rc.conf
fi
# Firewall program
fwcmd="/sbin/ipfw"
# We do need to define the natd_interface
# DO NOT FORGET THIS
natd_interface="ep0"
# Outside interface network and netmask and ip
oif="ep0"
onet="24.3.4.185"
omask="255.255.255.252"
oip="24.3.4.186"
# Inside interface network and netmask and ip
iif="wi0"
inet="10.2.3.0"
imask="255.255.255.0"
iip="10.2.3.1"
# My ISP's DNS servers
dns1="10.2.3.5"
dns2="10.4.5.6"
# Flush previous rules
${fwcmd} -f flush
# Allow loopbacks, deny imposters
${fwcmd} add 100 pass log all from any to any via lo0
${fwcmd} add 200 deny log all from any to 127.0.0.0/8
# If you're using 'options BRIDGE', uncomment the following
line to pass ARP
#${fwcmd} add 300 pass udp from 0.0.0.0 2054 to 0.0.0.0
# Stop spoofing
${fwcmd} add deny all from ${inet}:${imask} to any in via
${oif}
${fwcmd} add deny all from ${onet}:${omask} to any in via
${iif}
# Stop RFC1918 nets on the outside interface
${fwcmd} add deny all from any to 10.0.0.0/8 via ${oif}
${fwcmd} add deny all from any to 172.16.0.0/12 via ${oif}
${fwcmd} add deny all from any to 192.168.0.0/16 via ${oif}
# Stop draft-manning-dsua-03.txt (1 May 2000) nets (includes
RESERVED-1,
# DHCP auto-configuration, NET-TEST, MULTICAST (class D),
and class E)
# on the outside interface
${fwcmd} add deny all from any to 0.0.0.0/8 via ${oif}
${fwcmd} add deny all from any to 169.254.0.0/16 via ${oif}
${fwcmd} add deny all from any to 192.0.2.0/24 via ${oif}
${fwcmd} add deny all from any to 224.0.0.0/4 via ${oif}
${fwcmd} add deny all from any to 240.0.0.0/4 via ${oif}
# Network Address Translation. This rule is placed here
deliberately
# so that it does not interfere with the surrounding address-checking
# rules. If for example one of your internal LAN machines
had its IP
# address set to 192.0.2.1 then an incoming packet for it
after being
# translated by natd(8) would match the `deny' rule above.
Similarly
# an outgoing packet originated from it before being translated
would
# match the `deny' rule below.
${fwcmd} add divert natd all from any to any via ${natd_interface}
# Stop RFC1918 nets on the outside interface
${fwcmd} add deny all from 10.0.0.0/8 to any via ${oif}
${fwcmd} add deny all from 172.16.0.0/12 to any via ${oif}
${fwcmd} add deny all from 192.168.0.0/16 to any via ${oif}
# Stop draft-manning-dsua-03.txt (1 May 2000) nets (includes
RESERVED-1,
# DHCP auto-configuration, NET-TEST, MULTICAST (class D),
and class E)
# on the outside interface
${fwcmd} add deny all from 0.0.0.0/8 to any via ${oif}
${fwcmd} add deny all from 169.254.0.0/16 to any via ${oif}
${fwcmd} add deny all from 192.0.2.0/24 to any via ${oif}
${fwcmd} add deny all from 224.0.0.0/4 to any via ${oif}
${fwcmd} add deny all from 240.0.0.0/4 to any via ${oif}
# Allow established connections with minimal overhead
${fwcmd} add pass tcp from any to any established
# Allow IP fragments to pass through
${fwcmd} add pass log all from any to any frag
###
TCP RULES
# HTTP - Allow access to our web server
${fwcmd} add pass tcp from any to any 80 setup
# SSH Login - Allow & Log all incoming
${fwcmd} add pass log tcp from any to any 22 in via ${oif}
setup
# IDENT - Reset incoming connections
${fwcmd} add reset log tcp from any to any 113 in via ${oif}
setup
# Reject&Log all setup of incoming connections from
the outside
${fwcmd} add deny log tcp from any to any in via ${oif}
setup
# Allow setup of any other TCP connection
${fwcmd} add pass log tcp from any to any setup
###
UDP RULES
# DNS - Allow queries out in the world
${fwcmd} add pass udp from any to ${dns1} 53
${fwcmd} add pass udp from any to ${dns2} 53
${fwcmd} add pass udp from ${dns1} 53 to any
${fwcmd} add pass udp from ${dns2} 53 to any
# SYSLOG - Allow machines on inside net to log to us.
${fwcmd} add pass log udp from any to any 514 via ${iif}
# NTP - Allow queries out in the world
${fwcmd} add pass udp from any 123 to any 123 via ${oif}
${fwcmd} add pass udp from any 123 to any via ${iif}
${fwcmd} add pass udp from any to any 123 via ${iif}
# TRACEROUTE - Allow outgoing
${fwcmd} add pass log udp from any to any 33434-33523 out
via ${oif}
###
ICMP RULES
# ICMP packets
# Allow all ICMP packets on internal interface
${fwcmd} add pass icmp from any to any via ${iif}
# Allow outgoing pings
${fwcmd} add pass icmp from any to any icmptypes 8 out via
${oif}
${fwcmd} add pass icmp from any to any icmptypes 0 in via
${oif}
# Allow Destination Unreachable, Source Quench, Time Exceeded,
and Bad
# Header
${fwcmd} add pass icmp from any to any icmptypes 3,4,11,12
via ${oif}
# Deny and log the rest of them
${fwcmd} add deny log icmp from any to any
### MISCELLANEOUS REJECT RULES
# Reject broadcasts from outside interface
${fwcmd} add 63000 deny log ip from any to 0.0.0.255:0.0.0.255
in via ${oif}
# Reject&Log SMB connections on outside interface
${fwcmd} add 64000 deny log udp from any to any 137-139
via ${oif}
# Reject&Log all other connections from outside interface
${fwcmd} add 65000 deny log ip from any to any via ${oif}
# Everything else is denied by default, unless the
# IPFIREWALL_DEFAULT_TO_ACCEPT option is set in your kernel
# config file.
|
Now
comes the part I think needs some work, but I am personally not
sure how to resolve the problems I am encountering. I wanted to
run all of these scripts after the system actually had started (i.e.
all of the configurations in rc.conf had been made and the PC Cards
had been recognized), but that actually proved to be more of a problem
than anything and I could never get the scripts to run at the right
time. Since I only want them to run once and they must run after
the cards are inserted and recognized, I didn't know what else to
use besides @reboot in crontab and that did not work. So, for now,
wired.sh and wireless.sh are placed in /etc/pccard.conf - the modified
pccard.conf file - as such (the following are outtakes from the
modified pccard.conf file I am using and are specific to my cards
- also, make sure you copy pccard.conf from /etc/defaults to /etc
and modify it there - if you don't understand why you have to do
this, this is not the article to explain it):
# 3Com Etherlink III 3C589, 3C589B, 3C589C, 3C589D
card "3Com Corporation" "/3C589/"
config
auto "ep" ?
insert /etc/pccard_ether $device start -link0 link1
&& /usr/local/sbin/wired.sh
# insert /etc/pccard_ether $device start link0 -link1
remove /etc/pccard_ether $device stop
|
# Lucent WaveLAN/IEEE
card "Lucent Technologies" "WaveLAN/IEEE"
config
0x1 "wi" ?
# config auto "wi" ?
insert /etc/pccard_ether $device start &&
/usr/local/sbin/wireless.sh
remove /etc/pccard_ether $device stop
|
|
One
other thing to note is that I disabled IRQ 5 at the beginning of
the pccard.conf file because it is actually picked up by the sound
card and creates a conflict with the 3Com PC Card (please be sure
to read the beginning of the file - or man pccard.conf).
It is really important to pay attention
to the above paragraph because it can cause a huge headache when
you aren't expecting it (like last night - trying for 6 hrs to get
this setup to work on a desktop machine with a PC Card reader on
it only to have wi0 constantly run into a "watchdog timeout",
only to find out I hadn't removed the IRQ's from the pccard.conf
file that were being taken by other system components). Make sure
you scour dmesg for all devices and whichever IRQ's are being taken.
Normally, pcccard.conf looks like:
# Generally
available IRQs (Built-in sound-card owners remove 5)
irq 3 5 10 11 15
|
But, on my
system, IRQ 3, 5, 11 (and a few others) were already taken by other
pci/isa devices. When I went to start the Orinoco card, it was taking
IRQ 11, but not crashing (w/ the watchdog timeout) until I tried
to set the wireless configurations. Now, that section of my pccard.conf
looks like:
#
Generally available IRQs (Built-in sound-card owners remove
5)
irq 10 15
|
There are a number of reasons for
having the boot process take place the way it does - for example,
I have the original firewall script of rc.firewall run as open to
make sure that if there are problems during the boot process and
the script for one of the cards hangs, I know it is not the firewall
blocking remote entry into the machine. This may present a small
security issue, but the time between the firewall being open and
closing it up with rc.ipfw is relatively short. This is a vulnerability,
but there are ways to change this so that the firewall is automatically
closed. For my purposes, however, this is what works best.
Also, at the beginning, I have the NAT daemon
turned off. Because the interfaces and firewalling rules are not
applied yet, it is preferable to leave the daemon off at this time.
At this point, you should be able to restart
your computer and have a functioning AP that performs NAT for your
clients. It is necessary to assign your clients static IP's in order
for this to work. I am now working on a design that hands out addresses
via DHCP, but not yet finished. Eventually, I would like to add
IPSEC to this setup, too, but for right now, I am simply happy to
have this running.
Please email
me with questions, comments or suggestions. The address is:
freebsd-ap@stevenfettig.com
Copyright 2002 - Steven N. Fettig
Please feel free to use or ammend this document. However, public
posting of the original or modified forms of this document should
be noted by submission to Steve Fettig at the above email address.
|