# Home network configuration # (2.5GbE clients) # | | # +----------+ +----------+ # | | | | | | (1GbE clients) # | | | | | +|-|-|-|-|+ # +---+----+ +-+-+-+-+-+ |5 4 3 2 1| # |upstream| | 1 2 3 4 | |TL-SG105 | # +--------+ | shinobu | +---------+ # +---------+ # # It consists of shinobu as a router (this configuration), # connected to a TP-LINK TL-SG105E “smart managed” (i.e., it can do VLANs) 5-port switch. # The upstream comes (for now) from a PŸUR “WLAN-Kabelbox” (Compal CH7467CE). # Sadly, I could not enable bridge mode on it, so the packets now go through (at least) four layers of NAT: # device → NAT on shinobu (→ NAT on plastic router → PŸUR CGNAT) → NAT on VPN # # Because the switch only supports GbE, # the two clients I currently have with support for 2.5GbE are connected # directly to the two remaining network interfaces on shinobu. # Once I have more devices with support for 2.5GbE # or I find a good deal on a matching switch, # I will change this. # # Wireless is configured by providing the whole hostapd configuration file as a secret. # Once nixpkgs PR 222536 is merged, I will migrate to using the NixOS module. # Thanks to Intel’s wisdom, it’s not possible to use 5GHz in AP mode. { config, lib, pkgs, ... }: let cfg = import ./common.nix; in { imports = [ ./dnsmasq.nix ./nft.nix ./wlan.nix ]; boot.kernel.sysctl = { "net.ipv4.conf.all.forwarding" = true; "net.ipv6.conf.all.forwarding" = true; }; environment.systemPackages = with pkgs; [ ethtool ]; sops.secrets.wg-upstream-private-key = { owner = config.users.users.systemd-network.name; sopsFile = ../../secrets.yaml; }; networking.useDHCP = false; systemd.network = { enable = true; # not all interfaces need to be up wait-online.extraArgs = [ "--any" ]; netdevs = { br-lan = { netdevConfig = { Name = "br-lan"; Kind = "bridge"; }; }; wg-upstream = { netdevConfig = { Kind = "wireguard"; Name = "wg-upstream"; }; wireguardConfig = { PrivateKeyFile = config.sops.secrets.wg-upstream-private-key.path; FirewallMark = 51820; }; wireguardPeers = lib.singleton { wireguardPeerConfig = with cfg.wg-upstream; { Endpoint = endpoint.full; PublicKey = publicKey; AllowedIPs = [ "0.0.0.0/0" "::0/0" ]; PersistentKeepalive = 25; }; }; }; }; networks = { wan = { name = "enp1s0"; DHCP = "ipv4"; networkConfig = { IPv6AcceptRA = "yes"; }; dhcpV4Config = { UseDNS = "no"; }; ipv6AcceptRAConfig = { # Only use RA DHCPv6Client = false; UseDNS = "no"; }; }; lan1 = { name = "enp2s0"; bridge = [ "br-lan" ]; }; lan2 = { name = "enp3s0"; bridge = [ "br-lan" ]; }; lan3 = { name = "enp4s0"; bridge = [ "br-lan" ]; }; br-lan = { name = "br-lan"; domains = [ cfg.domain ]; address = [ "10.80.1.1/24" "fd00:80:1::1/64" ]; }; wg-upstream = { name = "wg-upstream"; address = cfg.wg-upstream.addresses; routingPolicyRules = [ { routingPolicyRuleConfig = { Family = "both"; # default is only ipv4 FirewallMark = 51820; InvertRule = "yes"; Table = 51820; Priority = 10; #SuppressPrefixLength = 0; # can’t be used here (forwarding does not work with it) }; } # FIXME: those two shouldn’t be necessary # It should automatically detect those routes existing and prioritise them # LAN (v4) { routingPolicyRuleConfig = { To = "10.80.1.0/24"; Priority = 9; }; } # LAN (v6) { routingPolicyRuleConfig = { To = "fd00:80:1::/64"; Priority = 9; }; } # wg-home { routingPolicyRuleConfig = { To = "10.80.0.0/24"; Priority = 9; }; } # VPN bypass { routingPolicyRuleConfig = { Family = "both"; # welcome in the year 2023, where ipv4 is the default FirewallMark = cfg.vpnBypassFwMark; Priority = 9; }; } # plastic router { routingPolicyRuleConfig = { To = "192.168.0.0/24"; Priority = 9; }; } ]; routes = [ { routeConfig = { Gateway = "0.0.0.0"; # point-to-point connection Table = 51820; }; } { routeConfig = { Gateway = "::"; Table = 51820; }; } ]; }; }; }; services.resolved.enable = false; }