Network
The physical layout of the network is as follows:
flowchart LR
internet["Internet"]
upstairs_wifi["Upstairs WiFi AP"]
downstairs_wifi["Downstairs WiFi AP"]
front_camera["Front Camera"]
porch_camera["Porch Camera"]
wg_clients["Wireguard Clients"]
subgraph marks_office ["Mark's Office"]
subgraph subgraph_padding_marks_office [ ]
modem["Fibre ONT"]
router["Core Router"]
main_switch["Main Switch"]
poe_switch_upstairs["PoE Switch"]
rpi01/02
desktop01
end
end
subgraph garage ["Garage"]
subgraph subgraph_padding_garage [ ]
poe_switch_downstairs["PoE Switch"]
lab_switch["Lab Switch"]
lab01..06
nfs01
srv01
end
end
subgraph hallway ["Hallway"]
subgraph subgraph_padding_hallway [ ]
upstairs_wifi
downstairs_wifi
end
end
subgraph outside ["Outside"]
subgraph subgraph_padding_outside [ ]
porch_camera
front_camera
end
end
internet --> modem
modem --> router
router --> main_switch
main_switch --> rpi01/02
main_switch --> desktop01
main_switch --> poe_switch_upstairs
main_switch --> poe_switch_downstairs
main_switch --> lab_switch
poe_switch_upstairs --> upstairs_wifi
poe_switch_upstairs --> downstairs_wifi
poe_switch_upstairs --> porch_camera
lab_switch --> lab01..06
lab_switch --> nfs01
lab_switch --> srv01
poe_switch_downstairs --> front_camera
srv01 -.-> wg_clients
%% empty subgraphs are wrapped around some components to create more padding
classDef subgraph_padding fill: none, stroke: none
class subgraph_padding_marks_office subgraph_padding
class subgraph_padding_garage subgraph_padding
class subgraph_padding_hallway subgraph_padding
class subgraph_padding_outside subgraph_padding
classDef outer_group fill: none
class marks_office outer_group
class garage outer_group
class hallway outer_group
class outside outer_group
Elements of this layout are explained in more detail below, along with details of IP assignment and other tools in use.
Core Router
The core router is currently a MikroTik hEX S device. It can be accessed at http://10.0.0.1 when inside the LAN.
In the future it may be replaced with a DIY build.
Internet Connection
The fibre ONT (optical network terminal) translates light signals from the outside network to copper ethernet for the network inside the house.
The first device after the ONT is the router, which provides the actual connection to the Internet via PPP (Point-to-Point Protocol). PPP is how the router authenticates with our ISP (PlusNet at the time of writing) to access the network.
Router-Level Firewall
The MikroTik router provides the main firewall for the network. It is configured under IP > Firewall on the router and is kept simple:
Outgoing traffic is allowed.
LAN-to-LAN traffic is allowed.
Incoming traffic is mostly disallowed:
NAT (network address translation) is used to route incoming SSH, HTTP and HTTPS traffic to the relevant services.
All other incoming traffic is dropped.
Site Networking
The two Raspberry Pis provide “site network” services (i.e. network services consumed by the whole house, as compared to “host network” services that run on a single machine). All site-network services are managed via Ansible.
DHCP
Kea is a DHCP (Dynamic Host Configuration Protocol) server that runs in an primary/secondary pair across the servers. It is the service that hands out IP addresses to clients when they join the network, along with other information like the network gateway IP, DNS servers, and the network’s domain name (which is lan.tatsu.casa).
DHCP reservations are used to reserve a particular IP address and make sure it is always given to the same client when it connects (based on the client’s MAC address). This is how all hosts have their network details configured, making the DHCP server on the router the source of truth for who gets which IP.
When a client that does not have a corresonding reservation, it is given an address from a pool of unreserved addresses (see below).
DNS Resolution and Filtering
BIND9 is a recursive[1] DNS resolver that runs on both RPi servers. As well as recursively resolving requests for external domains, it also contains static entries for *.lan.tatsu.casa domains.
BIND9 isn’t designed as DNS filtering service (like Pi-Hole or Blocky), but it still provides that service for us. BIND9 is configured with a “Response Policy Zone” (RPZ) that blocks resolution of most advertising, tracking and malware domains using a domain list from this repo.
Wireguard
Wireguard (WG) is a lightweight VPN that is used to create secure tunnels between hosts on the Tatsu network and hosts that are not actually present on the LAN - like mobile phones and laptops. It allows us to treat non-local hosts as if they were on the home network.
WG creates a new network interfaces on each host, which is why all hosts using WG have a separate WG IP address as well as their “normal” one. It uses pre-arranged public/private keys that are shared between hosts to secure communication between them. WG configuration is managed via Ansible.
WiFi and OpenWRT
There are two WiFi access points (APs): one on the upstairs landing and one in the downstairs hallway. They are both TP-Link EAP225 v3 units and are powered directly from the network switch using power-over-ethernet (PoE).
The APs have been flashed with OpenWRT firmware, replacing the original TP-Link firmware that they came with. This was done for several reasons, but mainly because OpenWRT is ultimately just Linux, which allows the APs to be connected to via SSH, managed using Ansible (instead of TP-Link’s problematic Omada tooling), etc.
A note on WiFi security: TP-Link only supports up to WPA2 but OpenWRT has support for WPA3. The APs still in run WPA2 mode because not all devices support WPA3 yet, like the ESP boards. We could run WPA2/WPA3 split mode, but the hallway tablet only supports that if management frame protection is also enabled, which the ESPs don’t support.
Host Networking
Networking configuration for all hosts is managed via Ansible including things like the host firewalls, DNS servers and any floating IP addresses.
Host-Level Firewalls
Firewalls are implemented on all hosts using nftables (NF = net filter), which is a modern replacement for iptables. These firewalls are configured via Ansible and generally block all incoming traffic except for that which is expected and allowed.
Web Proxy
Incoming web traffic (HTTP and HTTPS) from the outside world is directed to Envoy by the router.
Envoy & Envoy Gateway
Envoy is a service running in the Kubernetes cluster that handles TLS termination and routes requests to the correct service (usually based on domain name). It is also responsible for integrating with Authelia (see below) to authenticate requests.
Envoy Gateway is a Kubernetes-native wrapper around Envoy that serves as a control plane for it. Envoy’s own config is quite complex and won’t do things like discovering other services in Kubernetes, so we configure Envoy Gateway with fairly simple primitives, then it configures Envoy for us.
Authelia
Authelia is another service running in the Kubernetes cluster that provides authentication for every request. Users are currently configured manually in config and require MFA.
Authelia allows complex access control rules to be configured, which are used to allow some services to be public (such as our personal sites) or to require only single-factor login for some services (such as for the Woodhouse dashboard, accessed by a service account).
Annex: IP Schema
Note
For the in-use configuration of IP addressing, see the DNS and DHCP config files in Ansible.
The Tatsu LAN is 10.0.0.0/16, i.e. ~65k addresses in the form 10.0.x.y. This large address space is split up into smaller subnets, listed below alongside other ranges used beyond the LAN. This is division allows us to apply some structure and control traffic between types of devices.
Subnet |
Range Size |
Use |
|---|---|---|
|
~500 |
Network infrastructure |
|
~500 |
Reserved for exposed and floating IPs - see below |
|
~500 |
Physical hosts |
|
~500 |
Unused |
|
~1k |
IoT |
|
~1k |
DHCP for unknown hosts |
|
~4k |
Unused |
|
~8k |
Unused |
|
~16k |
Unused |
|
~32k |
Unused |
|
~250 |
Wireguard |
10.0.0.0 / 23 - Network Infrastructure
10.0.0.1- Core router10.0.0.10- RPi 1 (ns01.lan.tatsu.casa)10.0.0.11- RPi 2 (ns02.lan.tatsu.casa)10.0.0.20- Upstairs WiFi AP10.0.0.21- Downstairs WiFi AP
10.0.2.0 / 23 - Exposed and Floating IPs
Note
Other than the external entrypoints, if these IPs have a domain it must sit under <something>.lan.tatsu.casa, indicating that they cannot be accessed when outside the LAN.
10.0.2.5- Gitea SSH (gitea.lan.tatsu.casa)10.0.2.6- Mosquitto MQTT (mqtt.lan.tatsu.casa)10.0.2.10- PXE boot server10.0.2.11- qBittorrent port-forward10.0.2.12-cluster01control plane (cluster01.lan.tatsu.casa)10.0.2.13- External entrypoint (see web proxy)
10.0.4.0 / 23 - Physical Hosts
10.0.4.1-desktop01- Mark’s desktop10.0.4.2-laptop01- Mark’s laptop10.0.4.5-srv0110.0.4.6-nfs0110.0.4.8-laptop02- Ana’s laptop10.0.4.9-lab0110.0.4.10-lab0210.0.4.11-lab0310.0.4.12-lab0410.0.4.13-lab0510.0.4.14-lab06
10.0.8.0 / 22 - IoT
10.0.8.1- Spare bedroom room Chromecast10.0.8.2- Kitchen Google Home10.0.8.3- Living room Google Home Mini10.0.8.4- Boiler switch (ESP01 + ESPHome)10.0.8.5- Garage dehumidifier (ESP01 + ESPHome)10.0.8.6- Hallway dashboard tablet10.0.8.7- Xmas tree lights (ESP32-based 3rd-party board + WLED)10.0.8.8- Downstairs robot vacuum cleaner (Dreame L10s Ultra + Valetudo)10.0.8.11- Driveway alarm box (ESP01 + ESPHome)10.0.8.12- Car tracker (ESP12F + ESPHome)10.0.8.14- Living room TV10.0.8.15- Driveway CCTV camera10.0.8.16- Porch CCTV camera10.0.8.17- Roaming CCTV camera 110.0.8.18- Roaming CCTV camera 2
10.0.12.0 / 22 - DHCP
DHCP range for devices without static IPs or DHCP reservations
10.1.0.0 / 24 - Wireguard
10.1.0.1-srv01(Wireguard “hub”)10.1.0.2-laptop01- Mark’s laptop10.1.0.3- Mark’s phone10.1.0.4- Ana’s phone