Saturday, July 13, 2013

Setup a Wireless Access Point with Linux Mint 15 (Olivia)

In these days of tablets, smartphones and other "connected" devices, the ability to share a fast wired Internet connection via wi-fi can be very useful, specially at home or small offices. Wireless routers aren't very expensive and are simple enough to install – yet I have always thought they're kind of wasteful, considering most computers today ship with wi-fi interfaces, or can be fitted with USB cards that sell for pennies.

With Linux, wi-fi interfaces can be configured to operate in master mode, so they can accept client connections just like a dedicated router would. This is a huge improvement over "ad-hoc" wi-fi network sharing, because:
  1. Many mobile devices do not connect to "ad-hoc" access points;
  2. The WEP authentication standard used on those connections is known to be flawed, in contrast to the newer WPA standard used in "master mode" connections.
Today I updated my desktop to the latest Linux Mint 15 (Olivia), and as I went about configuring a Wireless Access Point (WAP) on it for my other devices, I took the time to document my changes to the system, so I can more easily reproduce them in future upgrades – and hopefully, also help others to setup a WAP with Mint.

The procedure I came up with was largely inspired by this blog post. It assumes the existence of a wired interface eth0 (which provides access to the Internet) and a mac80211-compatible wireless interface wlan0 (which will be configured to accept client connections in "master mode").

First open a command prompt and start a root session with su, then follow the steps below:

Step 1: Install Applications

Type the command below to install the required services:
apt-get install hostapd dnsmasq
As it is the services will be automatically started when the computer boots, but we need better control than that. So change the default settings to manual start:
update-rc.d -f hostapd remove
update-rc.d -f dnsmasq remove

Step 2: Configuration Files

Create or update the following config files with the contents below:

/etc/hostapd/hostapd.conf
interface=wlan0
driver=nl80211
ssid=hotspot # Your WAP name, change it to something more unique
hw_mode=g
channel=6 # You may want to change this if the channel is too crowded
wpa=1
wpa_passphrase=hotspot_password # Password for clients
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP CCMP
wpa_ptk_rekey=600

/etc/dnsmasq.conf
# disables dnsmasq reading any other files like /etc/resolv.conf for nameservers
no-resolv
# Interface to bind to
interface=wlan0
# Specify starting_range,end_range,lease_time
dhcp-range=10.0.0.3,10.0.0.20,12h
# dns addresses to send to the clients
server=8.8.8.8
server=8.8.4.4

Step 3: Interface Scripts

Add the scripts below to your system:

/etc/network/if-up.d/wapstart
#!/bin/sh

WIRE=eth0
WIFI=wlan0

# Only run script for wired interface
if [ ! "$IFACE" = "$WIRE" ]
then
    exit 0
fi

# Setup wireless interface
ifconfig $WIFI up 10.0.0.1 netmask 255.255.255.0

# Start dnsmasq
/etc/init.d/dnsmasq start

#Enable NAT
iptables --flush
iptables --table nat --flush
iptables --delete-chain
iptables --table nat --delete-chain
iptables --table nat --append POSTROUTING --out-interface $WIRE -j MASQUERADE
iptables --append FORWARD --in-interface $WIFI -j ACCEPT

# Start the Wireless Access Point service
/etc/init.d/hostapd start

exit 0

/etc/network/if-post-down.d/wapstop
#!/bin/bash

WIRE=eth0
WIFI=wlan0

# Only run script for wired interface
if [ ! "$IFACE" = "$WIRE" ]
then
    exit 0
fi

# Stops Wireless Access Point services
/etc/init.d/hostapd stop
/etc/init.d/dnsmasq stop

# Asked nice the first time...
killall dnsmasq
killall hostapd

ifconfig $WIFI down
Make sure to create the scripts from the root account, so they'll have the right ownership. Also don't forget to give them running permission:
chmod +x /etc/network/if-up.d/wapstart
chmod +x /etc/network/if-post-down.d/wapstop

Usage

After performing the steps above, you should be able to start the WAP by stopping and restarting the wired interface:
ifconfig eth0 down
ifconfig eth0 up
From now on it will also be automatically started at boot time.

Troubleshooting

If your devices can see and connet to the wireless hotspot, but they cannot access the Internet, enter the command below:
sysctl -w net.ipv4.ip_forward=1
This will update kernel settings to enable IP forwarding, and only has to be issued once.

Depending on your distribution, hostapd may require that the wireless interface be either turned "on" in the network manager applet (e.g. Mint 15), or excluded from Network Manager control (e.g. Kubuntu 14.04). In the second case add the following to /etc/NetworkManager/NetworkManager.conf:
[keyfile]
unmanaged-devices=mac:mac_address_of_wireless_interface
Also check /etc/init.d/hostapd for whether the variable DAEMON_CONF is set; if not, set it to the path of the config file:
DAEMON_CONF=/etc/hostapd/hostapd.conf
If nothing else works, you can try to find the cause by running hostapd directly instead of in service mode, with extra logging options enabled. For example:
hostapd -d /etc/hostapd/hostapd.conf