# HOWTO: Linux Router + Wireless Access Point

## Ryan@warpfive

HOW-TO: Linux Router with Wireless Access point in Bridged Mode

This how-to outlines the steps I used to construct a Linux box using Gentoo to give me a single box that will act as a  wireless access point, a router, web server and e-mail server. 

This document pulls together bits from the many how-tos Ive read on the subjects of wireless access points and router setups. Links to all the relevant source material is at the end of this document. Many thanks to those authors who publish their work for others like me to use.

I already had a Linux box running as my e-mail and web server which is made up of

VIA EPA-PD 600 MHz CPU

512MB RAM

Laptop hard disk (20GB)

Slimline CD-ROM

To this I added:

Dynamode ADSL PCI Modem (M-ADSL-PCI-C1)

Netgear WG311 Wireless Network Card (PCI)

Active Riser card to allow both PCI cards to be used with the VIA motherboard

The Kernel

To start with the Kernel needs to be configured to support all the drivers. At the time of writing I use version 2.6.14.2 from the vanilla tree. Make sure you have the following options compiled in or as modules:

```

General setup

  -> Sysctl support (CONFIG_SYSCTL)

Processor type and features

  -> Preemption Model 

    -> No Forced Preemption (Server) (CONFIG_PREEMPT_NONE)

Networking

  -> Generic IEEE 802.11 Networking Stack (CONFIG_IEEE80211)

  -> IEEE 802.11 WEP encryption (802.1x) (IEEE80211_CRYPT_WEP)

  -> IEEE 802.11i CCMP support (CONFIG_IEEE80211_CRYPT_CCMP)

  -> IEEE 802.11i TKIP encryption (CONFIG_IEEE80211_CRYPT_TKIP)

Networking

  -> Networking options

    -> Network packet filtering (replaces ipchains) (CONFIG_NETFILTER)

    -> 802.1d Ethernet Bridging (CONFIG_BRIDGE)

Networking

  -> Networking options

    -> Network packet filtering (replaces ipchains) (CONFIG_NETFILTER)

      -> Bridged IP/ARP packets filtering (CONFIG_BRIDGE_NETFILTER)

Device Drivers

  -> Network Device Support

    -> Wireless LAN (non-hamradio)

      -> Wireless LAN drivers (non-hamradio) & Wireless Extensions (CONFIG_NET_RADIO)

Device Drivers

  -> Network Device Support

    -> PPP (point-to-point protocol) support (CONFIG_PPP)

    -> PPP filtering (CONFIG_PPP_FILTER)

    -> PPP Deflate compression (CONFIG_PPP_DEFLATE)

    -> PPP BSD-Compress compression (CONFIG_PPP_BSDCOMP)

    -> PPP over ATM (CONFIG_PPPOATM)

Cryptographic options

  -> Cryptographic API (CONFIG_CRYPTO)

```

In order to build the Connexant Drivers the kernel cannot have the following options enabled. So make sure the following are not selected:

```

Processor type and features

  -> Symmetric multi-processing support (CONFIG_SMP) 

  -> Use register arguments (EXPERIMENTAL) (CONFIG_REGPARM)

```

Then save, build and install the new kernel.

Wireless Communications

I started with the wireless side of things as I thought this would give me the most problems. To start with the company I ordered the Netgear card with sent me a v3 card which is not currently supported by anything other than ndiswrapper. After sweet talking a friend I managed to swap the new v3 for an original v1 which is supported by the madwifi drivers. 

The emerge for Gentoo is masked and appears to be a bit old so I opted to download and compile the drivers manually. Grab the latest code from http://snapshots.madwifi.org/madwifi-ng-current.tar.gz then unpack the archive 

```
tar xzvf madwifi-ng-current.tar.gz
```

Change into the driver directory, for me this was madwifi-ng-r1365-20051222 and do 

```
make clean && make
```

If everything builds OK then run 

