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 [email protected]
# 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 [email protected]
env SYSTEMD_EDITOR=tee sudo -E systemctl edit --system [email protected] <<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 [email protected]
sudo systemctl enable [email protected]
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/[email protected]"
install -v -m 644 files/override.conf "${ROOTFS_DIR}/etc/systemd/system/[email protected]/"
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
[email protected]
[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 [email protected]
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]: [email protected]: Main process exited, code=exited, status=255/EXCEPTION
Nov 28 12:52:10 raspberrypi systemd[1]: [email protected]: 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?