« If you are looking for the original site: | Main | Changes, changes, changes. Hope you like them! »

FreeBSD 4.6 AP - HOWTO

The following is an article I wrote in August of 2002 on how to construct an Access Point using FreeBSD 4.6. The concepts still remain vailid, although I plan to update this howto in the summer of 2003 to make appropriate changes for FreeBSD 5.0. Please email me with any comments or questions.

FreeBSD 4.6 Wireless AP (w/ Firewall & NAT using IPFW)
Laptop Mode
16 July 2002
Last Modified: 9 August 2002
Steven N. Fettig
freebsd-ap@stevenfettig.com
See bottom for details and copyright info.


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

wireless.sh

#!/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

 

wired.sh

#!/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


# 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.

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)

About

This page contains a single entry from the blog posted on March 4, 2003 9:45 PM.

The previous post in this blog was If you are looking for the original site:.

The next post in this blog is Changes, changes, changes. Hope you like them!.

Many more can be found on the main index page or by looking through the archives.

Creative Commons License
This weblog is licensed under a Creative Commons License.