October 19, 2004

Wireless router with NetBSD 1.6.2 on Blueberry ibook

Update: 5.11.2004 - removed extra ipf rule that was not required and stopped computers connected to wifi from connecting to lan based servers.

Introduction

A few nights ago I decided I wanted wireless access at home. At the same time, I realised my bank account won't support the purchase of any additional wireless equipment. Its then that I recalled the fact I have a old blueberry laptop, that for one reason or another, runs netbsd. This blueberry ibook was also equipped with an airport card.

Perfect.

This document details (breifly, for I am never good on details) the process I went through of setting up a wireless router with MAC address xltering.

Note that I assume you already have netbsd 1.6.2 or greater installed. How to install netbsd on a blueberry ibook is a complete epic in itself, and frankly, I haven't the faintest idea how I accomplished it. I more or less woke up one morning, and it was booting. Honest.


Interface setup


My network is structured such that there are 2 subnets:
  1. 192.168.0.0/24 for lan
  2. 192.168.1.0/24 for wireless
On the blueberry ibook, gem0 is the lan interface, and wi0 is the wireless interface. Replace all instances of these names as you see fit. These interfaces are configured via the files /etc/ifconfig.wi0 and /etc/ifconfig.gem0 respectively:

steve@eva00::~> cat /etc/ifconfig.wi0
inet 192.168.1.1 up media DS11 mediaopt adhoc nwid g3_bridge
!wiconfig wi0 -c 1
!wiconfig wi0 -p 1
wiconfig wi0 -c 1 causes the airport card to create IBSS, so other wireless devices can see it. -p 1 causes the card to enter into BSS mode. Now this isn't strictly correct, but some how it magically works. If you know why, feel free to let me know! :-)
steve@eva00::~> cat /etc/ifconfig.gem0
inet 192.168.0.4 up netmask 255.255.255.0
media 100BaseTX

Routing and NAT setup


Routing and NAT under netbsd is fairly well documented, so I am just going to be brief:
  1. echo net.inet.ip.forwarding=1 >> /etc/sysctl.conf
  2. echo pass in all > /etc/ipf.conf
  3. echo pass out all >> /etc/ipf.conf
  4. echo map gem0 192.168.1.0/24 -> 0.0.0.0/32 > /etc/ipnat.conf
  5. echo ipfilter=YES >> /etc/rc.conf
  6. echo ipnat=YES >> /etc/rc.conf
  7. shutdown -r now
Note that this is strictly get-it-working-ASAP configuration. Feel tree to tweak them to your heart's content. At this stage, you should be able to get a client to join the network in adhoc mode, and have them ping any machines on your wired network. If you have Internet access, simple set the proper DNS/router parameters.


MAC filtering


For one reason or another, ipf doesn't do MAC filtering, so we are going to do it via ARP tables. It might be nasty, but it works :-)

Basically we map all IP address to some dummy IP, so any one connecting will be royally buggered. To let a trusted host join the network, we will map their IP to their MAC address. I should pointed out that a sufficiently determined attacker can easily capture enough packets to determine both the IP and MAC address required to access the network. This is not the magic bullet, just another fence, and not even a tall one.

The arp utility is used to create our ARP table, and set the router to act as an ARP server on the wi0 interface, so it answers all ARP requests on the 192.168.1.0/24 network. The command
usage: arp -s hostname ether_addr [temp] [pub]
is used to map a hostname (IP) to an ether_addr (MAC), and if the pub keyword is present, it will be published, and the server will act as an ARP server for that host. Now 192.168.1.0/24 has 256 hosts, and doing 256 such commands is a pain. Thankfully arp -f allows us to specify a file containing lines with the same syntax as above, to add entry to the ARP table. But this still requires a file containing 256 lines. Bummer.

Its at this point the legendary laziness of geeks prevails, and arp-deny is thus born. This simply program reads in a file containing trusted hosts' IP and MAC address, and generates output suitable for use with arp. I wrote a simple script to re-create the table, so I can easily add new hosts:
root@eva00::~> cat /usr/pkg/etc/rc.d/arp-deny.sh
#!/bin/sh

# clear the table
/usr/sbin/arp -d -a

# re-generate the arp-deny list
/root/arp-deny/arp-deny 192.168.1. 00:00:00:00:00:00 /etc/arp-allowed > /etc/arp-deny
# re-populate it
/usr/sbin/arp -f /etc/arp-deny > /dev/null 2>&1
Yet another get-it-working-asap hack :-) For reference, here is my /etc/arp-allowed file:
root@eva00::~> cat /etc/arp-allowed
192.168.1.1 00:30:65:09:73:ec
192.168.1.2 00:0d:93:eb:01:11
192.168.1.13 00:80:c8:07:3f:f9
Values has of course been censored :-) To add a new host, simple do
echo IP MAC >> /etc/arp-allowed && /usr/pkg/etc/rc.d/arp-deny.sh
Easy as pie :)


Notes


This really calls for a bridge, but for some reason I could not get a wireless/lan bridge working, so the router option was taken. If you can create a bridge, then by all means, do it. Ignore this method completely.

With the above configuration, in order for your lan (192.168.0.0/24) clients to access their wireless (192.168.1.0/24) siblings, you need to add a static route, either on the machines or on your router, so that they use our router (192.168.0.4) as the gateway when attempting such communication events.


MAC filter is also rather weak. Its strongly encouraged that you read up on WEP and enable it.

Hope this was helpful :-)

Cheers,
Steve