Embedded Linux Access Point
Written By: Adam L. Graham
Date: Jan / 25 / 2007
Equipment:
Qty Description
1 Soekris NET4526 Motherboard (486 133MHz AMD/64MB RAM/64MB CF)
1 Ubiquity SR2 802.11b/g mini pci card (400mW)
1 Pigtail U.FL to N-type female
1 Soekris VPN1411 ecryption card (optional)
1 Download of Pyramid Linux
Start by assembling the components in to the box you have seected to house them. I will assume you have made all the perparations to the box to house the components. After assembly use the Pryamid Linus instalation how to install the OS on to the embedded board.
NOTE: Becareful somecards require 5V and others 3.3V and some motherboards are one or the other and even sometimes both.
Before installing Pyramid Linux, let's boot up the hardware. You will need a null modem serial cable to connect the motherboard to a PC. You will also need a serial communication program, I prefer minicom.
First find out what physical serial ports you have:
$ setserial -g /dev/ttyS[0123]
/dev/ttyS0, UART: 16550A, Port: 0x03f8, IRQ: 4
/dev/ttyS1, UART: unknown, Port: 0x02f8, IRQ: 3
/dev/ttyS2, UART: unknown, Port: 0x03e8, IRQ: 4
/dev/ttyS3, UART: unknown, Port: 0x02e8, IRQ: 3
Well that's easy - there is only one. If there is no UART, there is no serial port. Most modern PCs only have one or two. If there is more than one it might take a bit of trial and error to figure out which one your serial cable is connected to.
Now start up Minicom:
# minicom -s
------[configuration]-------
| Filenames and paths
| File transfer protocols
| Serial port setup
| Modem and dialing
| Screen and keyboard
| Save setup as dfl
| Save setup as..
| Exit
| Exit from Minicom
----------------------------
Select "serial port setup". Your settings should look just like this, except you need to enter your own serial port address:
-------------------------------------------
| A - Serial Device : /dev/ttyS0
| B - Lockfile Location : /var/lock
| C - Callin Program :
| D - Callout Program :
| E - Bps/Par/Bits : 19200 8N1
| F - Hardware Flow Control : No
| G - Software Flow Control : No
|
| Change which setting?
-------------------------------------------
The default serial port speed of Soekris boards is 19200, 8N1. If you select the wrong speed, you'll see all kinds of gibberish characters when you connect.
Next, select the "Modem and dialing" option, and make sure the "Init string" and "Reset string" settings are blank. Finally, select "Save setup as dfl" to make this the default, and then "Exit". This takes you back to the main Minicom screen:
Welcome to minicom 2.1
OPTIONS: History Buffer, F-key Macros, Search History Buffer, I18n
Compiled on Nov 5 2005, 15:45:44.
Press CTRL-A Z for help on special keys
Power up the Soekris, and you'll see this:
comBIOS ver. 1.15 20021013 Copyright (C) 2000-2002 Soekris Engineering.
net45xx
0064 Mbyte Memory CPU 80486 133 Mhz
PXE-M00: BootManage UNDI, PXE-2.0 (build 082)
Slot Vend Dev ClassRev Cmd Stat CL LT HT Base1 Base2 Int
-------------------------------------------------------------------
0:00:0 1022 3000 06000000 0006 2280 00 00 00 00000000 00000000 00
0:16:0 168C 0013 02000001 0116 0290 10 3C 00 A0000000 00000000 10
0:17:0 104C AC51 06070000 0107 0210 10 3F 82 A0010000 020000A0 11
0:17:1 104C AC51 06070000 0107 0210 10 3F 82 A0011000 020000A0 11
0:18:0 100B 0020 02000000 0107 0290 00 3F 00 0000E101 A0012000 05
0:19:0 100B 0020 02000000 0107 0290 00 3F 00 0000E201 A0013000 09
1 Seconds to automatic boot. Press Ctrl-P for entering Monitor.
BootManage UNDI, PXE-2.0 (build 082)
BootManage PXE-2.0 PROM 1.0, NATSEC 1.0, SDK 3.0/082 (OEM52)
Copyright (C) 1989,2000 bootix Technology GmbH, D-41466 Neuss.
PXE Software Copyright (C) 1997, 1998, 1999, 2000 Intel Corporation.
Licensed to National Semiconductor
CLIENT MAC ADDR: 00 00 24 C1 1D F0
PXE-E51: No DHCP or proxyDHCP offers were received.
PXE-M0F: Exiting BootManage PXE ROM.
No Boot device available, enter monitor.
comBIOS Monitor. Press ? for help.
>
So there we are at the comBIOS command prompt. There is no CF card installed, so it automatically entered the BIOS. Otherwise you have to hit Ctrl+P to enter the comBIOS monitor. Let's see what we can do with it by pressing ?:
comBIOS Monitor Commands
boot [drive][:partition] INT19 Boot
reboot cold boot
download download a file using XMODEM
flashupdate update flash BIOS with downloaded file
time [HH:MM:SS] show or set time
date [YYYY/MM/DD] show or set date
d[b|w|d] [adr] dump memory (bytes/words/dwords)
e[b|w|d] adr value [...] enter bytes/words/dwords
i[b|w|d] port input from 8/16/32-bit port
o[b|w|d] port value output to 8/16/32-bit port
cmosread [adr] read CMOS RAM data
cmoswrite adr byte [...] write CMOS RAM data
cmoschecksum update CMOS RAM Checksum
set parameter=value set system parameter to value
show [parameter] show one or all system parameters
?/help show this help
Ok, not so very much. You should make sure the time and date are set correctly. And perhaps take a moment to enjoy the pleasure of connecting to a real serial console, instead of the poor crippled x86 serial console.
Install Pyramid
Download the image file from Metrix. Wget users can fetch it with this command:
$ wget http://metrix.net/support/dist/pyramid-1.0b1.img.gz
Copy it to your CF card with these commands, using your own correct image and /dev names:
# gunzip -c pyramid-1.0b1.img.gz | dd of=/dev/hdc bs=16k
3908+0 records in
3908+0 records out
Very good, it's done.
Finding the /dev Number
What if you don't know the /dev/ number of your flash card? The fdisk command tells the tale. A USB-connected device looks like this:
# fdisk -l
Device Boot Start End Blocks Id System
/dev/sdb1 1 984 991747+ 6 FAT16
An IDE CF reader shows up like a PATA hard drive:
Device Boot Start End Blocks Id System
/dev/hdc4 * 1 4 25000 a5 FreeBSD
If you have an IDE CF reader the card must be plugged in before you boot up, or the system won't see it.
Start Up Pyramid
Unplug the Soekris board. Install the CF card and power it up again. You can follow the boot process in Minicom. By default Pyramid assigns an address of 192.168.1.1 to eth0. On the 4521, this is the Ethernet port immediately to the left of the serial port. Enter https://192.168.1.1 in a Web browser on a neighboring PC and login as root, with the password root. You'll be greeted by the tastefully muted Pyramid Web GUI, as in Figure 1.
Naturally the first thing you'll want to do is change the root password. Do this from the "Edit Users" tab in the Web panel.
Administering Pyramid
Pyramid Linux has practically zero documentation. There are no man or info pages, no user forums or mail lists, and Metrix.net offers only a rudimentary Wiki. Be sure to check out the Wiki first because it has useful installation and FAQ sections. You can get command options with the --help flag, like dnsmasq --help. And, a lot of the old Pebble Linux documentation is still valid.
Pyramid Linux on a Soekris board has three points of entry: the serial console, SSH over Ethernet, and the SSL-protected Web interface. You don't really need the serial console after Pyramid is installed.
The Web GUI is pretty Spartan. It lets you configure the DHCP server, configure network interfaces, do some port forwarding and collect wireless statistics. But you can't create or delete users, bring interfaces up and down, set routes, write iptables rules, view logfiles – you get the idea. In fact if you disable your wireless interface in the Web GUI it will disappear from the page completely – you'll have to edit /etc/network/interfaces to bring it back. (eth0 and eth1 can be disabled without vanishing.) So you're going to need those command-line skills.
Pyramid mounts the root filesystem read-only. This is good for a couple of reasons: it extends the life of your compact flash card, and it might prevent a blunder or two. So what to do when you need to edit some files? No problem. Pyramid comes with two scripts for re-mounting the filesystem as read-write or read-only: /sbin/rw and /sbin/ro. Run /sbin/rw when you need to make some edits, then run /sbin/ro when you're finished.
Iptables Firewall
Building a good Internet-connection sharing firewall is most network admins' #1 job. Pyramid comes with an iptables script that opens Port 22 to the world, plus a lot of things I just plain don't understand. First off we need to make two mac filter lists, one is allowed mac addresses and one is for banned mac addresses, /tmp/whitelist and /tmp/blacklist. The fileformat for the lists is as follows:
00:06:25:2E:56:A0
00:06:25:2E:56:E1
To use these lists simply add the following to your iptables script:
TABLES = "filter nat mangle"
iptables = /sbin/iptables
touch /tmp/whitelist
touch /tmp/blacklist
WHITELIST = `cat /tmp/whitelist | awk '{print $1}'
BLACKLIST = `cat /tmp/blacklist | awk '{print $1}'
# Flush Everything
for TABLE in $TABLES
do
$iptables +t $TABLE -F
$iptables +t $TABLE -X
done
# Default Policy for main (filter) table
$iptables +t filter -P INPUT DROP
$iptables +t filter -P OUTPUT ACCEPT
$iptables +t filter -P FORWARD DROP
# Default Policy for nat table
$iptables +t nat -P POSTROUTING DROP
$iptables +t nat -P PREROUTING ACCEPT
$iptables +t nat -P OUTPUT ACCEPT
# Allow all traffic from existing connections
$iptables -t filter -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
$iptables -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Local Policies
# Allow Local Interface traffic
$iptables +t filter -A INPUT -i lo -j ACCEPT
# Allow from eth0 (wired network)
$iptables -t filter -A INPUT -m physdev --physdev-in eth0 -m state --state NEW -j ACCEPT
# allow connections to httpd
$iptables -t filter -A INPUT -p tcp --dport http -m state --state NEW -j ACCEPT
$iptables -t filter -A INPUT -p tcp --dport https -m state --state NEW -j ACCEPT
# FORWARD POLICY
# ALLOW DNS
$iptables +t filter -A FORWARD -p tcp --dport domain -j ACCEPT
$iptables +t filter -A FORWARD -p udp --dport domain -j ACCEPT
#ALLOW DHCP
$iptables +t filter -A FORWARD -p udp --dport 67:68 -j ACCEPT
# do not apply any rules to packets that have been marked (i.e. known MACs)
$iptables -t nat -A PREROUTING -m mark --mark 0x42 -j ACCEPT
# redirect HTTP requests from unknown MACs to local machine
$iptables -t nat -A PREROUTING -m physdev --physdev-in eth1 -p tcp --dport 80 -j REDIRECT
# forward any packets thave have been marked (i.e. know MACs)
$iptables -t filter -I FORWARD 1 -m mark --mark 0x42 -j ACCEPT
# mark all the packets from the registered MACs
for MAC in $KNOWN_MACS ; do
$iptables -t mangle -I PREROUTING -m mac --mac-source $MAC -j MARK --set-mark 0x42
done
# drop the packets from blacklisted hosts
for MAC in $BLACKLISTED_MACS ; do
$iptables -t mangle -I PREROUTING -m mac --mac-source $MAC -j DROP
done
# do not apply any rules to packets that have been marked (i.e. known MACs)
$iptables -t nat -A PREROUTING -m mark --mark 0x42 -j ACCEPT
# redirect HTTP requests from unknown MACs to local machine
$iptables -t nat -A PREROUTING -m physdev --physdev-in eth1 -p tcp --dport 80 -j REDIRECT
# forward any packets thave have been marked (i.e. know MACs)
$iptables -t filter -I FORWARD 1 -m mark --mark 0x42 -j ACCEPT
# mark all the packets from the registered MACs
for MAC in $WHITELIST ; do
$iptables -t mangle -I PREROUTING -m mac --mac-source $MAC -j MARK --set-mark 0x42
done
# drop the packets from blacklisted hosts
for MAC in $BLACKLIST ; do
$iptables -t mangle -I PREROUTING -m mac --mac-source $MAC -j DROP
done
Host and Domain Name
Change these to your own on the System Services tab. You should leave "Set clock using NTP" enabled, and then edit /etc/ntp.conf. Delete the default entries and replace them with this:
pool.ntp.org
pool.ntp.org
pool.ntp.org
Or if you have a local time server, use that.
DHCP Server
You can configure a simple DHCP server in the Web GUI. It won't let you do anything but set up a range of dynamically-assigned IPs, like Figure 1.
As you can see, the default lease time is 2 hours, which is pretty short. You can't assign hostnames, servers, or static IPs. There's a gotcha here you need to watch out for – you probably don't want to DHCP-serve the world, so make sure that your DHCP server is enabled only on eth0, the default LAN interface.
If you want DHCP to supply static IPs you'll need to configure /etc/dnsmasq.conf. First make sure it accepts requests only from the LAN:
interface=eth0
You can match up IPs to MAC addresses or hostnames. This example assigns the IP, hostname, and lease time to the MAC address:
dhcp-host=11:22:33:44:55:66,server15,192.168.1.25,6h
If you want it to be a permanent assignment, make the lease time infinite. You can assign other options as well, such as NTP servers. This example makes Pyramid the local time server:
dhcp-option=42,0.0.0.0
The number 42 means time server. You'll find all these number codes in RFC 2132. You can dish out mailservers, as this example for alrac.net shows:
localmx
mx-target=server15.alrac.net
mx-host=alrac.net,server15.alrac.net,10
DNS Server
Dnsmasq acts as both a caching nameserver and as a local DNS server. To easily set up local DNS, first create a master /etc/hosts file on Pyramid:
127.0.0.1 localhost pyramid
192.168.1.25 server15
192.168.1.100 workstation1
192.168.1.101 workstation2
192.168.1.102 workstation3
192.168.1.103 workstation4
Then make sure your upstream DNS servers are configured in /etc/resolv.conf:
nameserver 12.34.56.78
nameserver 12.34.56.79
And that's all there is to it; dnsmasq takes care of the rest.
You now have a good stout iptables NAT firewall with name services. Next week in Part 4 we'll make a wireless access point.
Some security-conscious admins prefer using a standalone WAP, rather than combining it with a firewall/gateway. It's simpler to build a dedicated WAP, so that's what we'll do today. You are welcome to put it together however you like.
Adding Applications
Pyramid is based on stock Ubuntu packages. It does not come with any package management tools, not even dpkg, but that's just a small inconvenience. Just boot up the Ubuntu live CD, and copy the binaries you want to your Pyramid box. You'll find out quickly if you need some additional libraries by running the binaries and generating some error messages, or use the ldd command:
$ ldd /usr/bin/arping
linux-gate.so.1 => (0xffffe000)
libresolv.so.2 => /lib/tls/i686/cmov/libresolv.so.2 (0xb7f91000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7e62000)
/lib/ld-linux.so.2 (0x80000000)
To see all the files in a package run dpkg -L [packagename. apt-file search [filename] tells you what package a file belongs to.
Kernel modules can be copied in the same manner; just remember to run modules-update so that Pyramid can find them. Then do the usual fiddling with modprobe or /etc/modules to load them.
You might even consider building a custom kernel with everything statically-compiled, and leaning it down to just what you need. Start by copying /proc/config.gz as a starting config-2.6* file.
The Web GUI has limited configuration functionality, and it's going to stay that way. A nice feature of the Web GUI, according to Mr. Westervelt, is "...it uses the standard config files on the box. If you are a keyboard cowgirl, you won't have to worry about some hidden directory that is switching everything back to Web defaults. If you are hand-editing and want to use the Web GUI later, you should take care to read the comments in the files."
Supported Wireless NICs
Our example board has an Atheros 5004 802.11b/g mini-PCI Atheros and Prism are good wireless chipsets for a Linux access point because both support HostAP mode. Not all WICs can do this. Both are well-supported in Linux. The nice folks at Atheros support the development of open source drivers. The Prism overlords do not, forcing the excellent Prism54 devs to reverse-engineer everything.
The MadWiFi driver has a closed binary hardware abstraction layer (HAL). The rest of it is dual-licensed under both the GPL and the BSD license. The closed binary bit is there to meet FCC regulations. See Madwifi.org/wiki/HAL for details.
Building Bridges
Because a device with multiple network interfaces must assign each interface to a different subnet, we can't just slap stuff together and watch it work. We have to build an Ethernet bridge between the wireless and the wired NICs. There are also a number of Pyramid Linux-specific tweaks, so follow along carefully.
This is a complete example /etc/network/interfaces file. Copy this exactly, except you must substitute your own LAN addressing and ESSID:
#/etc/network/interfaces
#simple bridge between
#eth0 and ath0
auto lo
iface lo inet loopback
auto br0
iface br0 inet static
address 192.168.1.10
network 192.168.1.0
netmask 255.255.255.0
broadcast 192.168.1.255
gateway 192.168.1.1
bridge_ports ath0 eth0
post-down wlanconfig ath0 destroy
pre-up wlanconfig ath0 create wlandev wifi0 wlanmode ap
pre-up iwconfig ath0 essid "alrac-net" channel 01 rate auto rts off frag off
pre-up ifconfig ath0 up
pre-up sleep 3
That's right, that's the whole thing. The default file comes with configurations for every possible network interface, which just get in the way. Chuck 'em all and start over. This configuration treats br0 like an ordinary Ethernet interface, and allows you to connect to it like any other host on your LAN. It has all the standard network settings including your Internet gateway, so your wireless clients have Internet access.
DHCP With dnsmasq
Pyramid defaults to using dnsmasq for name services, which is a nice thing. dnsmasq is compact and simple to use. The first thing to do is to disable dhcrelay, because it will derail wireless clients from getting a DNS server from dnsmasq. Go into /etc/rc2.d and change the dhcrelay link from Start to Kill. Remember to change the filesystem to read-write first:
pyramid:~# rw
pyramid:~# mv /etc/rc2.d/S20dhcrelay /etc/rc2.d/K20dhcrelay
Now edit /etc/dnsmasq.conf. It's a big file chock-full of useful comments, so the easy way is to rename the existing file and then create a new empty one:
pyramid:~# mv /etc/dnsmasq.conf /etc/dnsmasq.conf-old
pyramid:~# nano /etc/dnsmasq.conf
Populate it with these entries. Use your own DNS servers for "server", your own domain name, and your own addresses for the DHCP range:
domain-needed
bogus-priv
server=12.34.56.78
server=12.34.56.79
local=/localnet/
bind-interfaces
expand-hosts
domain=alrac.net
dhcp-range=192.168.1.100,192.168.1.200,255.255.255.0,10h
dhcp-lease-max=100
no-negcache
And now (drum roll) you may reboot. When it comes up back try connecting from a client machine.
dnsmasq does not have the usual startup files in /etc/init.d, but instead is started from /etc/inittab.
Connecting Securely
Now what? Well, you probably want to encrypt your connection, especially since your wireless clients are inside your firewall. If you are fortunate to have devices that are "Wi-Fi CERTIFIED" they support WPA2, which is a good thing. WPA2 provides strong encryption and is easy to administer.
If you have older WICs like my Prism I, which is not upgradeable to WPA2, there are still a number of options, like SSH tunneling and OpenVPN tunnels. See Resources for a number of articles on locking down your wireless network.
This is not a good setup for providing wide-open wireless access to the world. Pyramid comes with both NoCat and WiFiDog, so if you feel led to provide wireless Internet for the masses, use these and segregate the wireless network from your wired network. Unless you like being naked and helpless on the Internet.
Wireless
Calculators
Free Space Loss Calculator
mW and dbm Converter
Fresnel Zone Calculator
Tx Power Calculator
Operating System Margin
ERP Calculator
Range Calculator
Helix Antenna Calculator
WEP Key Generator
![]()
Antenna Designs
Yagi Directional Antenna
Colinear Omnii Directional Antenna
5dbi Colinear Omnii Directional Antenna
Helical Directional Antenna
Bi Quad Directional Antenna
![]()
Hardware
Linux Access Point
OpenBSD/OpenVPN Access Point
Embedded Linux Access Point/Router/Firewall
![]()
Standards
802.11 Standards