This is the second blog post about my home network improvements series.
In the previous post, we have evaluated our options for a new router and the conclusion was to build the hardware from PC parts and to install OPNsense. However, given that our selected PC parts are a bit too recent, the embedded NIC (a i219V) inside the intel B360 chipset is not yet recognised by the underlying FreeBSD core.
Therefore, we will now see how to build a router from scratch based on Ubuntu 18.04 LTS. I will only configure it for IPv4 as currently my ISP provides only IPv4 connectivity. I am currently planning a series of 3 posts including that one:
- Router features list (this post)
- Creating a basic router (to be published)
- Extra services (to be published, could be splitted in more than one post)
Disclaimer: I am not a security engineer, although I am very familiar with many aspects of security and security analysis. I am also not a network engineer, although I am very knowledgeable in network protocols, network programming and network security. This article is an exercise for me to see how far I can build a router for SOHO purpose. I make no warranty that it works as intended, nor that I will maintain this article to keep it up to date with respect to network technology and threats. Use at your own risk.
Note: I am mostly going to avoid using any Ubuntu specific tools but of course some will be unavoidable (e.g. network IP address configuration). So this guide should apply to other Linux distributions. Of course there will be some adaptations to do, especially with respect to configuring the network interfaces as there are so many different tools to do that.
Definition of a basic Router (features list)
tl;dr; my router shall support routing, firewall, NAT, DHCP, DNS resolution, NTP, traffic analysis, alerting, IDS/IPS, VPN and QoS. Many of these features are optional or nice to have.
A basic SOHO (small office / home office) or home router is the gateway between your local network (LAN) and the internet (WAN). All traffic inward or towards the internet will flow through it, this is call routing and it is the main function of this device.
Secondly given the limitations of ISP in general which provides you with one public IP address (especially true in case of IPv4 only), the gateway shall support NAT or Network Address Translation. NAT allows one to have more than one device on its local LAN by using a set of IP addresses which are non-public (so that can only be used inside a home or entreprise network but not on the internet), each device is attributed one of these local IP addresses, the NAT gateway is performing a translation between those local IP and the public ones on the internet masking (“masquerading”) the local IP by using the one public IP provided by the ISP. This means that a NAT device is acting on behalf of an internal device forwarding any remote requests this device might do toward the internet and transferring back to this device any responses it receives.
Note: In some cases, ISP are using carrier-grade NAT, meaning your router is not attributed with a public IP address but given a private IP address. This is often the case when the ISP has more customers than it has available IPv4 addresses (a shortcoming which IPv6 should help solving). In such a scenario, you can still access the internet (browsing, social media, streaming, etc.) but you cannot publish services (e.g. some games might be impacted, or the performance with some games might be impacted, you cannot have your own cloud at home and use it remotely easily (e.g. using owncloud or the services of your NAS, etc.)).
Finally, the router shall provide basic protection (via firewalling or through NAT) and potentially DHCP (dynamic IP address attribution to your devices on your LAN).
Why not WiFi (especially because the selected hardware has a built-in 802.11ac WiFi adapter)? I do have already a very good WiFi AP from Ubiquiti. I’m very satisfied with the coverage and quality of this AP. And most importantly I could not put the router where the WiFi AP is located (i.-e. at the centre of our home), the router is way too big, visible, too many cables to be there, so the router is in our basement and it’s in a pretty bad place for having good WiFi cover. Finally, the iwlwifi driver does not support to be configured as an access point in 5GHz, only 2.4GHz, and it has some other limitations as well. So if WiFi is important, you should consider a dedicated WiFi AP (as I do), use a PCIe WiFi card with a better chipset/driver or select a different hardware/motherboard.
Your router is the gateway to the internet, so any devices on your network needs to go through your router in order to send or receive packets with remote machines outside your LAN.
This functionality will be handle by the Linux Kernel.
At least block all (non-requested) incoming traffic and allow all outgoing traffic for a start (this can then be improved).
This functionality will be handle by the Linux Kernel, we will use the user space nftables utility to configure it.
Network Address Translation is mandatory for IPv4 as most likely you only get one public IPv4 address from your ISP and you have many devices to connect. With IPv6 this might be optional depending on your ISP contract. But anyway NAT is a simple way to achieve a basic firewall as described above. We will use NAT.
This functionality will be handle by the Linux Kernel, we will use the user space nftables utility to configure it.
DHCP – Dynamic IP address attribution
Although this feature does not need to be provided by your router, a device on your network needs to provide this feature if you want to connect devices on your network without taking care of which fixed IP address you should attribute it. However, as your router is most likely always up and running, it’s a good idea to let it handle DHCP requests so you don’t need an extra device.
There are many user space applications which provide such service. In order to quickly get started we will use dnsmasq inside a Docker container as I have already such setup and it is pretty easy to configure, or we might give a try at Pi-hole (which also use dnsmasq AFAIK) also inside a Docker container as such a setup should be fairly easy. However, I would like to switch to ISC DHCP server running also inside a Docker container in the near future.
You obviously don’t want your user to type (and remember IP addresses) while they browse the web, so you want to provide domain name resolution. It is possible that your provider does this for you, if you are satisfied with it, then just configure the IP of your ISP’s DNS resolver in your DHCP server, and your devices will use it. But in any case you might want to have a caching resolver (which forward request to upstream DNS resolver or provide the response if it is still cached) which can improve performances if your ISP DNS resolvers are a bit slow, and you can tweak it to force use DNSSEC to improve your trust. Here I want to try a recursive DNS resolver (so it will ask the root DNS servers for who is in charged of the .eu domain, then it will request the .eu DNS servers who is in charged of the berthon.eu domain and finally request the berthon.eu DNS servers what’s the IP of berthon.eu). But I might reconsider my choice and install a caching and forwarding DNS resolver using DNS over TLS with the 18.104.22.168 and 22.214.171.124 remote DNS resolvers.
There are many user space applications which provide such service. In order to quickly get started we will use dnsmasq inside a Docker container as I have already such setup and it is pretty easy to configure, or we might give a try at Pi-hole (which also use dnsmasq AFAIK) also inside a Docker container as such a setup should be fairly easy. This setup will be limited to DNS forwarding and caching, it will support DNSSEC but not DNS over TLS (not without some extra configuration). However, I would like to switch to unbound running also inside a Docker container in the near future. It should be possible to keep Pi-hole and use unbound instead of dnsmasq. Unbound can support DNS over TLS as well as DNSSEC and RFC 7816 DNS Query Name Minimisation.
Extra services for your router
The next services are not necessary for the core operations of a router, but they can enhance the security and supervision of such system, or complement it with other features which can be useful on a local network.
The selected hardware should be able to support stable time (either from the HPET or TSC clocks), so it could act as a good quality stratum 2 or 3 NTP server from the LAN. But note that for good time sync reliability, 3 NTP servers at a minimum shall be used. The NTP Pool project is here to help you. Potentially, if you have a fixed IP and good internet connection you could also contribute to this project. Sadly, I do not have a static IP address from my ISP so I cannot join. Anyway I have already 2 Raspberry Pis which are configured to provide NTP on my LAN, together with the new router I would have the minimum recommended NTP servers, they could all act as “proxy” for all our internal devices with respect to time sync. So saving some NTP requests to upstream NTP servers.
There are many user space applications which provide such service. Most Linux distributions come with either NTPd from the NTP project or Chrony, so it would be fairly easy to configure them and activate them, we will show you how. But I like to use containers, and I will show you how to embed them inside a Docker container (see also my previous article on NTP inside a container).
Being able to see how much of the network resources are being used. This could be in real time and historical data. It should be possible to activate further/deeper analysis per domain name (how much iCloud traffic), per device (how much my phone is using), per service (how much HTTPS traffic), etc.
Here I’m not yet entirely sure what are all the possible applications which could cover this need. We will start by using a small monitoring agent which can at least see the total amount of traffic per network interface. We will use either collectd or telegraf, coupled with influxdb for persisting the data and grafana for displaying them. This is basic but a good start (it can be used for system monitoring as well). Of course we will use containers to deploy that. For further and deeper traffic analysis, I would consider netflow analysis tools, but that will require some research as there are many options, some can use influxdb and grafana, so our basic monitoring could be extended.
An alerting mechanism, so that other services could trigger it to send information, e.g. exceptional sustained peak of traffic, new unknown device, new service traffic, NTP is not synced, etc.
I also do not know yet what I will do here. Of course, one could use emails, or messages (through a mattermost or slack API, etc.), etc. It’s a topic where I still need to do some research and where I also need to see what will the other applications support (e.g. Grafana supports alerting, etc.)
Intrusion Detection and Prevention
An intrusion prevention system, or at least an IDS (intrusion detection system). This service should detect and potentially prevent some threats like malware activity (as more Internet of Things are invading our household, this is becoming a risk).
There are many user space applications which provide such service. We will give a try at Suricata which is also the solution used by OPNsense, so if I or you ever switched back to OPNsense I or you can more than likely reuse the Suricata rules we will be selecting.
VPN Client & Server
You could need to have a VPN server hosted on your router so that you can connect to your home LAN even when away from home. In addition, you might want to have for certain route a VPN connection (to connect to work or a small online cluster, for privacy w.r.t. to your ISP or country, etc.).
I am not currently planning on publishing such an article. They are many ways of doing it and there are many already good articles on this topic elsewhere on the internet.
QoS – Quality of Service
You might want to consider applying QoS for several reasons. Your ISP does a pretty bad job and you have quite some buffer bloats which can make web browsing seems slow despite big bandwidth. Or you might have many users at home, some streaming while some requiring low latency (e.g. games) and you want to provide a fair share of the resources to everyone. etc.
I will tackle this issue at the very end. I first want to build the router, test it and if I see problem; I want to fix them and QoS migth be a solution. But before solving a problem, I want to measure it before and after changing things.
A router is not limited to that. It can have many more features (VLAN, Radius, web proxy, etc.) but I will incrementally add those along the way as I need them.