```
make install
```

 to install the drivers. Now the moment of truth run 

```
modprobe ath_pci
```

 to activate the driver and when you type 

```
dmesg
```

 you should see something like this

```

ath_hal: module license 'Proprietary' taints kernel.

ath_hal: 0.9.16.3 (AR5210, AR5211, AR5212, RF5111, RF5112, RF2413, RF5413, DFS)

wlan: 0.8.4.2 (Atheros/multi-bss)

ath_rate_sample: 1.2

ath_pci: 0.9.4.5 (Atheros/multi-bss)

wifi0: 11b rates: 1Mbps 2Mbps 5.5Mbps 11Mbps

wifi0: 11g rates: 1Mbps 2Mbps 5.5Mbps 11Mbps 6Mbps 9Mbps 12Mbps 18Mbps 24Mbps 36Mbps 48Mbps 54Mbps

wifi0: H/W encryption support: WEP AES AES_CCM TKIP

wifi0: mac 5.6 phy 4.1 radio 1.7

wifi0: Use hw queue 1 for WME_AC_BE traffic

wifi0: Use hw queue 0 for WME_AC_BK traffic

wifi0: Use hw queue 2 for WME_AC_VI traffic

wifi0: Use hw queue 3 for WME_AC_VO traffic

wifi0: Use hw queue 8 for CAB traffic

wifi0: Use hw queue 9 for beacons

wifi0: Atheros 5212: mem=0xde010000, irq=11

```

If you do then your wireless card has been detected correctly and its time to test it. Run 

```
wlanconfig ath0 create wlandev wifi0 wlanmode ap
```

to create an access point virtual interface to the madwifi driver. Now configure the access point to have a station id 

```
iwconfig ath0 essid "StationId"
```

and use ifconfig ath0 <IP address> netmask <netmask> up to give ath0 a valid presence. At this point use a different ip and subnet mask for example normally I use 10.10.12.x for my internal lan so for the access point I used 

```
ifconfig ath0 192.168.5.1 netmask 255.255.255.0 up
```

Using you wireless client, i.e laptop etc. fire it up and scan for the access point. If you used the example as above then you should see an access point called StationId and if you hard code the ip address to say 192.168.5.2 then you should be able to happily ping from laptop to Linux box and back again. 

With that working for the moment take the wireless down 

```
ifconfig ath0 down
```

WEP Encryption

NOTE: The key provided in the section was generated from the phrase SampleWepKey1 using the website in the references section. It should be changed when you finalize everything or generate yourself a new one now!

Enter 

```
iwconfig ath0 enc 5361-6d70-6c65-5765-704b-6579-31
```

to setup and WEP encryption key, then do 

```
ifconfig ath0 up
```

After you have done this use the laptop again and scan for the access point again. Now you will see you need to provide a key to connect now. Enter the hex string used above but without the dash characters and again you should be able to connect and ping from the laptop to the Linux box and back again.

Bridging And Automation

Ok so we have a wireless and wired connections to our Linux box but they are on different subnets and wont directly talk to each other for things like iTunes sharing etc. To do this we need to build a bridge but we also need to automat the access point setup process. Before you start backup /etc/conf.d/net as we will heavily alter this file, in fact it might be easier to start with a new file and the configuration below.

