
Unpopular Opinion: Laptops Make the Best Routers
Yeah, this one will need some explanation. But hear me out.
Many American households today have an old laptop lying around somewhere, collecting dust, doing a whole lot of nothing. It may or may not have a decent battery. It probably ran Windows 7 or Vista or something. And it's essentially garbage, but it hasn't been tossed yet.
Well, what if I told you that this ancient abacus could be used as a modern routing device?
If the laptop has a built in 1 gbps ethernet adapter, then you're all set. If it's only a 100 mbps, then you may be less excited, but it can still work. Or, you could get a USB plug that provides the ethernet connection.
You'll need either two network interfaces, so the built in one and a USB adapter, or you can use a single network interface and a VLAN enabled switch. I like this latter route.
Okay, here is what you do:
Laptop Setup
You could use Linux, FreeBSD, or OpenBSD. I used OpenBSD on my setup. You'll need to setup the physical network device to have two VLANs. One for the Internet, one for the internal network. In my case I have three VLANs, so there is a "home" side and a "dmz" type setup.
Here is a sample of the firewall config in the /etc/pf.conf file:
if_vlan_uplink = "vlan1"
if_vlan_user = "vlan101"
if_vlan_host = "vlan102"
net_vlan_user = "192.168.101.0/24"
net_vlan_user = "192.168.102.0/24"
### Tables
table <martians> { 0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 169.254.0.0/16 \
172.16.0.0/12 192.0.0.0/24 192.0.2.0/24 224.0.0.0/3 \
192.168.0.0/16 198.18.0.0/15 198.51.100.0/24 \
203.0.113.0/24 }
table <blocked_ips> persist file "/root/block_ips.txt"
### Traffic Normalization
# normalize incoming packets
match in all scrub (no-df random-id max-mss 1440)
# setup antispoofing
antispoof quick for { egress $if_vlan_user $if_vlan_host }
### NAT
# NAT traffic out egress
match out on egress inet from !(egress:network) to any nat-to (egress:0)
### Rules
# blocked packets get dropped
# drop is cheaper than reject
set block-policy drop
# block quick from blocked ips
block drop log quick from <blocked_ips>
# ignore loopback
set skip on lo0
# block incoming unroutable addresses
# note: if router is on an internal/private network, maybe dont do this
block in quick on egress from <martians> to any
# block any attempts to send to unroutable addresses
# note: if router is on an internal/private network, maybe dont do this
block return out quick on egress from any to <martians>
# block all in/out packets
block all
# allow IPv4 outbound
pass out quick inet
# allow internal IPv4 traffic
pass in on { $if_vlan_user $if_vlan_host } inet
# allow incoming ssh from internal
pass in on { $if_vlan_user $if_vlan_host } inet proto tcp from any to { $if_vlan_user $if_vlan_host } port ssh
Network Configs
You'll also need to enable IP forwarding.
Then the network config files:
/etc/hostname.vlan1
inet autoconf parent em0 vnetid 1 description "Uplink"
/etc/hostname.vlan101
inet 192.168.101.254 255.255.255.0 192.168.101.255 parent em0 vnetid 101 description "User VLAN"
/etc/hostname.vlan102
inet 192.168.102.254 255.255.255.0 192.168.102.255 parent em0 vnetid 102 description "Host VLAN"
DHCP
At this point you will need to setup a DHCP server (if you are needing to use that on your network), and serve that from the internal VLAN interface(s).
DNS
You might consider hosting DNS on this laptop as well, so you can block ad/tracking DNS names, or just cache queries on this system.
Switch Setup
The next step is to setup the VLANs on the switch. Mind, the laptop will only have one ethernet connection to the switch. So the switch will have something like port 1 with the Internet uplink. Port 2 to the laptop, trunking VLAN IDs 1, 101, and 102. Ports 3+ will then be divided into the associated VLANs (101/102).
Then plug it all in.
The Best Part
The best part is the /etc/hostname.* files, where you can set a "description." I find that very useful. You can see this description when using ifconfig
:
router0# ifconfig vlan1
vlan1: ...
...
description: Uplink
The user-defined description from the configuration file shows through to the use interface when checking the network statuses.
While I'm at it, I want to say the worst part: not having lsof
or sockstat
on OpenBSD is a bummer to me. Both of those tools are great for checking network connections. netstat
works, and it does have a traditional feel, but I'd rather use sockstat
.