HOWTO Building a Wireless Access Point
From Gentoo Linux Wiki
Please format this article according to the guidelines and Wikification suggestions, then remove this notice {{Wikify}} from the article
WARNING: This page needs a bunch of work! Although I've started making this article less specific to the Prism54 cards by separating out the first section, I haven't gotten around to doing any of the later sections yet - they need the Prism54 commands separated out from the generic bits, and stuff for the other cards added. Please help improve this page - if you're trying to get any other cards running as a basestation under Gentoo please feel free to make any appropriate edits. Email me if you'd like any help - if you're in the middle of a new build you should probably remind me that I thought it would be a good idea to give you my IM details so I can respond quickly. |
If you have any comments or suggestions, feel free to email me.
[edit] Purpose of this Document
Many drivers these days automatically create an Access Point, but some will need to create their own if they have to use an older driver or if they want to use multiple Access Points. The Access Point also called in some places the "Interface" is the client, software created, viewport to a wireless network. It is necessary to have one to connect wireless network (Station).
[edit] Buy a wireless card that supports "master mode"
What we need for a wireless "base-station" or "access-point" is a wireless network card that does "master mode", which allows our Linux box to behave just like products from the likes of Linksys, Netgear & Belkin - later sections of this HOWTO should be pretty much the same whether you can find a 802.11a, 802.11b or g card that does master mode in Linux.
Do be careful when buying a card for this project - WLAN cards documented as Linux-supported often become no longer available and it's not uncommon for manufacturers of wireless cards to sell completely different cards with a completely new chipset under the model number of a card that is already currently sold. I guess this saves them the trouble & expense of having new packaging & advertising printed, but it causes copious confusion for the Linux-loving enthusiast. Also look out for D-Link's evil naming conventions - the 3 different revisions of the DWL-520 are all different from the DWL-520+, which is different from the DWL-G520, which is different from the DWL-A520 and so on... when you throw into the mix the 8 different cards with "DWL" and "650" in their names it can give you a headache just trying to work out which one your supplier is listing, never mind installing the drivers.
[edit] Prism (HostAP)
Note that cards using these drivers are 11MBPS only.
Jason Boxman provides quite an excellent description of these drivers: HostAP enables 802.11b access point functionality utilizing the secondary (STA) firmware of Intersil's Prism2, Prism2.5, or Prism3 chipsets for time sensitive tasks. All other functionality is handled via the driver, including WEP and passing frames off to a port authenticator, like FreeRADIUS. Presently, HostAP works with Intersil's Prism chipset and cards utilizing PCI and PC Card interfaces to the host system. (PLX bridging is also supported) |
[edit] Atheros (Madwifi)
Atheros chipset cards can use the MadWifi drivers and tools. After making sure that you have the appropriate kernel support for wireless (not any particular chipset drivers), emerge the madwifi-ng package.
Code: Installing Madwifi driver |
|
The card will enter standard mode by default, but you want to bring the driver up in master mode. To accomplish this, you need to edit the module options. Note that the default behavior of etc-update will be to remove this customization, so remember to do what is necessary to keep your changes after re-emerging madwifi-ng (say, after a kernel compile).
File: /etc/modules.d/ath_pci snippet |
|
This is the old way of setting Atheros-based cards into master mode: Setting the driver into master mode is not done in the standard way; you have to take the interface down, destroy it, and rebuild it in the new mode, which goes by the name 'ap' rather than 'master.' Here's how that works: ifconfig ath0 down wlanconfig ath0 destroy wlanconfig ath0 create wlandev wifi0 wlanmode ap
You could also skip the 0 in the last command, as wlandev will choose the first available integer if none is supplied. The benefit of this tool seems to be that you can create an arbitrary number of virtual ath interfaces, which could presumably be used to service multiple seperate lans with different access control and/or features. In any case, once you've created the new device in mode 'ap' you should see it in the output from iwconfig and it should say "Mode:Master" |
Note that in all the rest of the configuration you should use the 'ath0' device, rather than 'wifi0' which appears to just be a container for the rest of the stuff.
This is all just what I've learned trying to set mine up....you should probaby go to http://madwifi.org and read through their wiki and userdocs.
Tip: If you get the error "Could not connect to kernel driver" (when trying to start hostapd) look in your hostapd.conf if you have enabled encryption because if you haven't the interface isn't started correctly. For details:
Madwifi Trouble Ticket.
[edit] NDISwrapper
NDISwrapper cards are NOT SUITABLE for base-station use - they don't do master mode. NDISwrapper is basically a layer of interfacing glue to use Windows drivers with Linux, and so it denies access to some of the more interesting &/or esoteric functions of the wireless card (because NDIS has no programming interface for them, I guess).
If you have a wireless card that you're currently using with NDISwrapper then it's possible that there are native drivers for it - I've seen quite a few posters to the Ubuntu forums suggesting using NDISwrapper with Ralink cards, for instance - but it's more likely that you'll have to bin it (or put it in your sister's Windows PC) and get a card with native drivers that interface properly with the kernel. NOTE: You can accomplish a similar goal with an Ad-Hoc network; this might help.
[edit] Prism54
I wanted a card that supported the Prism54 drivers, as they seemed to be about the most mature ones for "54G" wireless cards under Linux at the time I was looking - my Powerbook has Airport Extreme, Apple's name for 802.11g, so I might as well make use of it. I took a good look through the supported cards and decided upon the Allnet ALL0271. It seemed to be fairly well-recommended on the Prism54.org forums - there are too many short comments saying "worked for me" for me to post all the individual links, so do a search & read all the threads for yourself.
You can order the ALL0271 from the US, from Germany or if you're in the UK, I actually bought a handful, so email me if you'd like to buy one. I also recently got one of these cards working on a friend's SuSE 9.1 box, although the process isn't as brain-dead as it is under Gentoo - portage & the ebuilds automate the process so well.
[edit] Ralink rt2400 / rt2500
As I see on the rt2x00 project page, the new branch rt2x00 beta drivers support master mode and all advanced features, but legacy rt2400, rt2500, rt2570, rt61 drivers do not, but I have no way to test such setup.
For more details on this driver see the project homepage.
[edit] Broadcom 43xx cards (bcm43xx.ko)
Broadcom cards support master mode using the reverse-engineered kernel driver. You need to enable (or make as a module) the Softmac wireless extensions and BCM43xx wireless driver.
[edit] Realtek RTL8180 cards (rtl8180-sa2400 project)
Master mode is working correctly together with promiscuous mode, but there are problems with Wireless Extensions with version available in Portage together with kernels >=2.6.19 and the card may be handled incorrectly by init scripts. Supports WEP open encryption and possibly TKIP/CCMP(not tested). Broken with new(2.6.20+) kernels. Supports only 1/2/5.5/11M modes.
[edit] Texas Instruments ACX100/ACX111
In cards based on this chip (ex. D-Link DWL-520+) master mode is not fully implemented (as of 2007-01-01 driver) and there are some different problems like sometimes no beacons are broadcasted and card can't be properly initiated. Supports 1/2/5.5/11M(b) and 22M(b+) modes.
[edit] Intel PRO/Wireless (ipwXXXX) series
For ipw2100/ipw2200, unfortunately there is no way to use them as AP, but this can be done for ipw3945 and ipw4965, maybe ipw2915 too, which are pretty good cards anyway, using fully open-source iwlwifi drivers, but it can't be done with old Intel drivers with closed microcode.
[edit] Build a base Gentoo system
I'm assuming you've built Gentoo before - I just followed the Gentoo Quick Install Guide.
In order to run your WiFi drivers you need a couple of options enabled in your kernel, so you might as well do this during your original build. Look for:
CONFIG_HOTPLUG=y
Bus options (PCI, PCMCIA, EISA, MCA, ISA) --->
Support for hot-pluggable devices
CONFIG_FW_LOADER: m/y (either one will work)
Generic Driver Options --->
Hotplug firmware loading support
CONFIG_NET_RADIO=y
Device Drivers --->
Networking support --->
Wireless LAN (non-hamradio) --->
This is because:
from /usr/src/linux/drivers/net/wireless/Kconfig Saying Y here also enables the Wireless Extensions (creates /proc/net/wireless and enables iwconfig access). The Wireless Extension is a generic API allowing a driver to expose to the user space configuration and statistics specific to common Wireless LANs. The beauty of it is that a single set of tool can support all the variations of Wireless LANs, regardless of their type (as long as the driver supports Wireless Extension). Another advantage is that these parameters may be changed on the fly without restarting the driver (or Linux). [This is handy for wireless PCMCIA (PC-) cards] |
Now it's time to find and enable your drivers.
To determine type of your card,
emerge pciutils if you haven't done before,
and lspci.
You'll have to look under Wireless LAN category mentioned above, or in the portage, in the net-wireless category. Sometimes, when you choose to use driver from kernel, you should also pull in firmware for your card from portage, but not for every card.
To install in-kernel driver enable it either statically or as a module, by pressing y or m over desired item, then recompile and install new kernel or kernel modules.
If you want to use driver outside of kernel tree, proceed to next section.
[edit] Emerge the nitty-gritty
If you want to use driver outside of the kernel tree, you'll have to find it in portage, for example:
Some of driver package are available only with testing keyword, others (ex. rt2x00) require setting USE flags. In that case:
Of course replace package names, categories and use flags with ones you need.
Finally, if you don't use coldplug or udev coldplugging, and you want your driver to be loaded at startup, add right module to right file in /etc/modules.autoload.d/.
The ebuild is clever enough to pull in everything else it needs:
- wireless-tools - uh, what it says. Remember the bit in /usr/src/linux/drivers/net/wireless/Kconfig about "a single set of tool can support all the variations of Wireless LANs"?
- hotplug - needed to "upload the firmware to the NIC's ram on initialization"
So now you're ready to go. Neither of the above should be masked, but if they are add them to /etc/portage/package.keywords the same as you did for the driver itself above. If you've chosen just to use the drivers supplied with your kernel then you'll need to emerge these two ebuilds separately.
[edit] First tests - checking your wireless card works
[edit] The technical way:
Code: Checking the card is recognized with iwconfig |
|
In this example eth0 is my wired Ethernet 10base100 network card, probably a Realtek 8139 or an Intel ee100 I had lying around. I compile drivers for the most common types of network cards - any I recognise the name of when I'm doing make menuconfig - statically into the kernel.
It's fairly obvious from the above that eth1 is the wireless card - I hear some folks like to name their wireless interface wlan0 or whatever, but for the life of me I couldn't get this to work. So note now which interface name iwconfig is showing for your wireless card, because you'll need it later on.
[edit] The melodious way:
I tried this hunched over my Macintosh with Kismac listening to its Airport card:
ifconfig eth1 up
BING-BONG! My network stumbler detects a new wireless entity! Macs make melodious announcement noises at every opportunity, you see.
iwconfig eth1 mode Master essid foobert channel 11
BONG-BING! The network stumbler indicates that the network called "foobert" on channel 11 is managed.
iwconfig eth1 essid foobert channel 11 key aabbccdd
BLOOOOP! The network stumbler shows the "foobert" network to have WEP encryption.
So now you know that your WLAN card works and that your kernel & modules are compiled correctly & stuff. If these tests don't work, go away now & have a think why that might be.
[edit] Ensure you have a baselayout which handles wireless config
Well, I don't really like using stuff which isn't in stable, but at the time of writing Roy Marples' work on wireless networking configuration is only just being integrated into the Portage tree.
I started this HOWTO with the intention that it should be entirely independent of Roy's documentation and that it should simply describe building a wireless AP the best way possible. Clearly "the best way possible" means conforming with Gentoo-Portage & ensuring maximum compatibility & future-proofing - there's no point in building our own init configuration scripts if there's already a blueprint for this in Gentoo's baselayout.
So:
Code: Marking a testing baselayout as stable |
|
At the time of writing you may need to do the same with sys-apps/sysvinit, sys-libs/readline and app-shells/bash in order to satisfy dependencies.
I can see why Roy's work is being integrated into official Gentoo - it's really nice. I advise you to take a look at and revise the contents of /etc/conf.d/net - /etc/conf.d/net.example makes very good reading.
[edit] Set-up the wireless interface
You'll need to do this first:
cp -R /etc/init.d/net.eth0 /etc/init.d/net.eth1
The "-R" option causes the `cp` to act upon the symlink, rather than following it to the original file.
Here's all the configuration for the wireless interface - eth1 was indicated by iwconfig earlier:
File: /etc/conf.d/wireless |
|
You can alternatively put this is /etc/conf.d/net - both files seem to be parsed equally by the init scripts. They also have the same format, which I didn't initially realise from reading /etc/conf.d/wireless.example - /etc/conf.d/net.example is also worth perusing. You might wish to choose another channel - 6 and 11 are common, so you might find your neighbours are already using those.
Madwifi Some madwifi-specific settings you can put in your network configuration are: # Set the card's 802.11a/b/g mode: # Mode 0 = Autoselect (not sure if this is proper for an AP) # 1 = 802.11a # 2 = 802.11b # 3 = 802.11g iwpriv_ath0="mode 3"
# Suppress ssid broadcast: iwpriv_ath0="hide_ssid 1"
# Configure multiple iwpriv settings (example). iwpriv_ath0=( "mode 3" "hide_ssid 1" )
|
NOTE: Mode 0 is proper for an AP. In this mode client will determine speed. For example if I use B card it works in B mode and if I use G or SuperG card it works properly.
If you've compiled your wireless driver as a module, don't forget to ensure that it's loaded at boot:
# echo prism54 >> /etc/modules.autoload.d/kernel-2.6
Substitute ath_pci for prism54 if you're using the Madwifi driver.
And you'll probably want to bring the wireless interface up at boot, too: # rc-update add net.eth1 default
If I now run `/etc/init.d/net.eth1 start`, a message pops up on my Powerbook asking if I'd like to join the unsecured wireless network "MyNet". Cool! I test everything by rebooting the machine, to make sure I've remembered to type everything so far correctly.
At this point you'll need to set up the IP address manually on your laptop, but you should be able to ping the access-point from it. Make sure you set up the laptop you're testing with to be on the right subnet - I chose 192.168.0.1/255.255.255.0 for the IP of my access-point, so I'll need to choose an 192.168.0.XXX address for the laptop.
Code: Pinging the access point |
|
[edit] Simple NAT-forwarding setup
At first I'm just going set up simple NAT, which does just the same thing as the basic commercial access-points out there. I got this pretty much straight from The Gentoo Home Router Guide, so if you have any problems with this, the best place is to look there. Here's the essentials, but you should consider putting a bit more in there, like the way vapier does it.
Note also how vapier saves his configuration for future boots:
If you set a valid DNS address on your laptop, you should be able to surf the web! Of course, since you've been looking at the Home Router Guide, you'll probably be thinking about setting up DHCP & DNS servers on your access-point right about now.
[edit] Enabling WEP encryption
Now that we have a usable setup, we'd better enable some encryption, so our neighbours don't start making free with our connection - we don't want them watching all our pr0n, now, do we?!?
I've found two ways to generate a WEP key from the command-line; the more traditional way would involve cat /dev/random and piping it somewhere, but when I did this a few times to get the syntax right I found that I ran out of entropy pretty quick.
Since we all have OpenSSL installed (and you would think that OpenSSL's random number generator might be particularly good, anyway) here's how I obtained a random WEP key:
Code: Generating a random WEP key |
|
There are loads of pages on the web that will generate a WEP key randomly for you, but I wanted to do it entirely from the terminal, to save you copying & pasting from a web-browser & to learn stuff; I found it quite interesting. man openssl explains that openssl rand 13 generates 13 "pseudo-random bytes" and the xxd command converts these bytes into a hex string. The next line adds the random string to /etc/conf.d/wireless in a suitable format for the init scripts to parse it, and finally we need to see what the key is, so we can make a note of it & enter it on our laptop.
The above generates a "128-bit" WEP key - actually, the "13" indicates that you're actually only generating 8 x 13 = 104 bits, but in fact there are another 20 non-random bits on each WEP key, so the name is a bit of a misnomer. If you want a WEP key of only 64 bits 40 bits, then change the 13 to 5.
If you restart the interface, your laptop should now tell you that MyNet is a secure network and ask you for the key - I hope you remembered to take a note of it!
[edit] WPA Encryption
It's possible to use WPA encryption together with master mode, but as it requires hostapd, it can be only supported on Prism and Atheros-based cards In future, maybe it could be used with any card using Mac80211 stack. It can support anything from dynamic WEP through WPA-PSK to WPA2 (RSN) with AES/CCMP encryption with RADIUS accounting.
Check out
[1] for more information.
[edit] Bridging the wired & wireless segments
Our setup will work great so far if you're plugging an Ethernet cable-modem into the wired NIC & only using wireless clients with it - but there are some things it doesn't do so well. If we have one machine connected to the router's wired port & another connecting wirelessly, we won't be able to stream iTunes between them, for instance - that requires them both to be on the same subnet.
If you're only using two interfaces so far, then flush out all the stuff from the simple NAT setup, if applicable:
Code: Flushing ipTables rules & disabling NAT forwarding |
|
You'll need to get the bridging tools - the init.d scripts depend upon these:
emerge bridge-utils
And ensure that your kernel supports bridging:
CONFIG_BRIDGE=y
Device Drivers --->
Networking support --->
Networking options --->
<*> 802.1d Ethernet Bridging
NOTE: I found this under:
Networking --->
Networking support --->
Networking options --->
<*> 802.1d Ethernet Bridging
Your /etc/conf.d/net will require a complete overhaul - probably best to back it up first! I've moved all the wireless options from /etc/conf.d/wireless, which I no longer use, as I prefer to have all the options for the bridge in one place.
File: /etc/conf.d/net settings for a bridge with 2 interfaces |
|
Finally, we need to put the bridge in the default runlevel - eth0 & eth1 will also need to remain there, because of the bridge's depend statement above. -- Comment: I took the interfaces that make up the bridge out of the default runlevel, and the bridge successfully brings them up before coming up itself (probably due to the presence of the depends statement).
Code: Placing the bridge in the default runlevel |
|
The best way to test is to reboot - you should be able to ping across the bridge without needing any forwarding enabled.
In the example below I'm sitting at my desktop computer, 192.168.1.71 and ping first the bridge and then a laptop connected to the wireless network. Notice how the first ping response from the laptop is delayed, as the bridge initialises its stuff.
If you now open iTunes on both machines & ensure that Sharing is enabled in Preferences, they should now each show up as a shared library on the other machine, indicating that Rendezvous is working across the bridge. You should now be able to stream music between the wired & wireless segments!
If you have more interfaces, you could of course create NAT on the interface not in the bridge, so computers on wireless and wired segments not only see each other, but also have Internet access, in case of having only one IP, exactly the same way as written in NAT section
[edit] Known problems
[edit] Unwanted IP-based bridge filtering
Sometimes after bridge is being set up, only ARP and STP packets are coming through the bridge. The first symptom is that PCs from the other side of the bridge are in the ARP caches but no communication is possible, and communication with the bridge itself is possible. Try pinging hosts on the other side of the bridge and then run:
arp -a
It applies not only to wireless bridging. It's fault of Bridged IP/ARP filtering enabled which lets iptables/arptables see and manipulate bridged traffic. To fix it we have to either disable the following in kernel option in kernel:
CONFIG_BRIDGE_NETFILTER=y
Networking --->
Networking support --->
Networking options --->
Network packet filtering (replaces ipchains) --->
[ ] Bridged IP/ARP packets filtering
Or we have to disable some "features" in /proc/sys/net/bridge:
Code: Disabling netfilter on bridge |
|
And don't forget to add some lines to /etc/sysctl.conf so everything is correct on boot:
[edit] Wireless card is unable to transmit packets with other source MAC than it's own
Sometimes only packets transmitted from wireless segment are forwarded to wired segment but do not in opposite direction. The cause of it is a "feature" of wireless NIC, that it can't transmit packets with other source MAC address than it's own.
This is most probably dependent on card's firmware as EXACTLY the same chips are used in commercial hardware APs.
If you know which cards/chips/drivers suffer this problem, please write it!
To fix it we'll need ebtables. Assuming you have already configured your bridge, you have to enable ebtables in your kernel if you didn't already:
CONFIG_BRIDGE_NF_EBTABLES=y
Networking --->
Networking support --->
Networking options --->
Network packet filtering (replaces ipchains) --->
Bridge: Netfilter Configuration --->
<M> Ethernet Bridge tables (ebtables) support --->
<M> ebt: broute table support
<M> ebt: filter table support
<M> ebt: nat table support
<M> ebt: snat target support
I would also recommend enabling other filters/targets, but possibly you'll have to use the fix written before.
Don't forget to recompile and set up the kernel or to load apropriate modules.
The next thing you have to do is:
emerge ebtables
After emerge completes, we have to know the MAC address (HWAddr) of WLAN card. Assuming your wireless card is eth1, to get it type: ifconfig eth1 And lastly, enable the MAC Source NAT:
Code: Enabling MAC address Source NAT |
|
Alternatively, use this script to automatically create the rule, don't forget to replace eth1 with correct interface name
As of ebtables-2.0.8.2 there is an official init script which I made, utilizing ebtables-save and ebtables-restore so saving and restoring configuration is pretty easy.
Code: Saving rules and adding ebtables to default runlevel |
|
Now everything should be working fine.