Seems there are to many components that have to play together: dhcpcd, ifupdown, hostapd and maybe dnsmasq and bridge-utils. I have a suggestion to reduce complexity with using systemd-networkd. It is available by default on Raspbian and has everything built-in, no need to install any additional helpers.
Last tested on a Raspberry Pi 4B with
Raspberry Pi OS (32-bit) 2020-12-02 based on Buster updated on 2020-12-23.
Updates done with sudo apt update && sudo apt full-upgrade && sudo reboot
.
Here is a setup with a bridge:
(dhcp
from RPi) bridge
╱ wifi ┌───────┐
station <~.~.~.~.> │(wlan0)│ usb tether wan
│ br0│RPi(usb0) <--------> modem/phone <───> INTERNET
laptop <────────> |(eth0) │╲ ╲
╲ wired └───────┘╱ (dhcp
(dhcp 192.168.4.1 from modem/phone)
from RPi)
Here in short the steps. First switch over to systemd-networkd. Just follow to
Use systemd-networkd for general networking.
You can use section "♦ Quick Step". Then come back here.
Configure wpa_supplicant as access point. Create this file with your settings for country=
, ssid=
, psk=
and maybe frequency=
. You can just copy and paste this in one block to your command line beginning with cat
and including both EOF (delimiter EOF will not get part of the file):
rpi ~# cat > /etc/wpa_supplicant/wpa_supplicant-wlan0.conf <<EOF
ctrl_interface=DIR=/run/wpa_supplicant GROUP=netdev
update_config=1
p2p_disabled=1
country=DE
network={
ssid="RPiNet"
mode=2
key_mgmt=WPA-PSK
proto=RSN WPA
psk="password"
frequency=2437
}
EOF
rpi ~# chmod 600 /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
rpi ~# systemctl disable wpa_supplicant.service
rpi ~# systemctl enable wpa_supplicant@wlan0.service
rpi ~# rfkill unblock wlan
Configure interfaces by creating these files:
rpi ~# cat > /etc/systemd/network/02-br0.netdev <<EOF
[NetDev]
Name=br0
Kind=bridge
EOF
rpi ~# cat > /etc/systemd/network/04-br0_add-eth0.network <<EOF
[Match]
Name=eth0
[Network]
Bridge=br0
EOF
rpi ~# cat > /etc/systemd/network/10-usb0.network <<EOF
[Match]
Name=usb0
[Network]
DHCP=ipv4
EOF
rpi ~# cat > /etc/systemd/network/12-br0_up.network <<EOF
[Match]
Name=br0
[Network]
LLMNR=no
MulticastDNS=yes
IPMasquerade=yes
Address=192.168.4.1/24
DHCPServer=yes
[DHCPServer]
DNS=84.200.69.80 1.1.1.1
EOF
Please ensure that the ip address(range) 192.168.4.0/24 (or whatever do you use) does not match the same subnet that you get from your USB tethering device.
Now we have to tell wpa_supplicant to use a bridge. We do it by modifying its service with:
rpi ~# systemctl edit wpa_supplicant@wlan0.service
In the empty editor insert these statements, save them and quit the editor:
[Service]
ExecStartPre=/sbin/iw dev %i set type __ap
ExecStartPre=/bin/ip link set %i master br0
ExecStart=
ExecStart=/sbin/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-%I.conf -Dnl80211,wext -i%I -bbr0
ExecStopPost=-/bin/ip link set %i nomaster
ExecStopPost=-/sbin/iw dev %i set type managed
Reboot and it should do.
References:
Setting up a Raspberry Pi as an access point - the easy way
Access point as WiFi repeater, optional with bridge