We're using a forked version of pi-gen (https://github.com/RPi-Distro/pi-gen) to build custom RPi images. As part of the build, we're trying to set the RPi up as an Access point as WiFi router/repeater with additional WiFi-dongle (thanks @Ingo), and have added this step to one of our stages in RPi:
#!/bin/bash -e
# Disable classic networking
sudo systemctl mask networking.service dhcpcd.service
sudo mv /etc/network/interfaces /etc/network/interfaces~
sudo sed -i '1i resolvconf=NO' /etc/resolvconf.conf
# Enable systemd-networkd
sudo systemctl enable systemd-networkd.service systemd-resolved.service
sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
# Configure wpa_supplicant for wlan0 as access point
sudo cat > /etc/wpa_supplicant/wpa_supplicant-wlan0.conf <<EOF
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
ssid="${AP_WPA_ESSID}"
mode=2
key_mgmt=WPA-PSK
psk="${AP_WPA_PASSWORD}"
frequency=2412
}
EOF
sudo chmod 600 /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
sudo systemctl disable wpa_supplicant.service
sudo systemctl enable wpa_supplicant@wlan0.service
# Configure wpa_supplicant for wlan1 as client
sudo cat > /etc/wpa_supplicant/wpa_supplicant-wlan1.conf <<EOF
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
ssid="${CLIENT_WPA_ESSID}"
psk="${CLIENT_WPA_PASSWORD}"
}
EOF
sudo chmod 600 /etc/wpa_supplicant/wpa_supplicant-wlan1.conf
sudo systemctl enable wpa_supplicant@wlan1.service
env SYSTEMD_EDITOR=tee sudo -E systemctl edit --system wpa_supplicant@wlan1.service <<EOF
[Service]
ExecStartPre=/sbin/iptables -t nat -A POSTROUTING -o wlan1 -j MASQUERADE
ExecStopPost=-/sbin/iptables -t nat -D POSTROUTING -o wlan1 -j MASQUERADE
EOF
# Configure interfaces
sudo cat > /etc/systemd/network/08-wlan0.network <<EOF
[Match]
Name=wlan0
[Network]
Address=192.168.4.1/24
IPForward=yes
DHCPServer=yes
[DHCPServer]
DNS=1.1.1.1 8.8.8.8
EOF
sudo cat > /etc/systemd/network/12-wlan1.network <<EOF
[Match]
Name=wlan1
[Network]
DHCP=yes
EOF
When we run the new image, we're getting the following error during the boot:
[ TIME ] Timed out waiting for device /subsystem/net/devices/wlan1.
[DEPEND] Dependency failed for WPA … (interface-specific version).
What dependency are we missing?
UPDATE 1
Following the pi-gen
convention, I'm now "installing" the systemd files:
#!/bin/bash -e
install -v -m 600 files/wpa_supplicant-wlan0.conf "${ROOTFS_DIR}/etc/wpa_supplicant/"
install -v -m 600 files/wpa_supplicant-wlan1.conf "${ROOTFS_DIR}/etc/wpa_supplicant/"
install -v -m 600 files/08-wlan0.network "${ROOTFS_DIR}/etc/systemd/network/"
install -v -m 600 files/12-wlan1.network "${ROOTFS_DIR}/etc/systemd/network/"
# Disable classic networking
on_chroot << EOF
sudo systemctl mask networking.service dhcpcd.service
sudo mv /etc/network/interfaces /etc/network/interfaces~
sudo sed -i '1i resolvconf=NO' /etc/resolvconf.conf
# Enable systemd-networkd
sudo systemctl enable systemd-networkd.service systemd-resolved.service
sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
sudo systemctl disable wpa_supplicant.service
sudo systemctl enable wpa_supplicant@wlan0.service
sudo systemctl enable wpa_supplicant@wlan1.service
EOF
....but I'm not sure what to do with the systemctl edit
steps.
UPDATE 2
Made the switch to using instructions in Access point as WiFi router/repeater, optional with bridge and have updated the pi-gen scripts as follows:
00-run.sh:
#!/bin/bash -e
install -v -m 644 files/hostapd.service "${ROOTFS_DIR}/etc/systemd/system/"
on_chroot << EOF
systemctl unmask hostapd
systemctl enable hostapd
# Disable classic networking
systemctl mask networking.service dhcpcd.service
mv /etc/network/interfaces /etc/network/interfaces~
sed -i '1i resolvconf=NO' /etc/resolvconf.conf
# Enable systemd-networkd
systemctl enable systemd-networkd.service systemd-resolved.service
ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
EOF
install -v -m 644 files/hostapd.conf "${ROOTFS_DIR}/etc/hostapd/"
on_chroot << EOF
sed -i 's/^#DAEMON_CONF=.*$/DAEMON_CONF="\/etc\/hostapd\/hostapd.conf"/' /etc/default/hostapd
EOF
install -v -m 644 files/wpa_supplicant-wlan0.conf "${ROOTFS_DIR}/etc/wpa_supplicant/"
on_chroot << EOF
systemctl disable wpa_supplicant.service
systemctl enable wpa_supplicant@wlan0.service
EOF
install -d "${ROOTFS_DIR}/etc/systemd/system/wpa_supplicant@wlan0.service.d"
install -v -m 644 files/override.conf "${ROOTFS_DIR}/etc/systemd/system/wpa_supplicant@wlan0.service.d/"
install -v -m 644 files/08-wlan0.network "${ROOTFS_DIR}/etc/systemd/network/"
install -v -m 644 files/12-ap0.network "${ROOTFS_DIR}/etc/systemd/network/"
files/hostapd.service:
[Unit]
Description=Advanced IEEE 802.11 AP and IEEE 802.1X/WPA/WPA2/EAP Authenticator
#After=network.target
Wants=wpa_supplicant@wlan0.service
[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 wlan0 interface add ap0 type __ap
ExecStart=/usr/sbin/hostapd -B -P /run/hostapd.pid -B $DAEMON_OPTS ${DAEMON_CONF}
ExecStopPost=-/sbin/iw dev ap0 del
[Install]
WantedBy=multi-user.target
files/hostapd.conf:
interface=ap0
driver=nl80211
ssid=RPiWiFi
country_code=GB
hw_mode=g
channel=1
auth_algs=1
wpa=2
wpa_passphrase=pass1234
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
files/wpa_supplicant-wlan0.conf:
country=GB
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
ssid="OfficeWiFi"
psk="1234pass"
key_mgmt=WPA-PSK
}
files/override.conf:
[Unit]
BindsTo=hostapd.service
After=hostapd.service
[Service]
ExecStartPost=/sbin/iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE
ExecStopPost=-/sbin/iptables -t nat -D POSTROUTING -o wlan0 -j MASQUERADE
files/08-wlan0.network:
[Match]
Name=wlan0
[Network]
IPForward=yes
DHCP=yes
files/12-ap0.network:
[Match]
Name=ap0
[Network]
Address=192.168.4.1/24
DHCPServer=yes
[DHCPServer]
DNS=1.1.1.1 8.8.8.8
...but we're getting the following error with wpa_supplicant@wlan0.service
Nov 28 12:52:10 raspberrypi wpa_supplicant[350]: Could not set interface wlan0 flags (UP): Name not unique on network
Nov 28 12:52:10 raspberrypi wpa_supplicant[350]: nl80211: Could not set interface 'wlan0' UP
Nov 28 12:52:10 raspberrypi wpa_supplicant[350]: nl80211: deinit ifname=wlan0 disabled_11b_rates=0
Nov 28 12:52:10 raspberrypi wpa_supplicant[350]: Could not set interface wlan0 flags (UP): Name not unique on network
Nov 28 12:52:10 raspberrypi wpa_supplicant[350]: WEXT: Could not set interface 'wlan0' UP
Nov 28 12:52:10 raspberrypi wpa_supplicant[350]: wlan0: Failed to initialize driver interface
Nov 28 12:52:10 raspberrypi systemd[1]: wpa_supplicant@wlan0.service: Main process exited, code=exited, status=255/EXCEPTION
Nov 28 12:52:10 raspberrypi systemd[1]: wpa_supplicant@wlan0.service: Failed with result 'exit-code'.
Nov 28 12:52:10 raspberrypi systemd[1]: Failed to start WPA supplicant daemon (interface-specific version).
UPDATE 3
Had another chance to take a look at this. The above error appears to be because both the wlan0
and ap0
network interfaces have the same MAC address:
$ ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 74:da:38:c9:b1:15 brd ff:ff:ff:ff:ff:ff
3: ap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether 74:da:38:c9:b1:15 brd ff:ff:ff:ff:ff:ff
Can I set the hwaddress
for each network interface ahead of time? Or is it an issue with the USB/WiFi dongle? What USB/WiFi dongle is best for this setup?
pi-gen
has a way to copy/install systemd files (https://github.com/RPi-Distro/pi-gen/blob/master/stage2/02-net-tweaks/01-run.sh) that should help with the permissions issue. I've updated my script to use that approach, but I'm not sure what to do with thesystemctl edit
steps. Can the contents of that EOF be included in a file that I can install usingpi-gen
? – timborden Nov 06 '19 at 16:16systemctl edit
. About your update: I don't knowpi-gen
but I see you are still using sudo? Is it really needed withinon_chroot
? – Ingo Nov 06 '19 at 17:04pi-gen
and its installation routines. At a first glance it doesn't look bad but I don't oversee its dynamic: when is what installed and started. The setup Access point as WiFi router/repeater, optional with bridge have to meet a very important condition: starting the services for ap0, hostapd and wpa_supplicant strict in this order as described in section "♦ Details". Typical are conflicts with interfaces if it isn't given. You should check the starting order. – Ingo Nov 28 '19 at 19:09journalctl
) and the services appear to be starting in the desired order. I was also able to understand the error from thewpa_supplicant@wlan0.service
(I've updated the question) If you've got time to take another look, it would be greatly appreciated. – timborden Dec 13 '19 at 16:18