2015/01/11

DIY Wi-Fi Access Point on Linux

Hardware

From local vendor I bought PCI Express card with Atheros AR9485 chip complying to IEEE 802.11n. It should be versatile and well-supported via ath9k Linux kernel driver.

In case you are interested in the particular device, it is TP-LINK TL-WN781N.

Kernel 

Naturally you must have some decently recent kernel and enabled support for wireless networking, your Wi-Fi chip and bridging (will be explained later).
The more or less relevant config options on my machine looks this way:

Networking support --->
  Networking options  --->
    <M> 802.1d Ethernet Bridging
  -*- Wireless  --->
        <M> cfg80211 - wireless configuration API
        [*] enable powersave by default
        <M> Generic IEEE 802.11 Networking Stack (mac80211)
        -*- Enable LED triggers
  <M> RF switch subsystem support

Device Drivers  --->
  [*] Network device support  --->
        Wireless LAN  --->
          <M> Atheros Wireless Cards ---->
                      <M> Atheros 802.11n wireless cards support
                      [*] Atheros ath9k PCI/PCIe bus support
  -*- Enable LED triggers -->
        {M} LED Class Support
        -*- LED Trigger support

Bridging Wi-Fi and Ethernet 

To connect clients connecting to our Access Point we need to bridge our existing wired ethernet device eth0 and the wireless one, names wlp1s0 in my case.

Enable IP Forwarding 

Once we have the support in  kernel, we should enable it by default, that is done on Gentoo Linux by editing /etc/sysctl.conf and setting net.ipv4.ip_forward = 1.

You should also install bridge-utils, containing brtctl utility that can be used to query and change setting of ethernet bridges on your machine.

Setup Ethernet Bridge

Then you can adapt your network configuration. I did it by moving all configuration from eth0 to my bridge, called br0, and add eth0 to it at the boot time.  There should also be configuration for the wireless device but we do not want to add it to the bridge on boot - that's what will hostapd take care for.

So my /etc/conf.d/net looks this way after the above described changes:

modules=("ifconfig")

# wired

config_eth0="null"

# wireless

modules_wlp1s0="!iwconfig !wpa_supplicant"
config_wlp1s0="null"
channel_wlp1s0="6"
essid_wlp1s0="MY_SSID"
mode_wlp1s0="master"

# bridge

config_br0="192.168.1.250/24"
routes_br0="default via 192.168.1.254"
dns_servers_br0="192.168.1.250" #pdnsd
bridge_br0="eth0" # adding eth0 to the bridge on boot

Your configuration will probably vary, e.g.  setup of the DNS server, namely using caching DNS server pdnsd, would differ.

Don't forget to add net.br0 to the startup scripts for default run level oor you'll end with machine without network at all.

Access Point

The final piece in the puzzle is hostapd - the utility that attaches to your wireless device and changes it to Wi-Fi AP.  You have to adapt its config (/etc/hostapd/hostapd.conf on my machine) to you needs - make sure  that the settings match what you have in your network configuration:

interface=wlp1s0
bridge=br0
ssid=MY_SSID 
 
I also set country_code in hope that it will help me to meet wireless regulations and hw_mode. For security I set wpa  (set to 2, to avoid weak WPA 1) and wpa_passphrase. All the configuration options are well-documented so take you time and read it - further details are easily available in wikis on internet.

The final set is to test hostapd setup and to add hostapd to startup scripts for default run level. 

Reboot

If you did everything right, you can reboot. Boot will bring up eth0, then br0 and add eth0 to it, the hostapd kicks in bringing up the wireless device and adding it to the bridge - once done, AP starts to advertise itself and you can connect using predefined pass-phrase.

I hope I did not mess things too much as I am newbie to Wi-Fi, and this how-to will help you a bit.