```

# /etc/conf.d/net:

# $Header: /home/cvsroot/gentoo-src/rc-scripts/etc/conf.d/net,v 1.7 2002/11/18 19:39:22 azarah Exp $

# Global config file for net.* rc-scripts

# This will create the madwifi virtual interface to the wirless nic when ath0 is started

#

preup() {

        if [ "${IFACE}" = "ath0" ]

        then

                /usr/local/bin/wlanconfig ath0 create wlandev wifi0 wlanmode ap

                return $?

        fi

}

# This deletes the madwifi virtual interface when ath0 is stopped

#

postdown() {

        if [ "${IFACE}" = "ath0" ]

        then

                /usr/local/bin/wlanconfig ath0 destroy

        fi

}

# Bridge the wired interface (eth0) to the wireless network (ath0).

bridge_br0=( "eth0" "ath0" )

# Clear any configuration data for both wired and wireless interfaces

config_eth0=( "null" )

config_ath0=( "null" )

# Set the bridge ip address

# Change this to match your private network e.g. 192.168.1.5/24 = 192.168.1.5 netmask 255.255.255.0

config_br0=( "10.10.12.5/24" )

# The bridge relies on the configuration of both eth0 and ath0

depend_br0() {

   need net.eth0 net.ath0

}

# This is the iwconfig commands to configure the wireless card

#

# Use the iwconfig tool

modules_ath0=( "iwconfig" )

# Set the operation mode to be master so the card behaves as an access point

mode_ath0="Master"

# The station name to use

essid_ath0="StationId"

# The channel to brodcast on

channel_eth1="1"

# WEP key

key_StationId ="53616d706c655765704b657931"

```

The comments should explain the new net file quite well and it should to obvious which bits to alter if you need to. We do not set a default route in here as this will be set when PPPD is activated and if one is specified for the bridge PPP will not override this even if you set defaultroute in /etc/ppp/options. Setup an initialisation script for both the wireless and bridge interfaces by doing the following

```

cp /etc/init.d/net.lo /etc/init.d/net.ath0

cp /etc/init.d/net.lo /etc/init.d/net.br0

rc-update add net.ath0 default

rc-update add net.br0 default

```

Reboot and when the box restarts login. If you run ifconfig you should see something like this:

```

ath0      Link encap:Ethernet  HWaddr 00:09:5B:89:9F:0D

          UP BROADCAST RUNNING PROMISC MULTICAST  MTU:1500  Metric:1

          RX packets:0 errors:0 dropped:0 overruns:0 frame:0

          TX packets:164 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:0

          RX bytes:0 (0.0 b)  TX bytes:26901 (26.2 Kb)

br0       Link encap:Ethernet  HWaddr 00:09:5B:89:9F:0D

          inet addr:10.10.12.5  Bcast:10.255.255.255  Mask:255.255.255.0

          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

          RX packets:44164 errors:0 dropped:0 overruns:0 frame:0

          TX packets:56438 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:0

          RX bytes:3212363 (3.0 Mb)  TX bytes:15921550 (15.1 Mb)

eth0      Link encap:Ethernet  HWaddr 00:40:63:D9:7E:DD

          UP BROADCAST RUNNING PROMISC MULTICAST  MTU:1500  Metric:1

          RX packets:44214 errors:0 dropped:0 overruns:0 frame:0

          TX packets:56446 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000

          RX bytes:3908042 (3.7 Mb)  TX bytes:15922782 (15.1 Mb)

          Interrupt:10 Base address:0xd000

lo        Link encap:Local Loopback

          inet addr:127.0.0.1  Mask:255.0.0.0

          UP LOOPBACK RUNNING  MTU:16436  Metric:1

          RX packets:2227 errors:0 dropped:0 overruns:0 frame:0

          TX packets:2227 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:0

          RX bytes:132386 (129.2 Kb)  TX bytes:132386 (129.2 Kb)

wifi0     Link encap:Ethernet  HWaddr 00:09:5B:89:9F:0D

          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

          RX packets:14651 errors:0 dropped:0 overruns:0 frame:11885

          TX packets:5444 errors:86 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:199

          RX bytes:899840 (878.7 Kb)  TX bytes:653399 (638.0 Kb)

          Interrupt:11 Memory:de920000-de930000 

```

Now if you reconfigure the laptop to an ip address and subnet that a wired pc is on then you should be able to ping everything from everything i.e. Laptop -> Desktop, Laptop -> Linux Box, Desktop -> Laptop, Desktop -> Linux Box, Linux Box -> Desktop, Linux Box -> Laptop etc.

