This is in addition to the Ingo’s outstanding description. Here we would like to use the default networking system of Raspbian (assuming to have previously configured it) rather than replacing it with systemd-networkd.
The standard networking mode to configure TCP/IP in Raspbian/Raspberry Pi OS is mentioned in the related documentation. At the time of writing, dhcpcd is used (dhcpcd5 package). This mode replaced the former Debian Networking (ifupdown package), where the configuration was done in /etc/network/interfaces. The documentation also describes how to setup a Wi-Fi client/Wi-Fi station via wpa_supplicant by configuring
/etc/wpa_supplicant/wpa_supplicant.conf to connect the Raspberry Pi to an existing wireless LAN on its default wlan0 interface; alternatively, it describes how to set up a routed wireless access point on the same wlan0 interface (instead of the Wi-Fi station).
We will use this last document as a reference, changing it in just a few points to configure the same wireless board to enable a wlan0 interface (Wi-Fi Client/Station, connected to another wifi network or internet router) as well as a Wi-Fi Access Point named uap0 (e.g., to define a wlan repeater):
- we create a copy of the hostapd service configuration, adding ExecStartPre and ExecStopPost settings to add/remove the "type AP" virtual interface via iw; we prefer using this rather than adding a rule in /etc/udev/rules.d;
- we use dhcpcd to set a static IP address to the created interface, also modifying the wlan0 configuration, to act as a DHCP client (without static addressing)
As DNS forwarder and DHCP Server, we will keep dnsmasq, used in the previously mentioned Raspberry configuration. We will also keep DNS Multicast (libnss-mdns) and Zeroconf/Apple Bonjour (avahi-daemon). We will not use systemd-resolved.
Noticeably, we suppose that the older ifupdown mode is not used, meaning that /etc/network/interfaces is left to its default configuration, with no stanzas defined, apart from source-directory /etc/network/interfaces.d
, with any other note or statement commented out through an initial #
, and that /etc/network/interfaces.d directory is left empty. We also assume that sudo systemctl status dhcpcd
returns that the service is active.
Example for this setup:
(dhcp 192.168.1.3 from router) +----------------------+ (192.168.1.1
\ | | / +DHCP server)
wifi (eth0) wifi uplink | /
mobile-phone <~.~.~.~.~> (ap0)RPi(wlan0) <.~.~.~.~.> router <───> INTERNET
╲ ╱ ╲ wan
(dhcp 192.168.50.50 (192.168.50.1 (dhcp 192.168.1.2
from RPi) +DHCP server) from router)
Install dnsmasq and hostapd (like in Raspberry’s documentation):
sudo -Es
apt install -y dnsmasq hostapd
Configure hostapd for the Access Point:
test -f /etc/hostapd/hostapd.conf || cat > /etc/hostapd/hostapd.conf <<\EOF
ctrl_interface=/var/run/hostapd
driver=nl80211
country_code=IT # Use your country code
ssid=YourSessionIdentifier
hw_mode=g
channel=7
auth_algs=1
wpa=2
wpa_passphrase=verySecretPassword
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
EOF
chmod 600 /etc/hostapd/hostapd.conf
edit /etc/hostapd/hostapd.conf and verify it
Test creation and deletion of uap0 virtual device on wlan0:
/sbin/iw dev wlan0 interface add uap0 type __ap
/sbin/iw dev uap0 del
No error should be produced.
If the first command fails with Device or resource busy (-16), it means that the device driver does not allow creating additional "Type AP" interfaces, which are busy for other services (e.g., an AP or a P2P-GO group is already active and has to be deleted to allow this new service to be activated).
Check this command:
iw list | grep "Supported interface modes" -A 8
It should return one line including AP. If only STA and managed are returned, the device driver of the board (or the hw itself) does not allow creating an AP interface.
Output of the Raspberry Pi 4:
Supported interface modes:
* IBSS
* managed
* AP
* P2P-client
* P2P-GO
* P2P-device
Use this command to check the allowed combination options:
iw list | grep "valid interface combinations" -A 8
Every line contains alternative combinations. With the Broadcom BCM2711 SoC included in a Raspberry Pi 4 B, I get the following:
valid interface combinations:
* #{ managed } <= 1, #{ P2P-device } <= 1, #{ P2P-client, P2P-GO } <= 1,
total <= 3, #channels <= 2
* #{ managed } <= 1, #{ AP } <= 1, #{ P2P-client } <= 1, #{ P2P-device } <= 1,
total <= 4, #channels <= 1
Device supports scan flush.
Device supports randomizing MAC-addr in sched scans.
Supported extended features:
* [ 4WAY_HANDSHAKE_STA_PSK ]: 4-way handshake with PSK in station mode
It means that not more than one AP or P2P-GO interface can be configured at the same time.
If the test to create and delete the uap0 virtual device succeeds, you can go on, starting the uap0 AP virtual interface on wlan0:
SYSTEMD_EDITOR=tee systemctl edit --force --full uap@.service <<\EOF
[Unit]
Description=IEEE 802.11 %p%i AP on wlan%i with hostapd
After=network.target
[Service]
Type=forking
PIDFile=/run/hostapd.pid
Restart=on-failure
RestartSec=2
Environment=DAEMON_CONF=/etc/hostapd/hostapd.conf
EnvironmentFile=-/etc/default/hostapd
ExecStartPre=/sbin/iw dev wlan%i interface add %p%i type __ap
ExecStart=/usr/sbin/hostapd -i %p%i -P /run/hostapd.pid -B $DAEMON_OPTS ${DAEMON_CONF}
ExecStopPost=-/sbin/iw dev %p0 del
[Install]
WantedBy=multi-user.target
EOF
systemctl stop hostapd # if the default hostapd service was active before
systemctl disable hostapd # if the default hostapd service was enabled before
systemctl enable uap@0.service
rfkill unblock wlan
You might possibly want to manually edit this in the future, with:
sudo -Es
#export SYSTEMD_EDITOR=vi # uncomment this if you like "vi", otherwise "edit" will be used
export SYSTEMD_EDITOR=vi systemctl edit --full uap@.service
exit
Some configurations (especially related to the old ifupdown mode) consider adding a static rule in /etc/udev/rules.d to bring up the uap0 AP interface, like ACTION=="add", SUBSYSTEM=="ieee80211", KERNEL=="phy0", RUN+="/sbin/iw phy %k interface add uap0 type __ap"
; as we are parametrizing this with the ExecStartPre
and ExecStopPost
statements of the uap@
service definition, it is important that your configuration does not include such rule in /etc/udev/rules.d.
Now we setup wpa_supplicant for client connections.
We need to update dhcpcd (the default a DHCP client) by editing /etc/dhcpcd.conf, adding the following to the end (these settings replace the configuration suggested in Raspberry’s site, which defined a static address to wlan0 instead of a DHCP Client; ref. "Define the wireless interface IP configuration"):
interface wlan0 # these two lines are not strictly needed, as wlan0 uses the default configuration
dhcp
interface uap0 # this defines static addressing to uap0 and disables wpa_supplicant for this interface
static ip_address=192.168.50.1/24
ipv4only
nohook wpa_supplicant
Comparing with the description in Raspberry’s site, notice that, other than removing the static address, we will not use nohook wpa_supplicant
under interface wlan0, so that wpa_supplicant is activated by a default dhcpcd hook.
To verify this hook, check files included in the /lib/dhcpcd/dhcpcd-hooks directory: one of this is 10-wpa_supplicant, which is the responsible for activating wpa_supplicant on the new interface. It is automatically run when the new interface is discovered by dhcpcd.
The file used by wpa_supplicant (Wi-Fi Station agent) is the default one: /etc/wpa_supplicant/wpa_supplicant.conf. We assume that it is already configured and working; otherwise you can use a template to configure it:
test -f /etc/wpa_supplicant/wpa_supplicant.conf || cat >/etc/wpa_supplicant/wpa_supplicant.conf <<\EOF
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=IT
network={
ssid="TestNet"
psk="realyNotMyPassword"
key_mgmt=WPA-PSK
}
EOF
edit /etc/wpa_supplicant/wpa_supplicant.conf and verify it
chmod 600 /etc/wpa_supplicant/wpa_supplicant.conf
systemctl disable wpa_supplicant.service # not used, as the agent is hooked by dhcpcd
We can then follow Raspberry’s documentation to enable routing and IP masquerading:
sudo DEBIAN_FRONTEND=noninteractive apt install -y netfilter-persistent iptables-persistent
Create a file using the following command, with the contents below:
test -f /etc/sysctl.d/routed-ap.conf || cat >/etc/sysctl.d/routed-ap.conf <<\EOF
# https://www.raspberrypi.org/documentation/configuration/wireless/access-point-routed.md
# Enable IPv4 routing
net.ipv4.ip_forward=1
EOF
# edit /etc/sysctl.d/routed-ap.conf and verify it
Updating the firewall rules:
# Add firewall rules
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
sudo iptables -A FORWARD -i wlan0 -o uap0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i uap0 -o wlan0 -j ACCEPT
sudo netfilter-persistent save
dnsmasq configuration follows Raspberry’s example:
cat >> /etc/dnsmasq.conf <<\EOF
disables dnsmasq reading any other files like /etc/resolv.conf for nameservers
no-resolv
interface=uap0
no-dhcp-interface=lo,wlan0
domain-needed
bogus-priv
server=8.8.8.8
dhcp-range=192.168.50.50,192.168.50.199,12h
dhcp-option=3,192.168.50.1
EOF
edit /etc/dnsmasq.conf and verify it
The configuration is finished. You must reboot before testing.
reboot
The systemctl command on uap@0.service allows disabling, enabling and monitoring the AP function; for instance, to stop AP, to remove the virtual interface and to free up device driver resources, you can issue:
sudo systemctl stop uap@0
To start again the service:
sudo systemctl stop dhcpcd && sudo systemctl start uap@0 && sudo systemctl start dhcpcd
Notice that in both cases wlan0 link goes down for some seconds and then goes up again; an active TCP connection on wlan0 is not lost anyway.
Temporarily stopping dhcpcd before starting up uap0 is needed to also stop wpa_supplicant (hooked by dhcpcd); this is in order to avoid the Broadcom driver issue "failed to enable fw supplicant" (for some weird reason the device driver attempts to reload an already loaded firmware supplicant for this interface).
If wlan1 is configured in place of the default wlan0 Wi-Fi function of the Raspberry Pi (e.g., a USB wireless dongle supporting access point mode), replace wlan0 with wlan1, uap@0 with uap@1, uap0 with uap1 every time "wlan0", "uap@0" and "uap0" are mentioned.
To use a different root name than uap for the AP interface (e.g., referring to uap0), change it with the new name every time it is mentioned.
Raspberry’s documentation describes how to set up a Raspberry Pi as a bridged wireless access point. The Ethernet interface is used to connect the Raspberry to the upstream router (e.g., provided with Internet access and featuring a DHCP server). In such configuration, the Raspberry Pi itself can be accessed by its br0 wireless interface, but not by its Ethernet interface, which participates to the bridging function and is not assigned an IP address; also, to avoid resetting active sessions, the Ethernet interface must not be disconnected from the upstream router. As described by Ingo, it is not possible to bridge the Wi-Fi client connections to the upstream router.
Testing wpa_supplicant permissions
wpa_supplicant is interfaced to wpa_cli through UNIX sockets and when logging into the system with pi user, you should be able to successfully control wpa_supplicant and related configuration.
The following steps allow verifying wpa_supplicant permissions.
Check who starts wpa_supplicant and that you do not have more services activating this daemon. Assuming that the tested interface is wlan0, if you rely on dhcpcd you should be able to verify that wpa_supplicant does not start after temporarily adding denyinterfaces wlan0
as the first line of /etc/dhcpcd.conf (sudo systemctl restart dhcpcd
).
After restoring /etc/dhcpcd.conf and restarting the service, you shoud get something like the following with ps -ef | grep wpa_supplicant
:
root 613 1 0 Feb20 ? 01:50:03 wpa_supplicant -B -c/etc/wpa_supplicant/wpa_supplicant.conf -iwlan0 -Dnl80211,wext
Notice the root user, its dependency to the parent process id 1 and the command line arguments (-B
means daemon, -c
with the appropriate configuration file, -i
with the related interface, -D
with standard drivers).
Specifically, you need to verify the presence of -i
command-line option if wpa_supplicant.conf declares GROUP=netdev.
Check also journalctl -t dhcpcd-run-hooks
; you should get dhcpcd-run-hooks[7548]: wlan0: starting wpa_supplicant
.
If you do ls -l /etc/wpa_supplicant/wpa_supplicant.conf
you should get the following:
-rw-r--r-- 1 root root 1155 Feb 27 14:26 /etc/wpa_supplicant/wpa_supplicant.conf
Notice the permissions, the owner and the group.
If you edit /etc/wpa_supplicant/wpa_supplicant.conf, yous should verify
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
Notice /var/run/wpa_supplicant directory and netdev group.
If you do ls -ld /var/run/wpa_supplicant
, tou should get the following:
drwxr-x--- 2 root netdev 100 Feb 20 11:01 /var/run/wpa_supplicant
Notice the permissions, the owner which should be root and the group which should be netdev, thanks to GROUP=netdev in wpa_supplicant.conf.
If you do ls -l /var/run/wpa_supplicant
, you should get something like
total 0
srwxrwx--- 1 root netdev 0 Feb 20 11:00 p2p-dev-wlan0
srwxrwx--- 1 root netdev 0 Feb 20 11:00 wlan0
Notice the presence of the wlan0
Unix socket (srwxrwx---
), as well as the P2P Device (p2p-dev-wlan0).
Notice the owner, that shall be root, and the group, which is again netdev.
If you do iw dev
with wpa_supplicant active, one of the returned item should be:
Unnamed/non-netdev interface
wdev 0x2
addr ee:11:6c:59:a3:d4
type P2P-device
txpower 31.00 dBm
which refers to the P2P device (type P2P-device
).
Now edit /etc/passwd, check the presence of root users and pi users:
root:x:0:0:root:/root:/bin/bash
...
pi:x:1000:1000:,,,:/home/pi:/bin/bash
...
Edit /etc/group anch check the netdev group:
netdev:x:109:pi
User pi should be associated to a number of groups, including netdev.
Now verify that you are logged into the system with *pi user, do id
:
uid=1000(pi) gid=1000(pi) groups=1000(pi),4(adm),20(dialout),24(cdrom),27(sudo),29(audio),44(video),46(plugdev),60(games),100(users),105(input),109(netdev),997(gpio),998(i2c),999(spi)
One of the group shall be netdev
.
Verify that you can successfully run wpa_cli, without a need of sudo:
wpa_cli -i wlan0 ping
wpa_cli -i p2p-dev-wlan0 ping
You should get PONG twice.
Run wpa_cli -i p2p-dev-wlan0 reconfigure
; you shoud get OK.
sudo
. To simplify it I like to work in a shell with user environment but with root rights. You can simply invoke this withsudo -Es
. You will find it in the steps and you will find also anexit
(if not rebooting). – Ingo Oct 09 '18 at 23:29cat >filename <<EOF
thing I only select the block with my mouse and paste it with the middle button of my mouse to the prompt of my RasPi console - very quick and efficient. – Ingo Oct 09 '18 at 23:30$ sudo su; # _
– Piskvor left the building Mar 04 '19 at 10:57up
again as you can read in section Details - wpa_supplicant for bridge (Step 6). I will give a hint in the setup section. – Ingo Mar 18 '19 at 11:57wlan0
andwlan1
under some circumstances, so I had to enforce static naming in/etc/udev/rules.d/72-static-name.rules
. (My Wi-Fi dongle does not support AP mode.) – Robin Dinse Mar 20 '19 at 16:04sudo vi /etc/systemd/resolved.conf
and setDNSStubListener=no
to make any progress (can't reconstruct where i found that solution actually :(). – icyerasor Aug 06 '19 at 22:29https://www.freedesktop.org/software/systemd/man/systemd.network.html
– n1nj4 Mar 24 '20 at 19:21IPv4ProxyARP
insystemd.network
, natively. Unfortunately that feates is poorly documented. – n1nj4 Apr 16 '20 at 18:53top
that significant CPU (15%) is being used bykworker/u2:1-brcmf_wq/mmc1:0001:01
and all I'm doing is viewingtop
SSH. This appears to be the driver? Any ideas? – Tyrel Jan 13 '21 at 04:35RTNETLINK answers: Name not unique on network
comes up when turning both AP and Station mode (non-bridged). Closest I could find is https://stackoverflow.com/q/51040111/11377112 I think, but it doesn't really help much as it says to change mac address of one of them, but I don't know how. – Animesh Sahu Feb 13 '22 at 06:11nl80211: kernel reports: Match already configured. ctrl_iface exists and seems to be in use - cannot override it. Delete '/var/run/wpa_supplicant/wlan1' manually if it is not used anymore.
– Animesh Sahu Feb 13 '22 at 06:18