nixos-config/machines/shinobu/services/router/default.nix
Simon Bruder 959f7be3d0
Connect home network with IPv6 addresses
It adds a bit of latency (and is definitely not the best solution in
theory), but finally allows dropping IPv6 NAT and it works within the
constraits my home network has to live in.
2024-09-08 13:30:18 +02:00

146 lines
4 KiB
Nix
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# SPDX-FileCopyrightText: 2023-2024 Simon Bruder <simon@sbruder.de>
#
# SPDX-License-Identifier: AGPL-3.0-or-later
# Home network configuration
#
# +----------+ +------------+
# | | | | (clients)# (guests)
# | | | +--|--|--|--|-#+-|--|--|-|-unused|
# +---+----+ +-+-+-+-+-+ | 01 02 …… 12 # 13 …… 24 | 25 26 |
# |upstream| | 1 2 3 4 | | aruba Instant On 1830 | (SFP) |
# +--------+ | shinobu | +------------------------+-------+
# +---------+
#
# It consists of shinobu as a router (this configuration),
# connected to a aruba (HPE) Instant ON 1830 24-port 1GbE 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) three layers of NAT:
# device → NAT on shinobu → NAT on plastic router → PŸUR CGNAT
#
# Because of issues with the NICs operating at 2.5GbE,
# all clients are connected to the switch,
# even if they have a 2.5GbE NIC.
#
# 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 Intels wisdom, its not possible to use 5GHz in AP mode.
{ config, lib, pkgs, ... }:
let
cfg = pkgs.callPackage ./common.nix { };
in
{
imports = [
./dnsmasq.nix
./nft.nix
./tc.nix
];
sbruder.wireguard.he.enable = true;
boot.kernel.sysctl = {
"net.ipv4.conf.all.forwarding" = true;
"net.ipv6.conf.all.forwarding" = true;
};
environment.systemPackages = with pkgs; [
ethtool
];
networking.useDHCP = false;
systemd.network = {
enable = true;
# not all interfaces need to be up
wait-online.extraArgs = [ "--any" ];
netdevs = lib.mkMerge [
(lib.mapAttrs
(name: config: {
netdevConfig = {
Kind = "vlan";
Name = name;
};
vlanConfig = {
Id = config.id;
};
})
cfg.vlan)
(lib.mapAttrs'
(name: config: lib.nameValuePair "br-${name}" {
netdevConfig = {
Name = "br-${name}";
Kind = "bridge";
};
})
cfg.vlan)
];
networks = lib.mkMerge [
(lib.mapAttrs
(name: config: {
inherit name;
matchConfig = {
Type = "vlan";
};
bridge = [ "br-${name}" ];
})
cfg.vlan)
(lib.mapAttrs'
(name: config: lib.nameValuePair "br-${name}" {
name = "br-${name}";
domains = [ config.domain ];
address = lib.mapAttrsToList (family: familyConfig: familyConfig.gatewayCidr) config.subnet;
networkConfig = {
IPv6AcceptRA = false;
};
})
cfg.vlan)
{
wan = {
name = "enp1s0";
DHCP = "ipv4";
networkConfig = {
IPv6AcceptRA = "yes";
};
dhcpV4Config = {
UseDNS = "no";
};
ipv6AcceptRAConfig = {
# Only use RA
DHCPv6Client = false;
UseDNS = "no";
UseGateway = false; # should not be used by default for routing (wg-he takes precendence)
};
};
physical-lan = {
name = "enp2s0";
vlan = lib.attrNames cfg.vlan;
# no autoconfiguration needed, only tagged VLAN
networkConfig = {
LinkLocalAddressing = "no";
LLDP = "no";
EmitLLDP = "no";
IPv6AcceptRA = "no";
IPv6SendRA = "no";
};
};
lan2 = {
name = "enp3s0";
bridge = [ "br-lan" ];
};
lan3 = {
name = "enp4s0";
bridge = [ "br-lan" ];
};
# extended from common config
wg-he = {
address = lib.singleton "2001:470:73b9::1";
routes = lib.singleton {
routeConfig.Gateway = "::"; # on link
};
};
}
];
};
services.resolved.enable = false;
}