So now you have a working access point so now its time to add the internet.

The NET

The Dynamode ADSL PCI Modem is based on the Conexant chipset so start by grabbing the latest Conexant Drivers http://patrick.spacesurfer.com/adsl/driver-2.6-latest.tar.bz2

Then the usual

```

bzip2 -d driver-2.6-latest.tar.bz2

tar xvf driver-2.6-latest.tar

cd CnxADSL-6.1.2.007-PIM-2.6-1.4

make

```

The Conexant drivers come with an init script which will need to install into /etc/rc.d/init.d. If this fails the driver will not be installed so execute the following to install the driver:

```

mkdir -p /etc/rc.d/init.d

make install

rm /etc/rc.d/init.d/cnxadslctl && rmdir /etc/rc.d/init.d && rmdir /etc/rc.d/ 

```

To make the modem start at boot create the following init script /etc/init.d/cnxadsl

```

#!/sbin/runscript

#

#  This is the boot/shutdown script for the driver for the

#  Conexant AccessRunner ADSL modem.

#

# determine if we are loading or unloading

opts="start stop status"

depend() {

   need net 

   after modules

}

start() {

      # if the driver is not already loaded then

      # Load the module

      if [[ `lsmod | grep -o -e "CnxADSL"` ]] ; then

         eerror  "AccessRunner is already loaded"

   eend $?

      else

         ebegin "Starting Conexant AccessRunner"

         modprobe -i CnxADSL                     \

             CnxtDslVendorId=0x14F1         \

             CnxtDslArmDeviceId=0x1610      \

             CnxtDslAdslDeviceId=0x1611     \

             CnxtDslPhysicalDriverType=1 >/dev/null 2>/dev/null

         # Initialize the firmware

         /etc/Conexant/cnxadslload /etc/Conexant >/dev/null 2>/dev/null

   eend $?

     fi

}

stop() {

      # if the driver is started then stop it

      if [[ `lsmod | grep -o -e "CnxADSL"` ]] ; then

         ebegin  "Stopping Conexant AccessRunner"

   #kill pppd if running

        #    shouldn't this be handled by /etc/init.d/pppd ??

         ps ax | grep pppd | awk '{print $1}' | xargs kill -9 >/dev/null 2>/dev/null

         #unload the module

         modprobe -r CnxADSL

   eend $?

      else

   ebegin "AccessRunner was not loaded"

   eend $?

      fi

}

status() {

      if [[ `lsmod | grep -o -e "CnxADSL"` ]] ; then

        cat /proc/net/atm/CnxAdsl:0

      else

         echo "AccessRunner is not loaded"

      fi

}

```

Now make it executable and add it to the default level

```

chmod 755 /etc/init.d/cnxadsl

rc-upadate add cnxadsl default

```

To test its working 

```
/etc/init.d/cnxadsl start
```

and then 

```
/etc/init.d/cnxadsl status
```

 and you will get something like this while synchronisation when the exchange take place:

```
Conexant AccessRunner PCI ADSL Modem Adapter Status

----------------------------------

ADSL Line Not Connected

Line Rates: Not available

ADSL Modulation:G.DMT, Rate Unlimited  /  Full Rate

ATM Virtual Channel IDs: no connections open

```

Now the good news, the current ppp emerge includes the atm patch if you specify atm in your uses list. To make sure it is there everytime do 

```
echo echo net-dialup/ppp atm >> /etc/portage/package.use
```

Now just 

```
emerge ppp
```

Then configure /etc/ppp/options

```

noauth

plugin /usr/lib/pppd/2.4.2/pppoatm.so 0.38

noipdefault

nopcomp

debug

noccp

novj

holdoff 4

maxfail 25

persist

defaultroute

user "USERNAME"

```

and /etc/ppp/chap-secrets

```

"USERNAME" * "PASSWORD" 

```

