back
Written 2022-08-04
The place where I program has the worst connection to my router throughout the whole house. Obviously, this isn't ideal for most programming workloads such as looking up documentation and especially for cloning the crates.io index.
Luckily, I had Ethernet wired through the whole house, and I also had a Raspberry Pi and about 30 minutes.
For my setup, I used a Raspberry Pi 0 W because it's dirt cheap and has WiFi built-in.
You'll also need a Ethernet-to-MicroUSB adapter if you're on one of the Raspberry Pi 0 models (such as 02, 0W, and 0WH), like I am. If you're on a Pi 1-4, you can just use the onboard Ethernet port.
Just in case, you might also want to keep around a USB keyboard and an HDMI monitor around in case anything goes wrong and you can't access the Pi using SSH.
This setup will break any DNS servers already running on your Pi, such as Pi-Hole, so make sure you know what you're getting into.
You need to be root for the whole guide, so either use sudo -Es
or sudo su
to switch to the root user.
First, you have to remove the "classic" networking. You can do this while connected to SSH, so don't worry.
systemctl daemon-reload
systemctl disable --now ifupdown dhcpcd dhcpcd5 isc-dhcp-client isc-dhcp-common rsyslog
apt --autoremove purge ifupdown dhcpcd dhcpcd5 isc-dhcp-client isc-dhcp-common rsyslog
rm -r /etc/network /etc/dhcp
systemctl disable --now avahi-daemon libnss-mdns
apt --autoremove purge avahi-daemon
Next, install and set up systemd-resolved and systemd-networkd.
apt install libnss-resolve
ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
apt-mark hold avahi-daemon dhcpcd dhcpcd5 ifupdown isc-dhcp-client isc-dhcp-common libnss-mdns openresolv raspberrypi-net-mods rsyslog
systemctl enable systemd-networkd.service systemd-resolved.service
wpa_supplicant is what Raspbian uses for its WiFi configuration. We need to configure it to broadcast an access point that our devices can later connect to.
First, create /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
and add the following contents:
# /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
country=US
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
ssid="..." # Set to your desired network name
mode=2
frequency=2437 # change this to 5000 if you want a 5GHz access point
#key_mgmt=NONE # uncomment this if you don't want a password
# delete next 3 lines if key_mgmt=NONE
key_mgmt=WPA-PSK
proto=RSN WPA
psk="..." # set this to your desired password
}
Your password will be stored in plain text so make sure this file is not readable by anyone you don't want seeing the password
Now, we need to create a bridge network interface. This interface will bridge packets coming from the WiFi interface (wlan0
) and send them over the Ethernet interface (eth0
). This will allow devices connected to the Pi to appear on the same subnet as devices connected to the router itself.
First, define the interface:
; /etc/systemd/network/02-br0.netdev
[NetDev]
Name=br0
Kind=bridge
Then, tell systemd-networkd
to bridge packets to eth0
:
; /etc/systemd/network/04-br0_add-eth0.network
[Match]
Name=eth0
[Network]
Bridge=br0
Finally, configure network settings on the bridge:
; /etc/systemd/network/12-br0_up.network
[Match]
Name=br0
[Network]
MulticastDNS=yes
DHCP=yes
Now we have our bridge configured, but we need to tell our WiFi interface to actually use it. To do this, edit the .service
file:
systemctl edit wpa_supplicant@wlan0.service
This will open up your editor. In this editor add these lines:
[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
Finally, reboot. That's it! Your shiny new network extender should appear in the list of local WiFi networks. Connect to it, and see the difference!
If you have any questions, feel free to shoot me an email!