Raspberry Pi Zero W as both wifi client and access point

Sometimes, it can be great to have a separate access point for some devices, like for example Internet of Things devices. The Pi Zero W can just do that. But what if you need it to connect to the internet at the same time? In this article, I present how to configure the Raspberry Pi Zero W as both a wifi client and an access point.I recently read an article on Hack a Day about doing the same and inspired myself from this other article. However, I cleaned a bit the scripts and introduced a new feature which will be useful when moving your raspberry in different locations: the access point channel will automatically be changed to match the client channel.

Configuring wifi client

Configuring the wifi client is need first since you will need to install some packages. Process is very standard and described everywhere on the internet.

Main thing to configure is the list of access points in /etc/wpa_supplicant/wpa_supplicant.conf. You can provide configurations for several wifi networks. Each configuration should be in the following format:

network={
    ssid="SSID_OF_NETWORK"
    psk="NETWORK_PASSWORD"
}

Preparing the Raspberry Pi 0W

First, we need to install some packages needed for the access point:

sudo apt-get install hostapd dnsmasq

Then we need to disable the automatic launch of both services:

sudo systemctl disable hostapd
sudo systemctl disable dnsmasq

Creating configuration files

First, you need to know that there will be a virtual device called uap0 which is bound to wlan0.
In file /etc/network/interfaces add the following lines to configure the access point IP:

iface uap0 inet static
  address 192.168.50.1
  netmask 255.255.255.0
  network 192.168.50.0
  broadcast 192.168.50.255
  gateway 192.168.50.1

Then, we create a template file /etc/hostapd/hostapd.conf.tmpl for the access point. Please note that the initialization script below will take it, change channel and overwrite the file /etc/hostapd/hostapd.conf.
Next is the configuration file for hostapd service, located at /etc/default/hostapd, which must contain the following:

DAEMON_CONF="/etc/hostapd/hostapd.conf"

And finally, the configuration for dnsmasq which will assign IP addresses to your devices. The file is /etc/dnsmasq.confg:

interface=uap0
no-dhcp-interface=lo,wlan0
bind-interfaces
server=8.8.8.8
domain-needed
bogus-priv
dhcp-range=192.168.50.50,192.168.50.150,12h

Note that I used Google’s DNS (8.8.8.8) in my configuration and that allow IPs from 50 to 150.

Script to put it all together

Last but not least, comes the script that put it all together. Its goal is to create the virtual device, create the configuration file for hostapd from the current wifi network and launch all services. I put the script in /usr/local/bin/hostapdstart:

#!/bin/bash
# Create the virtual device
/sbin/iw dev wlan0 interface add uap0 type __ap
ifup uap0
# Fetch wifi channel
CHANNEL=`iwlist wlan0 channel | grep Current | sed 's/.*Channel \([0-9]*\).*/\1/g'`
export CHANNEL
# Create the config for hostapd
cat /etc/hostapd/hostapd.conf.tmpl | envsubst > /etc/hostapd/hostapd.conf
# Uncomment the two following lines to get access to internet
#sysctl net.ipv4.ip_forward=1
#iptables -t nat -A POSTROUTING -s 192.168.50.0/24 ! -d 192.168.50.0/24 -j MASQUERADE

systemctl start dnsmasq
systemctl start hostapd

And use the /etc/rc.local file to launch the script at boot time. For this, we need to add just one line:

/bin/bash /usr/local/bin/hostapdstart

Final note

I tried to apply the very same method to the Raspberry Pi 3, but ended with a routing problem (default route on access point). I did not dug to find the solution but I believe solution may come from /etc/network/interfaces.

Leave a Reply

Your email address will not be published. Required fields are marked *