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 interfacewlan0
: my wireless interfacelo
: loopbackwwan0
: 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
- use
systemd-networkd
to create a bridge, assign all wired an the wireless (wlan0
) interface - configure the modem using
modemmanager
/network-manager
. To simplify the setup I am usingnetwork-manager
to configure the modem after it has been brought up bymodemmanager
, but futuresystemd-networkd
releases might be able to directly communicate with modemmanager. This should further reduce the memory usage (currently the running system has a RSS of 100mb, removingnetwork-manager
might remove a quarter of that)
initial cleanup
I started with the Ubuntu 64bit Raspberry image and removed some stuff:
- removed
snapd
, not needed on a router - removed
netplan.io
, as I will usenetwork-manager
andsystemd-networkd
- removed
unattended-upgrades
- removed
cron as
I rather would use systemd timed jobs - removed
rsyslog
as I am fond ofjournald
, and if there’s nocron
package installedjournald
will persist logs for me
I did have to install some other packages though:
modemmanager
,network-manager
andlibqmi-utils
for managing my modembridge-utils
for managing and inspecting my network bridgehostapd
for creating an access pointiptables
just 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 network-manager
and wpa_supplicant
from not interfering with my access point configuration.
First, make sure that wpa_supplicant
will not interfere:
|
|
To prevent 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 /etc/NetworkManager/conf.d/unmanaged.conf
:
|
|
Please notice that I explicitely declared wlan0
as unmanaged-device (for network-manager).
Now I can just copy my old hostapd config over /etc/hostapd/hostapd.conf
:
|
|
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 00-br0.netdev
:
|
|
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 00-br0.network
:
|
|
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). IPForward=true
and 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 10-bind-en.network
:
|
|
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?
ModemManager configuration
We will lookup and configure stuff through the command line tools nmcli
and 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.