WiFi Setup
This guide will help you set up a WiFi Access Point on your Raspberry Pi.
Find your Raspberry's MAC address:
Enter the following command to find the MAC address of your Raspberry Pi's WiFi interface:
iw dev
You should see an output similar to this:
pi@securitycam:~ $ iw dev
phy#0
Unnamed/non-netdev interface
wdev 0x2
addr ba:27:xx:xx:xx:xx
type P2P-device
txpower 31.00 dBm
Interface wlan0
ifindex 2
wdev 0x1
addr b8:27:xx:xx:xx:xx
ssid FRITZ!Box 420
type managed
channel 1 (2412 MHz), width: 20 MHz, center1: 2412 MHz
txpower 31.00 dBm
The MAC address of the wlan0
interface is b8:27:xx:xx:xx:xx
in this case.
Remember this MAC address (write it down) and the channel number (channel 1
in this case) for later.
Allocate a device for the Access Point
Create a new interface called ap0
with the same MAC address as wlan0
.
ap0
will then be the interface used for the Access Point.
sudo nano /etc/udev/rules.d/70-persistent-net.rules
Add the following lines and replace your MAC address (!) accordingly:
SUBSYSTEM=="ieee80211", ACTION=="add|change", ATTR{macaddress}=="REPLACEWITHMACADDRESS", KERNEL=="phy0", \
RUN+="/sbin/iw phy phy0 interface add ap0 type __ap", \
RUN+="/bin/ip link set ap0 address REPLACEWITHMACADDRESS"
Configure Dnsmasq
Backup the original and create a new dnsmasq
configuration:
sudo cp /etc/dnsmasq.conf /etc/dnsmasq.conf.orig
sudo sh -c 'echo "interface=lo,ap0
no-dhcp-interface=lo,wlan0
bind-interfaces
server=8.8.8.8
server=1.1.1.1
domain-needed
bogus-priv
dhcp-range=192.168.10.50,192.168.10.150,12h" > /etc/dnsmasq.conf'
Configure Hostapd
Open the configuration file:
sudo nano /etc/hostapd/hostapd.conf
Add the following content:
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
interface=ap0
driver=nl80211
ssid=DevAccessPoint
hw_mode=g
channel=1
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
Before you save, make sure to do these changes to the configuration:
- Replace
DevAccessPoint
andYourPassPhraseHere
with your desired values - Replace the
channel
with the channel yourwlan0
was running on (as reported byiw dev
in step 1)
Now after having saved, we want to specify where hostapd
should find its configuration:
sudo sed -i 's|^#DAEMON_CONF=""|DAEMON_CONF="/etc/hostapd/hostapd.conf"|' /etc/default/hostapd
Modify the wpa_supplicant
configuration
Open the configuration file:
sudo nano /etc/wpa_supplicant/wpa_supplicant.conf
Add the following content if it's not already present:
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"
}
Customize the configuration:
- Replace
YourSSID1
andYourPassphrase1
with your Wi-Fi network’s SSID and passphrase (the network you want to connect to, not the one created in the previous step). - Update the
country=US
line to reflect your country code. - If you only have one Wi-Fi network, remove the second network block.
You can add multiple networks by duplicating the network block, incrementing the id_str
for each one. Only keep the blocks for the networks you plan to connect to.
Enable support for the new AP
Modify /etc/network/interfaces
to support the new AP
Open the configuration file:
sudo nano /etc/network/interfaces
Add the following content:
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
iface AP2 inet dhcp
: Remove this line if you do not have a second network configured in wpa_supplicant.conf.iface AP1 inet dhcp
: Keep this line since it corresponds to the first network (SSIDYourSSID1
in thewpa_supplicant.conf
).
Start both interfaces:
sudo ifdown --force wlan0
sudo ifdown --force ap0
sudo ifup ap0
sudo ifup wlan0
It's crucial to copy and paste the entire block of commands above all at once.
Executing them one by one will disconnect you from the Pi after disabling the interfaces, preventing you from re-enabling them immediately.
If your Raspberry Pi Zero 2 W does not reconnect to your WiFi network at this point wait a few more seconds, unplug the power and plug it back in.
Check the interfaces
You should be able to see the DevAccessPoint
network on your device.
SSH into the Pi again (either you connect to the DevAccessPoint
and ssh with ssh pi@192.168.10.1
as configured in here or find the Raspberry Pi's new IP address in your router and ssh into it).
Now check the interfaces:
pi@securitycam:~$ ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
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:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
inet 192.168.178.102/24 brd 192.168.178.255 scope global dynamic noprefixroute wlan0
valid_lft 863907sec preferred_lft 755907sec
inet6 2a02:4500:4507:8d04:e2455:6452:6e45:2f66/64 scope global dynamic mngtmpaddr noprefixroute
valid_lft 7102sec preferred_lft 2496sec
inet6 fe45::4455:a1e3:45c9:5451/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:xx:xx:xx:xx 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
inet 169.254.165.183/16 brd 169.254.255.255 scope global noprefixroute ap0
valid_lft forever preferred_lft forever
inet6 fe45::7d45:45b8:b45:2f45/64 scope link
valid_lft forever preferred_lft forever
inet6 fe45::ba27:eb45:fe7c:3cea/64 scope link
valid_lft forever preferred_lft forever
You should see both wlan0
and ap0
interfaces with their respective IP addresses.
Bridge traffic between AP and Client side
Enbale ip-forwarding:
sudo sysctl -w net.ipv4.ip_forward=1
Create an nftables rule to handle NAT (Masquerading):
sudo sh -c 'echo "
table ip nat {
chain postrouting {
type nat hook postrouting priority 100; policy accept;
ip saddr 192.168.10.0/24 oifname != \"ap0\" masquerade
}
}" >> /etc/nftables.conf && sudo nft -f /etc/nftables.conf'
Restart dnsmasq
:
sudo systemctl restart dnsmasq
Now you should be able to connect to the AP and use its internet connection to access the internet. (If you have a working internet connection on its client side)
Automate the workaround
Create a new file:
sudo sh -c 'cat <<EOF > /opt/start-ap-managed-wifi.sh
#!/bin/bash
LOGFILE="/var/log/pi_startup.log"
echo "[$(date)] Starting script. Sleeping 15 sec..." >> \$LOGFILE
sleep 15
echo "[$(date)] Starting execution" >> \$LOGFILE
sudo sysctl -w net.ipv4.ip_forward=1
echo "[$(date)] Enabled IP forwarding" >> \$LOGFILE
sudo sh -c "echo \"
table ip nat {
chain postrouting {
type nat hook postrouting priority 100; policy accept;
ip saddr 192.168.10.0/24 oifname != 'ap0' masquerade
}
}\" >> /etc/nftables.conf && sudo nft -f /etc/nftables.conf"
echo "[$(date)] Applied nftables rules for NAT" >> \$LOGFILE
sudo systemctl restart dnsmasq
echo "[$(date)] Restarted dnsmasq" >> \$LOGFILE
echo " " >> \$LOGFILE
EOF
sudo chmod +x /opt/start-ap-managed-wifi.sh'
Add a cronjob to run the script on boot:
sudo bash -c 'echo "@reboot /opt/start-ap-managed-wifi.sh" >> /var/spool/cron/crontabs/root'
Continue to bluetooth.mdx to set up bluetooth.
These instructions are tested on Raspbian Bookworm with a Raspberry Pi Zero 2 W.
Shoutout to TheWalrus for the original instructions. A comment under the post pointed out that the instructions depend upon if-up and if-down system which is no longer used as of Raspian Buster. You might want to visit the original post for more information.
These instructions depend upon if-up and if-down system used by Raspbian Stretch version.
But as of 2020, you would be using Raspbian Buster, which uses a different system, based on dhcpcd daemon. While it is technically possible to still get it working (because the ifup/ifdown system are still there), it is recommended to use systemd-networkd approach, which doesn't depend upon having to introduce udev hook.
The instructions are here: https://raspberrypi.stackex...