WirelessAPandClient
WirelessAPandClient
Table Of Contents
Enabling Simultaneous AP and Managed Mode WiFi on Raspberry Pi Zero W (Raspbian Stretch)
Prerequisites
Adding Udev Rule To Add A Virtual AP Device At Boot Time
Installing Dnsmasq and Hostapd
Modify Our Interfaces File
We’re Done! Or Are We…
Automate The Workaround
Special Thanks
Enabling Simultaneous AP and Managed Mode WiFi on Raspberry Pi Zero W (Raspbian Stretch)
I recently purchased a pair of Raspberry Pi Zero W boards, and plan to use them for some home automation / IoT-type work. One of my requirements is that the WiFi on this board be able to run as
both a “managed” device (also known as “client” mode) and as an access point, preferrably at the same time. After looking around a bit online, I found several people who claimed to have gotten
this working, as well as posts saying it should work, based on the chipset. Despite my best e orts, I was unable to get any of those tutorials to work reliably on their own. By combining some
information garnered from each one, along with some trial and error, I was nally able to get AP/Manged mode working, as described below.
Prerequisites
This tutorial assumes you’ve already created a bootable MicroSD card running the latest Raspbian Stretch image and have some way of accessing Linux, whether via serial interface, or a monitor
and keyboard. If you haven’t, a couple of great resources I found online are:
Raspberry Pi Zero W “headless” Setup - This great tutorial walks you through getting WiFi client mode enabled on your RPi Zero W, without need for an attached monitor or keyboard. You will
need a way to modify the contents of the MicroSD card’s lesystem, such as a Linux machine, Chromebook with crouton, or VM. There are also ways to do this from Windows, but I’ll leave
that as an exercise for the reader.
Raspberry Pi Zero OTG Mode - Another awesome tutorial, via GitHub gist, which explains how to enable OTG / USB Gadget mode on the RPi Zero / Zero W. OTG mode lets you both power and
communicate with the RPi Zero W as a virtual serial device, ethernet device, or mass storage device, among other things, with nothing more than a standard (read: non-OTG) USB cable. I used
this to directly access the Raspbian Linux terminal via USB while trying to tweak the WiFi settings so that I wouldn’t drop my ssh session from headless mode.
Before we can operate our access point, we need a device allocated for it, similar to how systemd allocates a wlan0 device at boot time. On the build of Raspbian Stretch I’m using, only wlan0 is
available automatically. We create a le caled /etc/udev/rules.d/70-persistent-net.rules which contains the following:
Note that you must replace both MAC addresses above with that of your own RPi. You can nd yours in various ways, such as from your router’s client list, or from the RPi’s command line via iw
dev :
pi@raspberrypi:~$ iw dev
phy#0
Unnamed/non-netdev interface
wdev 0x4
addr ba:27:eb:07:28:1f
type P2P-device
txpower 31.00 dBm
Interface wlan0
ifindex 2
wdev 0x1
addr b8:27:eb:ff:ff:ff
ssid <YOUR HOME SSID>
type managed
channel 6 (2437 MHz), width: 20 MHz, center1: 2437 MHz
txpower 31.00 dBm
https://blog.thewalr.us/2017/09/26/raspberry-pi-zero-w-simultaneous-ap-and-managed-mode-wifi/ 1/9
06/06/2019 Raspberry Pi Zero W Simultaneous AP and Managed Mode Wifi · TheWalrus
A number of tutorials I found claimed that the address for the virtual AP must be di erent from the primary MAC address. I found there to be no di erence in behavior, but you should be able to
change the last byte, for example, to give your client and AP di erent MACs.
The device we created above is called ap0 . We will refer to this elsewhere, so if you decide to change the name, make sure to use the new name everywhere else I reference it, or things won’t work
correctly.
Dnsmasq - This program has extensive features, but for our purposes we are using it as a DHCP server for our WiFi AP.
Hostapd - This program de nes our AP’s physical operation based on driver con guration.
Wait awhile, and this process should complete. The install process may automatically start the dnsmasq.service in systemd right after installation and it will probably fail, since ap0 does not exist
until we reboot. Disregard this for now.
Next, we need to modify 3 les. First we modify /etc/dnsmasq.conf by adding the following lines at the end of the le:
interface=lo,ap0
no-dhcp-interface=lo,wlan0
bind-interfaces
server=8.8.8.8
domain-needed
bogus-priv
dhcp-range=192.168.10.50,192.168.10.150,12h
Once again, notice we reference ap0 above, so use your device name here if you changed it earlier. I’ve added Google’s DNS server IP here (8.8.8.8) but feel free to use one from your router/ISP/or
whatever. I’ve also made the assumption that our DHCP server will give out addresses on the 192.168.10.0/24 subnet, ranging from .50 to .150. You can substiute your own subnet here, but be sure
to remember it for later, as it should match the static IP we assign your AP. The 12 hour lease time can also be arbitrarily changed to suit your needs.
Next, we need to modify the le at /etc/hostapd/hostapd.conf . I found many di erent parameters that can go in here, but this is what worked for me. Feel free to experiment further by poking
around online. Lets do this for now:
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
interface=ap0
driver=nl80211
ssid=YourApNameHere
hw_mode=g
channel=11
wmm_enabled=0
macaddr_acl=0
auth_algs=1
wpa=2
wpa_passphrase=YourPassPhraseHere
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP CCMP
rsn_pairwise=CCMP
1. Replace YourApNameHere and YourPassPhraseHere with the SSID and Passphrase you wish to use.
2. I read multiple sources claiming that the channel you use here must match the channel that your wlan0 iterface is using for its WiFi connection, as reported by iw dev . In my testing, it looks
like the RPi’s AP will dynamically change channels to match whatever channel the wlan0 interface is currently using. I watched this happen in real time by rebooting the WiFi AP the RPi was
using, forcing it to roam and switch to another AP in my house. In the process, wlan0 switched from channel 11 to channel 6, and ap0 did the same, without losing connectivity.
DAEMON_CONF="/etc/hostapd/hostapd.conf"
This tells the hostpad daemon to use our new conf le. (To be honest, I’m not sure if this matters since we will be launching hostapd manually and pointing to the proper con g le, but it shouldn’t
hurt anything.)
Next, we need to de ne our WiFi network interfaces, both for our managed access ( wlan0 ) and for our access point ( ap0 ). We will also use wpa_supplicant to assist with connecting to WPA-
encrypted WiFi networks. If you followed the “headless” bring-up tutorial I mentioned in the prereqs, you will have already touched both of the following les and con gured wlan0 as required. In
that case, we’ll be adding a static IP de nition for ap0 . First, we modify /etc/wpa_supplicant/wpa_supplicant.conf as so:
country=US
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
ssid="YourSSID1"
psk="YourPassphrase1"
id_str="AP1"
}
network={
ssid="YourSSID2"
psk="YourPassphrase2"
id_str="AP2"
}
Again, you should replace the SSIDs and Passphrases above with your own. You aren’t required to name multiple SSIDs here, but if you add more, the RPi can roam between networks if con gured
correctly, as we will do below. The id_str eld can be used as a quick reference name in our interfaces le. You should also change the country code to whatever is appropriate for your region.
/etc/network/interfaces
https://blog.thewalr.us/2017/09/26/raspberry-pi-zero-w-simultaneous-ap-and-managed-mode-wifi/ 2/9
06/06/2019 Raspberry Pi Zero W Simultaneous AP and Managed Mode Wifi · TheWalrus
auto lo
auto ap0
auto wlan0
iface lo inet loopback
allow-hotplug ap0
iface ap0 inet static
address 192.168.10.1
netmask 255.255.255.0
hostapd /etc/hostapd/hostapd.conf
allow-hotplug wlan0
iface wlan0 inet manual
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface AP1 inet dhcp
iface AP2 inet dhcp
As you can see, we want both ap0 and wlan0 to start up automatically, with ap0 de ned to have a static IP of 192.168.10.1 on the 192.168.10.0/24 subnet. Recall, the DHCP address range we
de ned in /etc/dnsmasq.conf matched this subnet. Adjust accordingly if you made changes. We also reference our hostapd con g le here, to direct the AP con guration for ap0 .
For wlan0 , we start it using manual mode and point it to our /etc/wpa_supplicant/wpa_supplicant.conf le for our WiFi network de nitions. The wpa-roam designator will allow the interface to
move freely between our de ned networks. Finally, the last two lines use our friendly names from wpa_supplicant.conf to refer to our available networks, and indicate this interface should use
DHCP supplied by those APs to assign an address to wlan0 . Please note the order here: ap0 must come up before wlan0, or they won’t both work at the same time.
At this point, I expect everything to work after a reboot. Instead, I end up with wlan0 UP and ap0 DOWN (or vice-versa) when checking via ip addr , and dmesg indicates some errors in the
Broadcom driver. After some tinkering, I discovered the following sequence of commands after a reboot would get both interfaces up and working simultaneously, like we wanted all along:
I had to add --force because sometimes hostapd would complain about having a lock on wlan0 and fail to proceed, so it ensures we get what we want. After bringing down both interfaces,
again, with ap0 going rst, followed by wlan0 , they should both come up:
pi@raspberrypi:~$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether b8:27:eb:ff:ff:ff brd ff:ff:ff:ff:ff:ff
inet 192.168.43.37/24 brd 192.168.43.255 scope global wlan0
valid_lft forever preferred_lft forever
inet6 fe80::ba27:ebff:fede:3a79/64 scope link
valid_lft forever preferred_lft forever
3: ap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether b8:27:eb:ff:ff:ff brd ff:ff:ff:ff:ff:ff
inet 192.168.10.1/24 brd 192.168.10.255 scope global ap0
valid_lft forever preferred_lft forever
inet6 fe80::ba27:ebff:fede:3a79/64 scope link
valid_lft forever preferred_lft forever
Great! But what about bridging tra c between my AP and client sides to allow a device to access the internet through my RPi? Let’s do that:
Here, we enable ip forwarding to allow packets to be forwarded between interfaces, and we add a postrouting rule to IP tables which routes all packets from the AP-side interface to the client-side
interface (where MASQUERADE is necessary, since the IP is dynamic and unde ned until wlan0 connects to an AP). Finally, we restart dnsmasq for good measure, since we previously brought
down ap0 with ifdown .
At this point, we should be able to connect a device to our Raspberry Pi Zero W’s AP SSID, while we also have our RPi connect to another access point for internet access, and we should be able to
access the internet from that device through our RPi. Only one thing left to do…
Try as I might to debug the issues I was having before manaully reseting the interfaces, I was unable to get the RPi to simply boot up working correctly. So, I decided to script the steps to “ x”
everything and set them to run as a root cron job with a 30s delay… (Yes, I know this is horrible practice, but I’m open to better suggestions.) I intially tried setting up a systemd service to call my
script instead of cron with a delay, but it didn’t seem to work or ran at the wrong time, requiring manual intervention.
I simply left the le in my default “pi” user’s home directory, but you can move it someplace more appropriate, such as /sbin . I then added a cron job like so:
$ sudo crontab -e
@reboot /home/pi/start-ap-managed-wifi.sh
This causes the script to run at every reboot. In testing, I foud the RPi Zero W boots in under 20s. Systemd runs the cron service somewhere in that range of time, which eventually runs the script
above. To be safe, you can change the 30s delay to something longer, but I found this to be pretty reliable.
Now, after every reboot, even though ap0 and wlan0 don’t initally play well together, the cron job kicks o my script after 30s and magically xes everything. We have AP and Managed mode
running at the same time, and we’re bridging tra c between the interfaces to allow for internet sharing through the Raspberry Pi Zero W.
Special Thanks
The following links were pretty instrumental in getting things moving in the right direction, so please check them out:
https://raspberrypi.stackexchange.com/questions/63841/rpi-zero-w-as-both-wi -client-and-access-point
RASPBERRY PI 3 - WIFI STATION+AP
Using your Raspberry Pi Zero’s USB wi adapter as both Wi client and access point
Please comment below if this helped you, or if you have any suggestions for improvements!
Comments Share
OLDER
Hello
NEWER
Using Esp8266 As An IoT Endpoint With Encrypted MQTT Transport
Featured Comment
LOG IN WITH
OR SIGN UP WITH DISQUS ?
Name
This is excellent! Thanks for throwing that together. Anyone who doesn't feel like manually going through the tutorial should be able to give that a run and get it working.
2△ ▽ • Reply • Share ›
I hacked together the following in my /etc/network/interfaces, which seems to replace your udev changes and various startup scripts, and is probably terribly offensive to anyone who
understands raspbian-debian's crazy spaghetti setup of network-interfaces/dhcpcd/wpa_supplicant/wpa_actions/and-probably-some-systemd-thrown-in-too (if there is anyone out there
who actually does):
allow-hotplug wlan0
iface wlan0 inet manual
pre-up ifup ap0
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
pre-down ifdown ap0
iface AP1 inet dhcp
iface AP2 inet dhcp
allow-hotplug ap0
iface ap0 inet static
pre-up iw phy phy0 interface add ap0 type __ap
pre-up ip link set ap0 address b8:27:eb:ff:ff:ff
post-down iw dev ap0 del
address 192.168.100.1
netmask 255.255.255.0
hostapd /etc/hostapd/hostapd.conf
4△ ▽ • Reply • Share ›
https://blog.thewalr.us/2017/09/26/raspberry-pi-zero-w-simultaneous-ap-and-managed-mode-wifi/ 4/9
06/06/2019 Raspberry Pi Zero W Simultaneous AP and Managed Mode Wifi · TheWalrus
ep y S ae
# Delays sending DHCPOFFER and proxydhcp replies for at least the specified number of seconds.
#dhcp-mac=set:client_is_a_pi,B8:27:EB:*:*:*
#dhcp-reply-delay=tag:client_is_a_pi,2
Albert, the instructions and updated recommendations are getting quite fragmented in the comments section. As mentioned elsewhere, please consider either updating your post
(preferable) or creating a new one with the new information gleaned from the comments :-) Updating this one seems a better option since it's one of the first hits on Google for Pi Zero
W access point.
2△ ▽ • Reply • Share ›
#!/bin/bash
Given that using cron is a huge hack anyway, I'll try out your suggestion and see how it goes. Removing 'auto' should also speed up initial boot, but I'll have to make sure that
first connection and subsequent down/up from my script aren't both required to make it work (magically). I haven't had a chance to make a optimization pass yet. Thanks!
△ ▽ • Reply • Share ›
I can get the ifdown and ifup statements to work via Slowbro's script as above - but cannot get the IP forwarding to work (disabled auto commands in
/etc/network/interfaces also as described above).
Any ideas? I'm keen for the IP forwarding to work for my project with the PiZW
I'm a bit new to linux and pi's in general so bear with me.
△ ▽ • Reply • Share ›
As a workaround i put
sudo ifdown --force wlan0 && sudo ifdown --force ap0 && sudo ifup ap0 && sudo ifup wlan0
at "/etc/rc.local" before "exit" command and after reboot it works great!
did that at image "2018-11-13-raspbian-stretch-lite.img"
1△ ▽ • Reply • Share ›
Thanks for that detailed post! There might be some useful information there for myself or other readers below.
△ ▽ • Reply • Share ›
If you're already using dnsmasq as per my instructions above, I think this might be a simple config line to do what you want: https://serverfault.com/que...
△ ▽ • Reply • Share ›
I finally found in another article from Craig Johnston where he added the ap device in the start script. So I just added the line iw dev wlan0 interface add ap0 type __ap to that script, and
completely removed the udev rule. It seems to work fine, and though I do get a "Failed to start Raise network interfaces" warning at boot. I don't know why, because all the interfaces
are present and working.
Thanks again!
△ ▽ • Reply • Share ›
Glad it helped! If you don't mind sharing the link you mentioned, please do, as it will probably be useful to anyone else reading this. Thanks!
△ ▽ • Reply • Share ›
Basically, I want to implement the below architecture with my three raspberry Pis:
Technically, if you configure the network appropriately, you'd only need one Pi to be an AP, and the others could be clients, and they could all talk to each other. Furthermore,
you could configure each one to run as an AP if they're unable to connect to another AP as a fallback option. I assume you're looking for some kind of redundancy?
△ ▽ • Reply • Share ›
According to this thread, if I get USB Wifi adapters, that could work.
△ ▽ • Reply • Share ›
Depending on how old your hardware is, it might be worth making sure your RPi is up to date by following the instructions here: https://raspberrypi.stackex...
△ ▽ • Reply • Share ›
figure:
see more
△ ▽ • Reply • Share ›
Cool project! I'm not sure if this project does AP+STA mode, but it provides a GUI for configuring a Raspberry Pi as a router: https://github.com/billz/ra...
My tutorial above should accomplish the same thing, but does not provide a GUI, as it's all config-file-based.
△ ▽ • Reply • Share ›
but below scenario is possible with your project? please give me guidance:
now just consider RASPBERRY PI Zero in AP+STA forget the GUI interface
only one Esp8266 is connected to Rpi's access point and our RpI running TCP server and receives ESP8266'S data without internet?
△ ▽ • Reply • Share ›
✉ Subscribe d Add Disqus to your siteAdd DisqusAdd 🔒 Disqus' Privacy PolicyPrivacy PolicyPrivacy
RECENTS
HOW-TO
USING ESP8266 AS AN IOT ENDPOINT WITH ENCRYPTED MQTT TRANSPORT
2019-03-27
HOW-TO
RASPBERRY PI ZERO W SIMULTANEOUS AP AND MANAGED MODE WIFI
https://blog.thewalr.us/2017/09/26/raspberry-pi-zero-w-simultaneous-ap-and-managed-mode-wifi/ 8/9
06/06/2019 Raspberry Pi Zero W Simultaneous AP and Managed Mode Wifi · TheWalrus
2017-09-26
BLOG
HELLO
2016-05-26
CATEGORIES
blog (1)
how-to (2)
TAGS
arduino (1)
certs (1)
esp8266 (1)
hello (1)
how-to (2)
mqtt (1)
raspberry-pi (1)
TAG CLOUD
https://blog.thewalr.us/2017/09/26/raspberry-pi-zero-w-simultaneous-ap-and-managed-mode-wifi/ 9/9