Approximate reading time: 6 minutes
I have an old Thinkpad T420 that is still pretty good — the battery holds for ~4 hours, the CPU is an i7 from 2011, and it has 8GB of ram. I decided to use it as a router on the new house I'm moving to, going back to a similar setup to what I had a few years ago.
In 2014 I moved to a house, and I was starting to experiment with home automation. A few years before I had built a Hadoop cluster[archived] using Raspberry Pi[archived]s, so I had a bunch of them lying around. I used one to build a system that turned on the garden lights automatically at sunset if there was anyone home, and had the other Raspis set up as media players around the house, so I could play music in different rooms from my phone. I also built a motorized security camera in the backyard to keep an eye on my chickens.
One problem I had was with the wifi connectivity. The house was not big, but it was hard to get a good signal in some places, especially the backyard. After trying different solutions I ended up buying a few enterprise long range wireless access points, based on recommendations from co-workers at Facebook who knew way more about networking than I will ever know. Access points are different than wifi routers; they only provide the connectivity and you still need to run a server to give out IP addresses on your network. I used my original router for that, turning off its wifi and using it to provide IP addresses (via a DHCP server[archived]).
After a while I thought I could have more control, so I set up a Raspberry Pi as a DHCP server and router, bypassing the wifi router DHCP and using it only for internet connectivity. This gave the Raspberry Pi a real IP address, so I could login into it if I was not home, and from there to other computers in my network. It was also running a message queue[archived] that was used for many things: from tracking phone locations to enabling communication between all the different devices in my house.
In 2018 I moved to a small studio in San Francisco, and the previous tenant left behind a small Apple wifi thingy. It was good enough to cover the whole studio, and there wasn't much that I wanted to automate anyway. It served me well for the last 2 years, and was flexible enough that I was able to configure it to allow remote access to my machines, in case I was away and needed to retrieve a file.
Next week I'm moving to a new house, in a somewhat remote location. There's no mail service, and the only options for internet are cellular, satellite or microwave. I decided to sign up for the microwave service, and have 4G (cellular) as a backup. Since bandwidth is limited in both, I thought it would be a good opportunity to run my own router again, using Pi-hole[archived] to filter out ads and save bandwidth. Except that this time I decided to use the T420 laptop instead of a Raspberry Pi.
The laptop has a few advantages over the Raspi. First, it has a battery, so in case of power outages I can still keep my internet running for a couple hours. Second, if I need to troubleshoot anything on it I can just open its screen and I'm logged in. No need to login from another computer, which can be tricky if there's a network problem, for example.
I decided to set up before the move, to make sure everything would be working when I got there. My plan is to have the laptop run Debian[archived], a Linux distribution that I've used for more than 20 years in servers. The laptop will connect to the "main" internet through ethernet, and share the connection with the house through the long range access points (connected via a USB-ethernet adapter and a hub). I also want to have the laptop connected to the 4G internet, automatically switching to it when the main internet is down.
I've been working on this setup for a few days now, and it's been hard, mostly because the documentation for Debian is all over the place. When I started using Debian the network was configured in a file called /etc/network/interfaces
, but the docs[archived] now sat that's a legacy system and I should use systemd
instead. The problem is that much of their documentation on networking still assume you're using the legacy system; for example, their NetworkConfiguration[archived] page, which looks like a canonical and up-to-date source, doesn't mention systemd
at all.
The documentation for setting up a network with systemd
is confusing, and the options are not clear. For example, this is one way to enable DHCP on an interface:
[Network]
DHCP=yes
But this is also valid:
[Network]
DHCP=ipv4
What other options are valid? I don't know. What are configuration sections exist? I don't know. But I was able to get a basic setup working with systemd
, and I discovered that it makes it really easy to run a DHCP server and enable IP forwarding/masquerading to share an internet connection:
[Network]
Address=10.0.0.1/24
DHCPServer=yes
IPMasquerade=yes
IPForward=yes
[DHCPServer]
PoolOffset=1
PoolSize=200
EmitDNS=yes
DNS=10.0.0.1
This was basically all I needed to do in order to have the laptop sharing the internet through the access points, and having the clients use Pi-hole as a DNS server to block advertisement! I still have many questions: can I give static IP addresses to client depending on their MAC address? I don't know, and I couldn't figure it out.
While this got me 80% of what I wanted to do, there was one component missing: having the 4G modem connected, and have the laptop switch to it automatically in case the main internet was down. The modem I'm using is an old Pantech UML290. Last year I found two of them in the trash outside my building, so I ordered a new SIM card from Verizon and was able to get it running on a Windows machine. Running it on Linux should be easy... right?
The Debian docs[archived] aren't very useful, since they're for 3G modems that connect through a dial up interface. When I plug the UML290 in my laptop it automatically creates a network interface called wwan0
, so in theory if I run a DHCP client on the interface it should give me an IP address and internet connectivity. Of course it doesn't work like that, and after more than a week the only way I was able to get it to connect was:
After a few hours of research I discover in a mailing list that ModemManager[archived] has better support for the UML290. ModemManager
is a companion tool to NetworkManager
, which is yet another way of configuring your network. Since it was designed for laptop users, it has better support for USB modems. I also read that it can automatically choose between different networks, favoring wired connections of wireless ones, so I'm hoping it will provide automatically fallback to 4G if the main internet is down.
Last night I undid the network configuration I had done with systemd
, and installed NetworkManager
and ModemManager
. I was able to add the modem and connect to the internet, though the IPV6 DNS seems to be broken. Configuring everything is unnecessarily complicated because of missing and incomplete docs, and also because configuration is stored in some kind of database, requiring you to run a special command in order to change it. Many options are undocumented, and other are inconsistent — for example, set ipv4.method disabled
vs. set ipv6.method ignore
to disable them.
I also tried using documentation from Ubuntu, but I don't think they're any better. The documentation for sharing a connection[archived], for example, is 3 paragraphs long, and says "That requires running commands similar to".
"Similar to"? How do I figure out the exact commands? I don't know.
Currently I have systemd
doing half of what I need (DHCP, NAT) and NetworkManager
doing the other half (4G, fallback?). I'm going to give NetworkManager
a try, even though it's not recommended for servers, and post an update if it works.
You can engage with this post on Twitter or Webmention.
Updating my recent post on Setting up a Linux router in 2020. I was able to get it working, after a few hickups. I configured NetworkManager to share the internet with the interface associated with the access points. At first the connected clients didn't have access to the internet, but I noticed I had two different IPs associated to the interface, from when I had first configure Pi-hole.
I just created a new assistant[archived] for my blog engine, displaying the estimated reading times on longer articles. You can see an example in my latest post about building a Linux router.