So I’ve been using a Raspberry Pi 4b+ together with a WaveShare LTE Modem as 4G router/access-point for my home network setup. I do like my hardware to be quiet and thus fan-less, alas the Raspberry Pi 4b+ gets a tad on the warm side. So this was a perfect opportunitiy to play around with an older Raspberry Pi 3b+ which should use approx. 20-25% less power (both, during idle and load) and with “new” software.
My existing setup was working fine, but I’ve read a lot about systemd-networkd recently, so this is a perfect time to try to use it. In addition, the shell script that was used to activate the 4G network interface always felt like a kludge, so let’s try to do this in a cleaner way using modemmanager and network-manager. During the setup I found out, that in the near future I might be able to cut out network-manager as systemd-networkd/modemmanager might be sufficient for my needs.
network interfaces and target setup
What network interfaces do I have?
enxb827eb480c95: wired network interface
wlan0: my wireless interface
wwan0: the add-on waveshare sim-7600e 4G modem
The goal is to create a software access-point using hostapd (which will be using the
wlan0 interface). The
wlan0 interface and the wired network interface should both be placed upon a software bridge (
br0) so you can connect a client either through a ethernet cable or through the access-point. Both devices on the bridge should have the same local IP-address (192.168.111.1) and new clients should get a new IP-address through DHCP.
The 4G modem should automatically connect to my internet provider (T-Mobile) on startup and all connected devices should be able to access the Internet through the 4G modem.
how to get to a simple network setup
To achieve my goal, I did the following steps:
- replace some services with systemd-provided services
- configure hostapd to automatically create a soft access point using the embedded wireless card
systemd-networkdto create a bridge, assign all wired an the wireless (
- configure the modem using
network-manager. To simplify the setup I am using
network-managerto configure the modem after it has been brought up by
modemmanager, but future
systemd-networkdreleases might be able to directly communicate with modemmanager. This should further reduce the memory usage (currently the running system has a RSS of 100mb, removing
network-managermight remove a quarter of that)
I started with the Ubuntu 64bit Raspberry image and removed some stuff:
snapd, not needed on a router
netplan.io, as I will use
cron asI rather would use systemd timed jobs
rsyslogas I am fond of
journald, and if there’s no
journaldwill persist logs for me
I did have to install some other packages though:
libqmi-utilsfor managing my modem
bridge-utilsfor managing and inspecting my network bridge
hostapdfor creating an access point
iptablesjust in case
Configure software access point (wlan0)
I already had a
hostapd.conf but I did had to do some try-and-error to finally get
wpa_supplicant from not interfering with my access point configuration.
First, make sure that
wpa_supplicant will not interfere:
network-manager from doing weird stuff I added my wireless interface to the “do not control this for me” list. I am using a vanilla
/etc/NetworkManager/NetworkManager.conf (without any changes):
Notice that the
keyfile plugin is enabled by default. I am using this to prevent network-manager from configuring my wireless card. To achieve this, I added the following as
Please notice that I explicitely declared
wlan0 as unmanaged-device (for network-manager).
Now I can just copy my old hostapd config over
I am quite sure, that the configuration could be improved, but it works for now. Please note, that I am configuring
wlan0 as network interface (
interface=wlan0) and instruct
hostapd to put newly connected clients onto a bridge (
bridge=br0). We will configure the bridge after we enabled hostapd (so that the access point automatically starts on bootup). To do enable hostapd we’ll just use systemd:
Next: configure the bridge
Configure a bridge using systemd-networkd
All systemd-networkd configuration can be found under
/etc/systemd/network. For my setup we will use three cnofig files: one to create the bridge device, one to configure IPs for the bridge (and enable ip forwarding/routing) and one to add all wired interfaces to the bridge. Hostapd will add itself to the bridge (as this was configured through
bridge=br0 in its configuration file).
Lets start by creating a new bridge named
br0 in a config file named
Prettry straight forward, the config file just contains the name that the bridge will use and that it’s a bridge. Now lets add some IP configuration through the config file
We initially “match” the ip config to
br0, as in “let’s configure our bridge br0”. The network section is magic: through Address we configure our IP-address and network subnet. Using
DHCPServer=true enables systemd-networkd internal DHCP server to serve clients (such as wired or wireless connected computers), we further configure the DHCP Server in the “DHCPServer” section (mostly pushing a DNS server and only allowing ips ranging from 100-164 so that there is no overlap with statically configured devices on my network).
IPMasquerade=both (you could also use
ipv4 instead of
both) actually configured all ip forwarding and masquerading. So no manually added iptables rules this time.. this feels like magic.
Now lets add a simple rule to automatically add all wired devices to the bridge through
To be honest, I just wasn’t able to remeber the full device name of the ethernet device, so I just added all devices starting with
en* (which would also include eth0, etc.).
And that’s it for systemd-networkd. Did I mention that this feels a bit like magic?
We will lookup and configure stuff through the command line tools
mmcli. Initially check if a modem was even found and enable it:
Not sure if this step was needed, but it’s always a good idea to check if those pesky things are working before using them.
Now we’ll do the easy way and use network-manager to configure a new connection, setup the APN (“internet.t-mobile.at”) and configure the connection/device to automatically start on bootup:
..and reboot the system
And that’s acutally it. Reboot the system (
systemctl reboot) and hopefully your Raspberry Pi is now acting as an 4G internet router plus access point.