Building a Router with Ubuntu Linux

For my router project, I used Ubuntu server and because so much of this information is so hard to find, I’ll be documenting here for anyone interested.

To start, a barebones installation of Ubuntu Server 14 LTS. First things first, install and configure openssh. Setup your public key too, don’t need to be entering a password like a savage.

Nothing special about the install. I named my machine charon after the Mass Relay in the Sol system in the Mass Effect series. It’s an old Dell with 3 GB of RAM and a 64 GB SSD, massively overpowered for what we need but this is literally the worst machine I own, so let’s move on.

Now, our connections. In my case, eth0 is the external connection, through which I’ll be doing my initial setup and eth1 is the connection that will eventually face my new network. br0 is then the bridge between these that provides basic connectivity. /etc/network/interfaces is as follows:

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
    address 192.168.1.111
    netmask 255.255.255.0
    gateway 192.168.1.1

auto eth1
iface eth1 inet static
    address 10.10.10.1
    network 10.10.10.0
    netmask 255.255.255.0
    broadcast 10.10.10.255

auto br0
iface br0 inet static
    address 10.10.10.1
    network 10.10.10.0
    netmask 255.255.255.0
    broadcast 10.10.10.255
    bridge-ports eth0 eth1

Now here’s a tricky bit, because of how Ubuntu sets up it’s network connections, you need to list the connection you’ll be ssh’ing in through first. This means when we get to that point where it’s time to forbid ssh connections from the outside, we’ll need to turn these around or the machine will be inaccessible.

IP Tables

Basic throughput is not enough for what a router needs to do, we net NAT, or Network Address Translation, to make this work properly. So let’s get that going, with four not at all simple commands:

iptables -A FORWARD -o eth0 -i eth1 -s 10.10.0.0/24 -m conntrack --ctstate NEW -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -F POSTROUTING
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

And save those somewhere convenient:

iptables-save | sudo tee /etc/iptables.sav

In your rc.local file, add this to make sure they’re always loaded (remember to update this if you change anything or you will be very sad):

iptables-restore < /etc/iptables.sav

Enable IP Forwarding:

sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"

Open up /etc/sysctl.conf and uncomment this:

net.ipv4.ip_forward=1

Setup DCHP

Up next, I installed dchp3-server with apt-get install dhcp3-server. Proved to be the simplest to configure, mine is a pretty straightforward setup using the DCHP range of everything above 200. Here’s my /etc/dhcp/dhcpd.conf file:

ddns-update-style none;

option domain-name "unsc.fleet";
option domain-name-servers 10.10.10.1;
option broadcast-address 10.10.10.255;
option subnet-mask 255.255.255.0;
option routers 10.10.10.1;

default-lease-time 600;
max-lease-time 7200;

log-facility local7;

subnet 10.10.10.0 netmask 255.255.255.0 {
        range 10.10.10.200 10.10.10.250;
}

Then I created the file /etc/defaults/dhcp3-server and added this:

INTERFACES="eth1"

To make sure DHCP would only answer on the eth1 interface. Testing it:

DHCP Test

Everything looks good.

Bridge the Traffic

Sadly I was never able to get this working. I eventually bought a DD-WRT Buffalo N300 router which I’ve enjoyed ever since.

Sources

If you run into problems, these are my best resources which I consulted to a slavish degree through the course of this project. Dig it, and best of luck!