Sep 20, 2013

Raspberry Pi As A Wi-Fi Access Point

Hey guys, happy Mid-Autumn Festival.  Tired of BBQ and mooncakes? Let's have a quick project by turning a Raspberry Pi into a Wi-Fi access point.  The first Pi image I tried was OpenWrt 12.09 (Attitude Adjustment), which is a very small Linux distro for embedded systems.  But turned out the image just doesn't work out of the box at the 1st boot.  A few boot files seem to be outdated and should be replaced by those from other distros like OpenELEC.  Really frustrated indeed :(.  So I fell back again to my home router with Raspbian installed.  There are lots of write-ups regarding making Pi a Wi-Fi AP already, but none of them worked for me tho :(.  After trying a few things out, I made my own steps.



Wi-Fi dongles


Buffalo WLI-UC-GNM W-Fi dongle was used in the test. See http://elinux.org/RPi_USB_Wi-Fi_Adapters for more hardware info.

$ lsusb | grep -i wireless
Bus 001 Device 004: ID 0411:01a2 BUFFALO INC. (formerly MelCo., Inc.) WLI-UC-GNM Wireless LAN Adapter [Ralink RT8070]


Package Installation


We need a few more packages to complete the task:

$ apt-get install hostapd isc-dhcp-server

Package Removal


 It took me some time to figure out a link detection daemon called ifplugd is bad for us to do the following configuration:
  • MAC address modification for interface eth0.  Yes, in my scenario the MAC address of the interface to the Internet is locked to a specific value.  This is not required for you guys I think.
  • Static IP address assignment for interface wlan0.  This is essential for further routing and forwarding configuration
$ apt-get remove ifplugd


Topology and Interface Configuration


  • WAN: eth0, Ethernet connected to the Internet. IP address is DHCP assigned.
  • LAN: wlan0, wireless interface for the hotspot. IP address is statically assigned to 10.8.8.254
$ more /etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp
  hwaddress ether 00:90:de:ad:be:ef

auto wlan0
iface wlan0 inet static
  address 10.8.8.254
  netmask 255.255.255.0


HostAPd Configuration


Quoted from the hostapd manpage, hostapd is an IEEE 802.11 AP, IEEE 802.1X/WPA/WPA2/EAP/RADIUS Authenticator.  For brevity most of the comments in the configuration files are removed, but you can easily look them up on the net.

$ more /etc/hostapd/hostapd.conf
interface=wlan0
driver=nl80211

ssid=Pi-Fi
hw_mode=g
channel=6
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=MySecret
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP


The values in bold above can be changed to fit your needs.

$ more /etc/default/hostapd
DAEMON_CONF="/etc/hostapd/hostapd.conf"

DHCP Server Configuration


An IP addresses pool will be defined, along with some TCP/IP configuration to be dispatched to the clients.

$ more /etc/dhcp/dhcpd.conf
authoritative;
ddns-update-style none;
ignore client-updates;

subnet 10.8.8.0 netmask 255.255.255.0 {

    option routers                  10.8.8.254;
    option subnet-mask              255.255.255.0;
    option domain-name              "home.tw";
    option domain-name-servers      8.8.8.8;

    range 10.8.8.130 10.8.8.169;
    default-lease-time 86400;
}


We just listen on the interface wlan0:

$ more /etc/default/isc-dhcp-server
INTERFACES="wlan0"


Routing and NAT Configuration


Add the following lines to the file /etc/rc.local:

sysctl net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE


That's it. Let's make some services start on boot, then reboot.

$ sudo update-rc.d hostapd enable
$ sudo update-rc.d
isc-dhcp-server enable
$ sudo reboot



After the reboot, if everything goes well our Wi-Fi SSID will be broadcasted in the air like a normal AP does.  Interfaces info follow:

$ ifconfig
eth0      Link encap:Ethernet  HWaddr
00:90:de:ad:be:ef 
          inet addr:192.168.111.193  Bcast:192.168.11.255  Mask:255.255.252.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:104189 errors:0 dropped:0 overruns:0 frame:0
          TX packets:84076 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:105045101 (100.1 MiB)  TX bytes:17906110 (17.0 MiB)

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:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

mon.wlan0 Link encap:UNSPEC  HWaddr 4C-E6-76-D5-92-37-00-00-00-00-00-00-00-00-00-00 
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:32587 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:3042110 (2.9 MiB)  TX bytes:0 (0.0 B)

wlan0     Link encap:Ethernet  HWaddr 4c:e6:76:d5:92:37 
          inet addr:10.8.8.254  Bcast:10.8.8.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:85472 errors:0 dropped:0 overruns:0 frame:0
          TX packets:104367 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:17480008 (16.6 MiB)  TX bytes:108515924 (103.4 MiB)


Notice the IP address of wlan0 should be correctly assigned, and an extra interface mon.wlan0 will be brought up by hostapd as well.  In my test, three devices could get on the Internet simultaneously via this hotspot without any problem.

References:
  1. http://www.howtogeek.com/167425/how-to-setup-wi-fi-on-your-raspberry-pi-via-the-command-line/. But I didn't try the WPA supplicant part.
  2. http://elinux.org/RPI-Wireless-Hotspot. Does not work for me. :(