You can test ppp now but I will stop it after it has connected as you have no firewall to prevent unauthorised access to your computers. 

Firewall (IPTABLES)

No Im no expert at this. Ive managed to configure Cisco packet filters without too much trouble but I can never seem to get my head around iptables. What follow is what I have learnt from playing and I think I have a fairly good configuration. Having said that if you spot anything obvious please let me know and Ill update or remove this information if Ive completely screwed up.

Start with 

```
emerge iptables
```

Then create the rule set. I have a fairly hard method of denying everything then allowing what I want. The name servers and time servers are for Zen Internet in the UK and should be altered accordingly for your ISP.

```

# Clear any existing rules

iptables -F

iptables -t nat -F

# Allow packets for connections which are already established 

iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT

# Access from the local LAN & Loop back

iptables -A INPUT -i br0 -j ACCEPT

iptables -A INPUT -i lo -j ACCEPT

# ISP Name servers & Time Server

iptables -A INPUT -p udp -s 212.23.3.11 -j ACCEPT

iptables -A INPUT -p udp -s 212.23.6.35 -j ACCEPT

iptables -A INPUT -p udp -s 212.23.8.6 -j ACCEPT

# Allow connecions to WEB and E-Mail Services

iptables -A INPUT -p tcp -dport http -j ACCEPT

iptables -A INPUT -p tcp -dport smtp -j ACCEPT

# Bittorrent

iptables -A INPUT -p tcp --dport 6881:6889 -j ACCEPT

# Allow Pings

iptables -A INPUT -p icmp -j ACCEPT

# Allow traffice through the bridge

iptables -A FORWARD -i br0 -o br0 -j ACCEPT

# Allow traffic to be forwarded from the LAN to the Internet and back.

iptables -A FORWARD -i br0 -s 10.10.12.0/24 -j ACCEPT

iptables -A FORWARD -i ppp0 -d 10.10.12.0/24 -j ACCEPT

# Set the masqyerade rule

iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

#Set the default rules

iptables -A INPUT DROP

iptables -A FORWARD DROP 

iptables -A OUTPUT ACCEPT

```

Starting PPP at boot

On the unixhead website it a great script that can be run from /etc/conf.d/local.start which will start pppd when the modem has synchronised with the exchange. To use the script I did the following:

```

nano w /bin/ppptest

--- BEGIN CUT HERE ---

#!/bin/sh

#ppp starter

#waits until conexant dsl modem connected before launching pppd

ppptest()

{

if [ "`cat /proc/net/atm/CnxAdsl\:0| grep Connected | grep -v Not | wc -l | awk '{print $1}'`" != "0" ]

then

        /usr/sbin/pppd

else

        sleep 5

        ppptest

fi

}

ppptest

--- END CUT HERE ---

chmod +x /bin/ppptest

```

then edit /etc/conf.d/local.start  and add

```
/bin/ppptest
```

If all goes well by the end of the boot process you will be automatically connected to the internet.

TODO

Things left to do include adding a DHCP server so guest PCs are given and ip address automatically and some status monitoring for traffic load on the ppp interface, line status monitoring to kill ppp if the line fails through maintenance etc. and restart it when the line returns. 

References

MadWifi Information

First Time http://madwifi.org/wiki/UserDocs/FirstTimeHowTo

Simple Access Point http://madwifi.org/wiki/UserDocs/SimpleAccessPoint

Installing Madwifi on Gentoo http://madwifi.org/wiki/UserDocs/Distro/Gentoo

WEP Calculator

http://www.digitwebsites.net/wepkeys.php

Internet Connections

Conexant Setup http://gentoo-wiki.com/HOWTO_PPPoA_ADSL_with_a_Conexant_Accessrunner_PCI_modem

Conexant Setup http://www.unixhead.org/docs/conexant/linux-conexant-howto.html

Home Router Guide http://www.gentoo.org/doc/en/home-router-howto.xml

----------

