Skip to content

Instantly share code, notes, and snippets.

@volkbay
Last active September 25, 2025 20:25
Show Gist options
  • Select an option

  • Save volkbay/de77da4d748c1b1e8f381e0bbd9f0234 to your computer and use it in GitHub Desktop.

Select an option

Save volkbay/de77da4d748c1b1e8f381e0bbd9f0234 to your computer and use it in GitHub Desktop.
Set Raspberry Pi 3 as a WiFi repeater/extender/AP
[Unit]
Description=Create virtual AP interface ap0
Before=hostapd.service
After=sys-subsystem-net-devices-wlan0.device
Requires=sys-subsystem-net-devices-wlan0.device
[Service]
Type=oneshot
ExecStart=/sbin/iw dev wlan0 interface add ap0 type __ap
ExecStartPost=/sbin/ip addr add 192.168.4.1/24 dev ap0
ExecStartPost=/sbin/ip link set ap0 up
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
interface=ap0
dhcp-range=192.168.4.10,192.168.4.100,255.255.255.0,24h
bind-interfaces
...
# edit DAEMON_CONF and uncomment:
DAEMON_CONF="/etc/hostapd/hostapd.conf"
...
interface=ap0
driver=nl80211
ssid=<your_new_ssid>
hw_mode=g
channel=6
wmm_enabled=1
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=<your_new_passphrase>
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP
country_code=TR
ieee80211n=1
... existing tables ...
table ip nat {
chain prerouting {
type nat hook prerouting priority 0;
}
chain postrouting {
type nat hook postrouting priority 100;
oif "wlan0" masquerade
}
}
net.ipv4.ip_forward=1

🧰 Setup

  • Device: Raspberry Pi 3B
  • OS: Raspberry Pi OS (bookworm)
  • No extra WiFi adapter or shield
  • An existing upstream WiFi connection

On the single integrated chip of RPi3, the existing WiFi network will be re-broadcasted as another WiFi network. The resulting setup will act not exactly as an access point (which converts ethernet to wireless), but as a repeater or an extender.

The aim is to extend an existing connection to dead zones, or in my case, to convert settings (e.g. changing from WPA2-Enterprise to WPA2-Personal).

Caution

Works but limited throughput and may sometimes drop connections.

πŸͺœ Installation

We will use the built-in WiFi for both upstream and created networks. The dependencieas are nl80211, hostapd, dnsmasq and nftables.

  1. Start with setting up the reqired packages.
sudo apt update
sudo apt install hostapd dnsmasq nftables
sudo systemctl unmask hostapd
sudo systemctl enable hostapd
sudo systemctl enable dnsmasq
sudo systemctl enable nftables
  1. Built-in WiFi (or upstream) connects to wlan0 interface. We will create another interface as ap0 on the same adapter chip with a static IP 192.168.4.1. To configure the packages, update following files as given in the attached files here:
  • /etc/hostapd/hostapd.conf - Configures AP definition. Insert desired network name and password here.
  • /etc/default/hostapd - Point to default config file for hostapd service
  • /etc/dnsmasq.conf - Defines DNS masking address range (DHCP for the AP subnet).

It is best to backup the original file for dnsmasq package by:

sudo mv /etc/dnsmasq.conf /etc/dnsmasq.conf.orig
  1. We will create a virtual interface ap0 and assign a static IP to it by establishing the related service in the following steps. Here, we are telling NetworkManager to ignore ap0 so it won't assign DHCP IPs.
sudo nano /etc/NetworkManager/conf.d/unmanaged.conf
  1. Enable IP forwarding as bookworm uses nftables tool. Apply the changes you made and add set of rules to NAT.
sudo nano /etc/sysctl.d/routed-ap.conf
sudo sysctl --system
sudo nano /etc/nftables.conf
sudo nft -f /etc/nftables.conf
sudo systemctl restart nftables

You can check the changed ruleset by nft list ruleset.

  1. The built-in chip can do AP + client only if you create a virtual interface. So here in this step, we will create one named ap0 and wrap it in a system service for convenience. The configuration given guarantees ap0 exists before hostapd launches.
sudo nano /etc/systemd/system/ap0.service
sudo systemctl daemon-reload
sudo systemctl enable ap0.service
  1. Finally, arrange system service order of the rest of the packages. So that, system will do: wlan0 device exists β†’ create ap0 (adds ap0, assigns static IP and brings it up) β†’ hostapd (binds to ap0) β†’ dnsmasq (binds to ap0) β†’ nftables (sets NAT rules)
  • Update sudo systemctl edit hostapd with:
[Unit]
Requires=ap0.service
After=ap0.service
  • Update sudo systemctl edit nftables with:
[Unit]
Requires=hostapd.service
After=hostapd.service
  • Update sudo systemctl edit dnsmasq with:
[Unit]
Requires=hostapd.service
After=hostapd.service

Last step is to apply changes above sudo systemctl daemon-reload. After rebooting the system, the order of services may be checked by sudo systemd-analyze blame.

🐎 Running

Use sudo raspi-config or the GUI to connect wlan0 to your WiFi as usual. Don't forget to check WiFi country code selection. Finally, check your incoming internet connection:

iwgetid
ping -c3 8.8.8.8

Then, reboot once to be apply effects - sudo reboot or restart the pipeline that has just been configured:

sudo systemctl restart ap0
sudo systemctl restart hostapd
sudo systemctl restart dnsmasq
sudo systemctl restart nftables

At this point, you should have wlan0 connected to your upstream Wi-Fi (internet) and ap0 broadcasting the indicated SSID network via 192.168.4.1/24. Please check IP addresses and desired UP flag with ip addr command.

πŸ› οΈ Troubleshooting

Those can be helpful in case you encountered an issue:

  • ip addr should show both interfaces UP with correct IPs.
  • iw list and iw dev must show AP mode support on ap0 and managed on wlan0. Also, they should be on the same channel with normal transmit power ratings.
  • journalctl -u <package> | tail -n20 or sudo systemctl status -l <package> will show why a certain service failed (wrong channel, interface missing, etc.). For example, look for the following lines in hostapd log:
ap0: interface state UNINITIALIZED->ENABLED
ap0: AP-ENABLED
  • Ensure correct system service ordering by sudo systemd-analyze blame. It is convenient to ...| grep <service> to easily observe CPU starting time of the given service. Also, sudo systemctl list-dependencies <service> should output desired dependencies for that service.
  • Do not use automatic channel selection by channel=0 with hostapd settings as it takes forever.
  • The following checks should unmanaged ap0 (static IP) and wlan0 connected to upstream network.
nmcli dev status
iwgetid
  • There should be no block on the adapters, if so, unblock them:
sudo rfkill list all
sudo rfkill unblock all
  • Lastly, check firmware and driver issues for Broadcomm. If necessary, update them. Although, usually, the error you get here roots from the running order of the services.
lsmod | grep -E "brcmfmac|brcmutil|cfg80211|mac80211"
dmesg | grep -iE "brcm|bcm|wlan|cfg80211" | tail -n50

[keyfile]
unmanaged-devices=interface-name:ap0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment