This article is about setting up a Linux router based on Docker. Unlike many other tutorials on the web the goal is to host and run every component of the router in its own container. Docker’s isolation feature should make it a good fit to for example run a DHCP server separately.
Another interesting feature is that containers can be connected with different types of networks. This allows effective routing between the single components of the router. That makes it well suited for a router which can route packets to different networks based on their source (source-based routing). Being an expat in Australia, this is interesting to me in order to access certain internet pages as if I was at home to circumvent geo-blocked content.
An usual approach to work around this kind of restriction is to setup a virtual private network software on your devices. However, this comes with a few disadvantages. You need to setup and maintain the vpn software on every device. It does not work well with screen casting solutions like Google’s Chrome Cast or Amazon’s Fire Stick because the device you start the cast from and the displaying device need to be connected to the same vpn at the same time. Also, not every device supports connecting to a vpn after all.
After all, I decided to create my on solution for this problem and since I had a spare Raspberry PI 3 laying around I wanted to use it for the project.
Requirements (directly jumping into the solution space) for the first version of the router:
- The router provides a WLAN Access Point with the Raspberry PI 3 hardware.
- The router runs a DHCP server handing out IPs in the range from 10.1.1.100 to 10.1.1.200
- For every device on the LAN the user can configure whether its traffic is routed through a vpn or directly to the local internet provider
- The user can configure route targets for each device on an intranet web page
- The router runs a DNS cache (dnsmasq) specifically for each target network
- DNS leakage must not occur. Traffic routed through the vpn shall only run DNS queries through the vpn tunnel and the same for the local internet access
- When the VPN is down, traffic of devices configured to be routed through the vpn must not “leak” through the main WAN access but be rejected by proper ICMP packets
- When the routing target for a device is changed all connections currently established from that device must be disconnected
- This is an experiment so the router is part of an already existing LAN and existing router (which leads to double network address translation)
Qualities in regards to security
- The destination configuration page must be only accessible from the LAN
- There are no open ports on the WAN interface(s) (for now – usually SSH access from the internet is critical)
The following drawing shows an overview of the first version. Blue represents containers and green indicates networks – of type bridged or macvlan.
The responsibilities of the individual building blocks are:
- DHCPD: Runs a DHCP daemon which hands out IP Addresses on the 10.1.1.0/24 network
- HostAPD: Runs the HostAP daemon which opens a Wifi access point using the Raspberry Pi 3 hardware
- LAN: Bridges access to the LAN (via USB dongle)
- Router: Routes traffic between the LAN subnet and the local WAN access or OpenVPN WAN access networks. It offers gateway functionality on 10.1.1.10 which includes forwarding DNS queries coming in on port 53/UDP
- Local WAN Access: Provides masqueraded access to the local WAN. Runs DNSMasq which answers and caches DNS queries. Has two IPs: One in the 10.2.1.0 subnet and one as a DHCP client from the primary home router.
- OpenVPN WAN Access: Provides masqueraded access to an OpenVPN connection. Runs DNSMasq which answers and caches DNS queries. Also has two IPs.
- Primary Home Router: Access to the primary LAN which must provide a correctly configured DHCP server.
In the next part I will discuss the network setup for the router. The project can be found here: https://github.com/ThomasZeman/rpi3-router