132 lines
5.5 KiB
YAML
132 lines
5.5 KiB
YAML
date: 2014-08-19
|
|
tags:
|
|
- linux
|
|
- networking
|
|
title: Building My Own Home Router, Part 1
|
|
---
|
|
This is the first of a series of blog posts on building my own home router from scratch using Debian. My hopes are that by sharing my experiences, it can help others in this endeavor.
|
|
---
|
|
I've been kicking around the idea of building my own router for a while now, mostly due to the fact that my trusty [WRT54GL][1] is grealy limted by what it can do with its measly 4 MB of flash and weak CPU. After months of casually searching and trying (unsuccessfully) to re-purpose some old hardware, I finally found what I've been looking for: a cheap-ish, low-power, rackmount server with more than one NIC.
|
|
|
|
# The Hardware
|
|
|
|
* [Intel D2500CCE Mini-ITX motherboard in a rackmount case][2]
|
|
* [Intel 7260-ac Mini-PCIe card with antenna][3] - there are some issues with this, which I'll cover in a later post
|
|
|
|
I can't believe that I didn't think to check the various Mini-ITX resellers for something like this, because this is almost exactly what I've always been looking for. I got a 2-NIC board since I'm cheap and already have a gigabit switch, but you can easily find boards with more ports if you don't mind shelling out the extra cash.
|
|
|
|
Once the equipment got to my apartment, I slapped in some old laptop RAM and a spare 2.5" drive and got Debian installed.
|
|
|
|
|
|
# 802.3 and IPv4
|
|
|
|
The first order of business was to replicate the core functionality of my old router: IPv4 routing and Ethernet connectivity. The plan was to use eth0 as my public interface (plugged into my cable modem) and eth1 as my internal interface. Before I even plugged in anything, I wrote a basic `/etc/network/interfaces` file.
|
|
|
|
```
|
|
auto lo
|
|
iface lo inet loopback
|
|
|
|
# outside
|
|
allow-hotplug eth0
|
|
iface eth0 inet dhcp
|
|
hwaddress ether AA:BB:CC:DD:EE:FF
|
|
dns-search home.nickpegg.com nickpegg.com
|
|
dns-nameservers 8.8.8.8 8.8.4.4
|
|
|
|
# inside
|
|
auto eth1
|
|
iface eth1 inet static
|
|
address 10.0.0.1
|
|
netmask 255.255.255.0
|
|
```
|
|
|
|
Note the `hwaddress ether` line there. Since my ISP (whose name shall not be spoken (not Voldemort, but [just as evil][4])) locks me to a single MAC address, my new router had to spoof my old router's MAC address, which was spoofed from my laptop that I originally set the connection up with. If you seemingly can't get a DHCP lease on your public interface, this is likely the problem.
|
|
|
|
|
|
Now that I had my interfaces configured and rarin' to go, I had to make sure that my ip{,6}tables rules were in order before plugging in.
|
|
|
|
#### rules.v4
|
|
```
|
|
*nat
|
|
:PREROUTING ACCEPT [2:125]
|
|
:INPUT ACCEPT [1:65]
|
|
:OUTPUT ACCEPT [4:260]
|
|
:POSTROUTING ACCEPT [0:0]
|
|
-A POSTROUTING -o eth0 -j MASQUERADE
|
|
COMMIT
|
|
*filter
|
|
:INPUT DROP [0:0]
|
|
:FORWARD ACCEPT [0:0]
|
|
:OUTPUT ACCEPT [0:0]
|
|
-A INPUT -i lo -j ACCEPT
|
|
-A INPUT -i eth1 -j ACCEPT
|
|
-A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
|
|
-A INPUT -i eth0 -p icmp -m icmp --icmp-type 8 -j ACCEPT
|
|
-A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
|
|
-A FORWARD -i eth1 -o eth0 -j ACCEPT
|
|
COMMIT
|
|
```
|
|
|
|
#### rules.v6
|
|
```
|
|
*filter
|
|
:INPUT DROP [0:0]
|
|
:FORWARD ACCEPT [0:0]
|
|
:OUTPUT ACCEPT [0:0]
|
|
-A INPUT -i lo -j ACCEPT
|
|
-A INPUT -i eth1 -j ACCEPT
|
|
COMMIT
|
|
```
|
|
|
|
The above rules are my output from `iptables-save` and `ip6tables-save`, and are fully compatible with the respective restore programs. Debian even has a nice package called `iptables-persistent` which will load these rules on boot if you stash them as `rules.v4` and `rules.v6` in `/etc/iptables`!
|
|
|
|
To better understand these rules, it helps to have the [Netfilter packet flow diagram][5] in front of you. There are some simple goals with these:
|
|
|
|
## IPv4 Filters
|
|
|
|
* Allow traffic coming from loopback or the inside interface
|
|
* Only allow traffic outside->inside if it pertains to an existing in->out connection
|
|
* **Secret sauce** - that MASQURADE line enables NAT, so my private addresses can hide behind the one public address that my ISP gives me
|
|
|
|
|
|
## IPv6 Filters
|
|
|
|
* Just drop everything for now unless it comes from the inside and is destined for the router itself
|
|
|
|
|
|
Of course, before I could have a fully-functional internet connection, I had to get DNS set up. And I guess a DHCP server would be nice to have before my leases all expire and everything drops its IP.
|
|
|
|
Luckily, there's a software package which is geared towards these very tasks: `dnsmasq`! Getting it running was as easy as running `apt-get install dnsmasq` and `service dnsmasq start`, which was enough to get DNS working. To get DHCP working, I created two config files in `/etc/dnsmasq.d/`:
|
|
|
|
#### dhcp.conf
|
|
```
|
|
# My DHCP configs
|
|
dhcp-range=10.0.0.110,10.0.0.250,12h
|
|
|
|
# options for DNS
|
|
dhcp-option=option:domain-search,home.nickpegg.com,nickpegg.com
|
|
|
|
# Static DHCP entries
|
|
dhcp-host=00:24:1D:7D:5F:C3,10.0.0.10,host1
|
|
dhcp-host=88:30:8A:22:2E:74,10.0.0.11,host2
|
|
dhcp-host=00:23:54:1A:16:2D,10.0.0.12,host3
|
|
```
|
|
|
|
#### interface.conf
|
|
```
|
|
# Only allow DNS/DHCP requests from the inside interface
|
|
interface=eth1
|
|
```
|
|
|
|
With all of that, I had a functioning IPv4 router and could do important things again, like idle on IRC and browse Reddit.
|
|
|
|
This is just the beginning though! You should go check out [part 2][6] of this series where I get 802.11 working.
|
|
|
|
|
|
|
|
[1]: http://en.wikipedia.org/wiki/Wrt54gl
|
|
[2]: http://mitxpc.com/proddetail.asp?prod=ER1UD2500DLM02
|
|
[3]: http://mitxpc.com/proddetail.asp?prod=INTWIFI7260AC
|
|
[4]: http://www.comcast.com/
|
|
[5]: http://upload.wikimedia.org/wikipedia/commons/3/37/Netfilter-packet-flow.svg
|
|
[6]: http://nickpegg.com/2014/8/building_my_own_home_router,_part_2_-_802.11.html
|