# Home network configuration # # +----------+ +---------------+ # | | | +-+-+---+ | # | +|-|-|-|-|+ | | # +---+----+ |5 4 3 2 1| | +--+--+ # |upstream| |TL-SG105 | | |fuuko| # +--------+ +---------+ | +-----+ # | # ( clients ) # # It consists of fuuko 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 from some plasic Huawei router/AP I don’t control. # # The VLANs are configured as follows: # Port | VLAN | ID(s) # 5 | untagged | 2 # 4 | tagged | 2,3 # 1-3 | untagged | 3 # # Wireless currently still is done by a separate GL.iNet GL-MT300N-V2 running OpenWRT, # but this will be changed to a Intel Wireless-AC 9260 in fuuko at a later date. { config, lib, ... }: let domain = "home.sbruder.de"; in { sops.secrets.wg-mullvad-private-key = { owner = config.users.users.systemd-network.name; sopsFile = ../secrets.yaml; }; boot.kernel.sysctl = { "net.ipv4.conf.all.forwarding" = true; }; networking = { # networkd handles this useDHCP = false; # networkd didn’t work that well for this nat = { enable = true; enableIPv6 = true; externalInterface = "wg-mullvad"; internalInterfaces = [ "lan" ]; internalIPv6s = [ "fd00:80:1::/64" ]; }; }; systemd.network = { enable = true; netdevs = { wan = { netdevConfig = { Kind = "vlan"; Name = "wan"; }; vlanConfig = { Id = 2; }; }; lan = { netdevConfig = { Kind = "vlan"; Name = "lan"; }; vlanConfig = { Id = 3; }; }; wg-mullvad = { netdevConfig = { Kind = "wireguard"; Name = "wg-mullvad"; }; wireguardConfig = { PrivateKeyFile = config.sops.secrets.wg-mullvad-private-key.path; FirewallMark = 51820; }; wireguardPeers = lib.singleton { wireguardPeerConfig = { Endpoint = "146.70.117.194:51820"; PublicKey = "ydXFN45/kROELJrF6id+uIrnS5DvTKSCkZDjfL9De2Q="; AllowedIPs = [ "0.0.0.0/0" "::0/0" ]; PersistentKeepalive = 25; }; }; }; }; networks = { physical = { name = "enp8s0"; vlan = [ "wan" "lan" ]; # no autoconfiguration needed, only tagged VLAN networkConfig = { LinkLocalAddressing = "no"; LLDP = "no"; EmitLLDP = "no"; IPv6AcceptRA = "no"; IPv6SendRA = "no"; }; }; wan = { name = "wan"; matchConfig = { Type = "vlan"; }; networkConfig = { # Upstream provides no IPv6 :( # If this is not set, it waits and fails systemd-networkd-wait-online LinkLocalAddressing = "no"; IPv6AcceptRA = "no"; }; DHCP = "ipv4"; dhcpV4Config = { UseDNS = "no"; }; }; lan = { name = "lan"; matchConfig = { Type = "vlan"; }; domains = [ domain ]; address = [ "10.80.1.1/24" "fd00:80:1::1/64" ]; }; wg-mullvad = { name = "wg-mullvad"; address = [ "10.66.208.88/32" "fc00:bbbb:bbbb:bb01::3:d057/128" ]; dns = [ "10.64.0.1" ]; routingPolicyRules = [ { routingPolicyRuleConfig = { 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 { routingPolicyRuleConfig = { To = "10.80.0.0/24"; Priority = 9; }; } { routingPolicyRuleConfig = { To = "10.80.1.0/24"; Priority = 9; }; } ]; routes = [ { routeConfig = { Gateway = "0.0.0.0"; # point-to-point connection Table = 51820; }; } { routeConfig = { Gateway = "::"; }; } ]; }; }; }; services.resolved.enable = false; services.dnsmasq = { enable = true; extraConfig = '' bogus-priv # do not forward revese lookups of internal addresses domain-needed # do not forward names without domain interface=lan # only respond to queries from lan no-hosts # do not resolve hosts from /etc/hosts no-resolv # only use explicitly configured resolvers cache-size=10000 domain=${domain} # Allow resolving the router interface-name=${config.networking.hostName}.${domain},lan interface-name=${config.networking.hostName},lan # DHCPv4 dhcp-range=10.80.1.20,10.80.1.150,12h dhcp-option=option:router,10.80.1.1 # SLAAC (for addresses) / DHCPv6 (for DNS) dhcp-range=fd00:80:1::,ra-stateless,ra-names dhcp-option=option6:dns-server,fd00:80:1::1 ''; servers = [ "10.64.0.1" # mullvad DNS, should be fastest overall #"9.9.9.9" # dns.quad9.net #"2620:fe::fe" ]; }; services.prometheus.exporters.dnsmasq = { enable = true; listenAddress = config.sbruder.wireguard.home.address; leasesPath = "/var/lib/dnsmasq/dnsmasq.leases"; }; networking.firewall.allowedUDPPorts = [ 53 67 ]; networking.firewall.allowedTCPPorts = [ 53 ]; }