This post shows steps to set up Raspberry Pi Zero W as a wireless router.
I tested it with Raspbian Buster Lite (September 2019 version) on Raspberry Pi Zero W and this USB WiFi adapter. [Updated on 11.25.2019]
The figure above shows overview of the idea. Here are some assumptions:
- Raspberry Pi Zero W (the router) connects to an existing WiFi network (i.e. hotspot/access point) for Internet access via the on-board WiFi adapter.
- The router creates a private WiFi network (192.168.3.0/24) using a USB WiFi adapter.
- The IP address of the interface for the private network is set to 192.168.3.254.
- The IP address range for the private network is from 192.168.3.1 to 192.168.3.20.
- A device connected to the private network can access the Internet through the router.
Here is the list of contents of this post.
Contents
– Prerequisites
– Steps
1. Package installation
2. Wireless interface names
3. Assigning a static IP address for USB WiFi adapter (wlan1)
4. DHCP server setting
5. Access point setting
6. Enabling traffic forwarding
7. Forwarding rule configuration
8. Connecting to existing WiFi network (If it’s not connected yet)
9. Test
– Reference
Prerequisites
Steps
1. Package installation
1-1. As always, update the package list and upgrade the installed software first.
sudo apt-get update && sudo apt-get upgrade -y
1-2. Install ‘hostapd’ and ‘dnsmasq’.
sudo apt-get install hostapd dnsmasq -y
2. Wireless interface names
Before starting work on the configurations, check the interface names for the on-board WiFi and WiFi adapter. Those names will be used later.
2-1. Run ‘ifconfig’ command without connecting the WiFi adapter.
ifconfig
You should be able to see “wlan0”. It’s the interface name for the on-board WiFi adapter.
2-2. Then, connect the WiFi adapter and run the same command. This time you’ll notice that “wlan1” is added. It’s the name for newly connected USB WiFi adapter. So, now we know the interface names:
wlan0 : on-board WiFi
wlan1 : WiFi adapter
3. Assigning a static IP address for USB WiFi adapter (wlan1)
3-1. Open /etc/dhcpcd.conf
sudo nano /etc/dhcpcd.conf
3-2. Copy below at the end of the file. [6]
interface wlan1
static ip_address=192.168.3.254/24
nohook wpa_supplicant # don't call the wpa_supplicant hook
denyinterfaces wlan1 # don't send DHCP requests
after reboot, wlan1 should look like this:
pi@raspberrypi:~ $ ifconfig wlan1
wlan1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.3.254 netmask 255.255.255.0 broadcast 192.168.3.255
...
4. DHCP server setting
As suggested in [1], rename the original configuration file and create a new file from the scratch.
4-1. Rename the original file.
sudo mv /etc/dnsmasq.conf /etc/dnsmasq.conf.orig
4-2. Create a new file.
sudo nano /etc/dnsmasq.conf
4-3. Copy lines below, save and close the file.
interface=wlan1
dhcp-range=192.168.3.1,192.168.3.20,255.255.255.0,24h
5. Access point setting
5-1. Create the configuration file.
sudo nano /etc/hostapd/hostapd.conf
5-2. Copy the lines below, save and close the file. Replace <NETWORK_NAME> and <PASSWORD> with whatever you want for your private network.
interface=wlan1
hw_mode=g
channel=7
wmm_enabled=0
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
ssid=<NETWORK_NAME>
wpa_passphrase=<PASSWORD>
5-3. Specify the location of the configuration file. To do that, first open /etc/default/hostapd
sudo nano /etc/default/hostapd
5-4. Then, add the line below, save and close the file.
DAEMON_CONF="/etc/hostapd/hostapd.conf"
5-5. Enable hostapd by running the commands below [5]. (Thank you Dan for the info!)
sudo systemctl unmask hostapd.service
sudo systemctl enable hostapd.service
6. Enabling traffic forwarding
6-1. Open the configuration file.
sudo nano /etc/sysctl.conf
6-2. Look for the line below.
#net.ipv4.ip_forward=1
6-3. Uncomment the line. Now, it should be like:
net.ipv4.ip_forward=1
7. Forwarding rule configuration
7-1. Run these command:
sudo iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
sudo iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i wlan1 -o wlan0 -j ACCEPT
7-2. Backup the configuration.
sudo sh -c "iptables-save > /etc/iptables.ipv4.nat"
7-3. In order to load the rules on boot, open /etc/rc.local,
sudo nano /etc/rc.local
7-4. Then add this line above “exit 0”.
iptables-restore < /etc/iptables.ipv4.nat
8. Connecting to existing WiFi network (If it’s not connected yet)
8-1. Open /etc/wpa_supplicant/wpa_supplicant.conf
sudo nano /etc/wpa_supplicant/wpa_supplicant.conf
8-2. Add lines below at the end of the file. Replace <NETWORK_NAME> and <PASSWORD> to appropriate strings for your WiFi network for Internet access.
network={
ssid="<NETWORK_NAME>"
psk="<PASSWORD>"
key_mgmt=WPA-PSK
}
9. Test
9-1. Reboot the board.
sudo reboot
9-2. Search the WiFi network configured in step 5-2 from a WiFi enabled device (e.g. PC, phone) and connect to it. After connected, you should be able to access the Internet from the device.
References
[1] How to use your Raspberry Pi as a wireless access point
[2] Internet sharing – Arch Linux
[3] How-To: Turn a Raspberry Pi into a WiFi router
[4] What is the difference between -m conntrack –ctstate and -m state –state
[5] RPi Update broke Access Point setup #1093 – GitHub
[6] How do I configure dhcpcd to call wpa_supplicant for a specific interface? – StackExchange