Tech —

The Ars guide to building a Linux router from scratch

Remember how our homebrew router embarrassed off-the-shelf options? Go make your own.

After finally reaching the tipping point with off-the-shelf solutions that can't match increasing speeds available, we recently took the plunge. Building a homebrew router turned out to be a better proposition than we could've ever imagined. With nearly any speed metric we analyzed, our little DIY kit outpaced routers whether they were of the $90- or $250-variety.

Naturally, many readers asked the obvious follow-up—"How exactly can we put that together?" Today it's time to finally pull back the curtain and offer that walkthrough. By taking a closer look at the actual build itself (hardware and software), the testing processes we used, and why we used them, hopefully any Ars readers of average technical abilities will be able to put together their own DIY speed machine. And the good news? Everything is as open source as it gets—the equipment, the processes, and the setup. If you want the DIY router we used, you can absolutely have it. This will be the guide to lead you, step-by-step.

What is a router, anyway?

At its most basic, a router is just a device that accepts packets on one interface and forwards them on to another interface that gets those packets closer to their eventual destination. That's not what most of us are really thinking when we think of "a router" in the sense of something we'll plug into our home or office to get to the Internet, though. What do we need to have before any homebrew device looks like a router?

For most of us, the important bits will be routing, NAT, DHCP, and DNS. In this build, we'll use the same free and open source implementations of these technologies that power huge chunks of the Internet infrastructure itself.

Routing

This one's easy—the Linux kernel itself handles it for us without any additional software. We're not looking for any complex multiple-route stuff that would need Border Gateway Protocol or the like, so we can basically just enable forwarding between interfaces, set up a few rules to tell us when not to forward between interfaces, and call it a day.

Network Address Translation

In a nutshell, NAT lets you access routeable (Internet) IP addresses from non-routeable (local, private) IP addresses. A router does this by accepting traffic from the LAN, substituting its own public IP address for the LAN IP address the packet came from, and sending the packet on to the Internet. When replies to the packet come back to the router, the router looks up which LAN IP address the original packet came from, puts that IP address back into the packet in place of its own, and forwards the packet back to the original machine.

We need NAT because we don't have enough public IP addresses for every personal computer and device out there, not by a long shot. IPv6 will change all that, but when we make the final switchover to IPv6... well, your guess is as good as mine. We aren't going to even try to cover IPv6 in this article; it's a complicated matter. For now, we'll note that we need NAT, the Linux kernel makes that available as the MASQUERADE function of iptables, and move on.

Dynamic Host Configuration Protocol

Yep, that's what "DHCP" stands for. The DHCP server in a consumer router hands out IP addresses, default gateway information, network and broadcast addresses, and DNS server addresses. We want our router to do the same thing for us—which the Internet Software Consortium's own reference DHCP service will do just fine.

Domain Name Service

You don't strictly need to have local DNS service on your router. You could just tell all of your clients to use a publicly available DNS resolution service, like Level 3's 4.2.2.4 or Google's 8.8.8.8. Still, it's certainly nice to have. We're going to go old school here and use the same DNS server application that the Internet itself does: BIND, the Berkeley Internet Name Daemon. Having our own DNS server locally means that we'll typically get DNS queries resolved faster, more accurately, and in strict accordance with caching and expiration protocols set in the domain names themselves when compared to using somebody else's DNS server. It also means less total DNS traffic since we're doing that caching locally.

Router hardware

As we disclosed last time, this decision was pretty simple: a dual-gigabit-NIC mini-PC from Alibaba and an inexpensive SSD from Newegg. (Update, 4/18: Though that vendor seems to have raised its prices on Alibaba, you can still get a basically identical mini-PC option through Amazon.)

Those particular choices sparked a lot of comments. Was this the absolute least expensive possible setup? No, definitely not. So why did I use the pieces I did? For one thing, I wasn't actually sure where the homebrew would end up on the performance spectrum. I wanted to get an efficient but relatively powerful CPU... the kind you'd find in, say, an Intel-based Chromebook.

Looking for a high-performing CPU ruled out older Atom-based nettops, which are notoriously anemic for x86 CPUs. It didn't necessarily rule out parts like PCEngines' AMD Bobcat-based apu1d4, but that just wasn't quite what I wanted to play with on the first go-round. The Ivy Bridge Celeron I got was exactly what I wanted—about as high performance as you can get while staying easy on the power bill.

There was one other personal "pro" about buying from an Alibaba vendor. My kids attend a Mandarin language immersion school, and it was kind of awesome discovering a handwritten note on the inside of the packaging, showing it to my kids, and telling them this was actually written by a person in China who was building the new thing Daddy got. (I'm told that the handwriting translates to "high performance computer with two networks," but I don't speak Chinese, and my kids' teacher doesn't speak nerd. There could be something lost in the translation.)

It's a small world after all.
Enlarge / It's a small world after all.
Jim Salter

With the other parts selected, let's start with the 120GB SSD. That's laughable overkill, right? Well, yes, it's absolutely way more storage than you need for a router. But I wanted solid state both for fast boot times and for not being reliant on a spinning chunk of rust. I also wanted a brand I know, since really dodgy SSDs can be, well, really dodgy. That ruled out the $20 no-brand SSDs I could have found on Alibaba itself. And when I went shopping for SSDs from known brands, what I found was that dropping from 120GB to 32GB would only have saved me $5, if that. I went with the 120GB Kingston, and as a nice bonus, I now don't have to worry about accumulated kernels from security updates filling up my root partition and screwing things up.

In theory, I could have used a cheap SD card instead of the SSD. But in practice, the Alibaba page didn't specify whether the BIOS was capable of actually booting from SD or not, so I didn't want to rely on it. (I did check when I got the router in hand, and yes, it will boot from SD just fine). SD cards also tend to be noticeably slower than SSDs. This doesn't matter for the operation of the router, but it does matter for reboot times. (Plus, hey, I wanted to spoil myself! 120GB Kingston SSD it was.)

Since the Partaker mini-PC came complete except for the SSD, there really wasn't much of a hardware "build" process on my end. Basically, all it took was plugging in one SATA and one SATA power cable. Whether that's a feature or a bug depends on just how badly you want to feel like you turned a bunch of screws.

The manufacturer provided four mounting holes for the storage on the removable cover plate of the router, but since I chose an SSD that weighs effectively nothing, I elected to ignore them. There's enough space to just sort of nestle it over to the side of the motherboard, and that way I don't have to worry about accidentally yanking on a cable when I remove the access plate for the router.

That's really it to the build process on this one: remove PC from box, open PC, plug in SSD, close PC, call it a day. Call it 10 minutes, really.

Channel Ars Technica