From 94a64b792cfe328fa45e2cae7edcd8d098dba71e Mon Sep 17 00:00:00 2001 From: Raito Bezarius Date: Tue, 2 Jan 2024 00:31:55 +0100 Subject: [PATCH] router03: init --- machines/core-services-01/subZone.nix | 1 + machines/router03/_configuration.nix | 28 ++ machines/router03/_hardware-configuration.nix | 40 +++ machines/router03/router.nix | 335 ++++++++++++++++++ meta/nodes.nix | 13 + 5 files changed, 417 insertions(+) create mode 100644 machines/router03/_configuration.nix create mode 100644 machines/router03/_hardware-configuration.nix create mode 100644 machines/router03/router.nix diff --git a/machines/core-services-01/subZone.nix b/machines/core-services-01/subZone.nix index f1bc0c6..b2d5663 100644 --- a/machines/core-services-01/subZone.nix +++ b/machines/core-services-01/subZone.nix @@ -86,6 +86,7 @@ dualstack // { # Routers router01.A = [ "10.1.1.1" ]; router02.A = [ "10.1.1.1" ]; + router03.A = [ "10.1.1.120" ]; # Hypervisors pve01 = { diff --git a/machines/router03/_configuration.nix b/machines/router03/_configuration.nix new file mode 100644 index 0000000..fedc0a1 --- /dev/null +++ b/machines/router03/_configuration.nix @@ -0,0 +1,28 @@ +# Edit this configuration file to define what should be installed on +# your system. Help is available in the configuration.nix(5) man page +# and in the NixOS manual (accessible by running ‘nixos-help’). + +{ config, pkgs, ... }: + +{ + imports = + [ + ./router.nix + ]; + + # Use the systemd-boot EFI boot loader. + boot.loader.systemd-boot.enable = true; + boot.loader.efi.canTouchEfiVariables = true; + + # Set your time zone. + # time.timeZone = "Europe/Amsterdam"; + + networking.hostName = "router03"; + networking.domain = "internal.rz.ens.wtf"; + + services.getty.autologinUser = "root"; + services.openssh.enable = true; + + system.stateVersion = "24.05"; # Did you read the comment? +} + diff --git a/machines/router03/_hardware-configuration.nix b/machines/router03/_hardware-configuration.nix new file mode 100644 index 0000000..3ab0c99 --- /dev/null +++ b/machines/router03/_hardware-configuration.nix @@ -0,0 +1,40 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/profiles/qemu-guest.nix") + ]; + + boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ ]; + boot.extraModulePackages = [ ]; + boot.initrd.luks.devices.c-disk = { + device = "/dev/disk/by-uuid/9c57dd15-b6e4-4496-84ca-6ffe41a9dd42"; + + keyFile = "/dev/zero"; + keyFileSize = 1; + + fallbackToPassword = true; + }; + + + fileSystems."/" = + { device = "/dev/disk/by-uuid/a48770a7-87f0-4f95-9458-50f022d20472"; + fsType = "ext4"; + }; + + fileSystems."/boot" = + { device = "/dev/disk/by-uuid/1FD5-AB3E"; + fsType = "vfat"; + }; + + swapDevices = + [ { device = "/dev/disk/by-uuid/050ed1a8-60be-47e8-9f96-146362ea5e46"; } + ]; + + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/machines/router03/router.nix b/machines/router03/router.nix new file mode 100644 index 0000000..6cbb320 --- /dev/null +++ b/machines/router03/router.nix @@ -0,0 +1,335 @@ +{ config, pkgs, lib, ... }: +let + inherit (lib) mkOption types; + mkVLAN = name: id: { + netdevConfig = { + Kind = "vlan"; + Name = name; + }; + vlanConfig.Id = id; + }; + mkTunnel = kind: name: { local, remote, mtu ? 1480 }: { + netdevConfig = { + Kind = kind; + Name = name; + MTUBytes = toString mtu; + }; + tunnelConfig = { + Local = local; + Remote = remote; + }; + }; + vip = config.router.wan.vip; + rip = config.router.wan.rip; +in +{ + options.router = { + wan = { + vip = mkOption { + type = types.str; + description = "Highly-available virtual IP address of the router"; + }; + rip = mkOption { + type = types.str; + description = "Real IP address of the router"; + }; + }; + }; + config = { + router.wan.vip = "129.199.146.230"; + router.wan.rip = "129.199.146.231"; + networking.firewall.allowedUDPPorts = [ 25351 ]; + systemd.network.enable = true; + networking.dhcpcd.enable = false; + systemd.network.links."10-swp" = { + matchConfig.MACAddress = "92:E3:9C:CE:EF:14"; + linkConfig.Name = "swp"; + }; + systemd.network = { + config.routeTables = { + he = 100; + mwan = 110; + }; + netdevs = { + "05-admin-vpn" = { + netdevConfig = { + Kind = "wireguard"; + Name = "wgadmin"; + MTUBytes = "1420"; + }; + wireguardConfig = { + PrivateKeyFile = "/etc/secrets/wireguard/wgadmin"; + ListenPort = 25351; + }; + wireguardPeers = [ + { + wireguardPeerConfig = { + PublicKey = "obsUPq4Y1XGbl3yPUytPKkVcSP+eECpaQX+bV+ocwXg="; + AllowedIPs = [ "fd81:fb3a:50cc::100/128" ]; + }; + } + ]; + }; + "10-tun-mwan" = mkTunnel "gre" "gre-mwan" { + remote = "80.67.167.30"; + local = vip; + }; + "10-tun-he" = mkTunnel "sit" "sit-he" { + remote = "216.66.84.42"; + local = vip; + }; + # VLANs + # 401: uplink ENS + # 3500: intranet club réseau, proxy ARP et proxy arp pvlan / 10.1.1.1/22 + # 3510: mgmt club réseau (administration network) / fd81:fb3a:50cc::/64 + # 3605: MWAN V6 DMZ / 2a0e:e701:1120:b00c::1/64 + # 3606: MWAN V4 DMZ / 45.13.104.25/29 + # 3607: Club Réseau v6 DMZ (en ASN propre) + # 3608: DN42 DMZ + # 3609: HE V6 DMZ / 2001:470:1f13:187::1/64 + # 3610: Free V6 DMZ + # 3620: HE.net IPv6 /48 -> DHCP-PD /60 + # 3621: MWAN DMZ /48 PD delivery / 2a0e:e701:1120::1/48 + # 3622: Router VRRP link / $to_be_determined. + # "10-uplink-ens" = mkVLAN "uplink-ens" 401; dysfunctional? + "10-intranet-krz" = mkVLAN "intranet-krz" 3500; + "10-admin" = mkVLAN "admin" 3510; + "10-mwan-v6" = mkVLAN "mwan-v6" 3605; + "10-mwan-dual" = mkVLAN "mwan-dual" 3606; + "10-krz-v6" = mkVLAN "krz-v6" 3607; + "10-dn42-dmz" = mkVLAN "dn42-dmz" 3608; + "10-he-dmz" = mkVLAN "he-dmz" 3609; + "10-free-dmz" = mkVLAN "free-dmz" 3610; + "10-he-pd" = mkVLAN "he-v6-pd" 3620; + "10-mwan-pd" = mkVLAN "mwan-v6-pd" 3621; + "10-vrrp-router" = mkVLAN "vrrp-router" 3622; + }; + networks = { + "10-admin-vpn" = { + matchConfig.Name = "wgadmin"; + networkConfig = { + Description = "VPN d'administration système de l'infrastructure"; + Address = [ "fd81:fb3a:50cc::1/64" ]; + # Give access to the rest of the network. + IPForward = "ipv6"; + ConfigureWithoutCarrier = true; + }; + linkConfig.RequiredForOnline = "routable"; + }; + "15-admin-vlan" = { + matchConfig.Name = "admin"; + networkConfig = { + Description = "VLAN d'administration système de l'infrastructure"; + Address = [ "fd81:fb3a:50cc:1::1/48" ]; + # Give access to the rest of the network. + IPForward = "ipv6"; + IPv6ProxyNDP = true; + ConfigureWithoutCarrier = true; + }; + linkConfig.RequiredForOnline = "routable"; + }; + "20-tun-mwan" = { + matchConfig.Name = "gre-mwan"; + networkConfig = { + Description = "Tunnel de livraison GRE IPv4/IPv6 de MilkyWAN"; + Address = [ "10.1.1.50/30" "2a0b:cbc0:1::216/126" ]; + ConfigureWithoutCarrier = true; + }; + routes = [ + { + routeConfig = { + Gateway = "10.1.1.49"; + Table = "mwan"; + Scope = "global"; + # FIXME(raito): Has no effect? Upstream bug? + Source = "45.13.104.25/29"; + }; + } + { + routeConfig = { + Destination = "::/0"; + Gateway = "2a0b:cbc0:1::215"; + Table = "mwan"; + Scope = "global"; + Source = "2a0e:e701:1120::/48"; + }; + } + ]; + routingPolicyRules = [ + { + routingPolicyRuleConfig = { + From = "2a0e:e701:1120::/48"; + Table = "mwan"; + }; + } + { + routingPolicyRuleConfig = { + From = "45.13.104.25/29"; + Table = "mwan"; + }; + } + ]; + }; + "20-tun-he" = { + matchConfig.Name = "sit-he"; + networkConfig = { + Description = "HE.NET IPv6 Tunnel (owned by gdd)"; + Address = [ "2001:470:1f12:187::2/64" ]; + ConfigureWithoutCarrier = true; + }; + routes = [ + { + routeConfig = { + Destination = "::/0"; + Table = "he"; + Scope = "global"; + Source = "2001:470:1f13::/48"; + }; + } + ]; + routingPolicyRules = [ + { + routingPolicyRuleConfig = { + From = "2001:470:1f13::/48"; + Table = "he"; + }; + } + ]; + }; + "10-swp" = { + matchConfig.Name = "swp"; + networkConfig = { + Description = "VLAN-aware switch port"; + Address = [ "${rip}/24" ]; + Gateway = "129.199.146.254"; + LLDP = true; + # Only to the switch we are connected to directly, e.g. the hypervisor or the switch. + EmitLLDP = "nearest-bridge"; + # For VRRP. + KeepConfiguration = true; + }; + routingPolicyRules = [ + { + routingPolicyRuleConfig = { + From = "45.13.104.25/29"; + Type = "prohibit"; + }; + } + ]; + tunnel = [ + "gre-mwan" + "sit-he" + ]; + vlan = [ + # "intranet-krz" - we don't want to keep this. + "admin" + # FIXME: "mwan-v6" - do we want to keep this? + # We can achieve v6-only by enforcing MAC address isolation for IPv4. + "mwan-dual" + # FIXME: legacy-nat-zone. + # FIXME: "krz-v6" - not ready yet. + # FIXME: "dn42-dmz" - revive this if you want. + "he-dmz" + # FIXME: "free-dmz" - not ready yet, abandoned? + # FIXME: "he-v6-pd" - require rework + # FIXME: "mwan-v6-pd" - require rework + ]; + }; + # TODO: SIIT/NAT64/DNS64 component to avoid IPv4 dependency. + "20-mwan-dual" = { + matchConfig.Name = "mwan-dual"; + addresses = [ + { + addressConfig = { + Address = "2a0e:e701:1120:b00c::1/64"; + AddPrefixRoute = false; + }; + } + { + addressConfig = { + Address = "45.13.104.25/29"; + AddPrefixRoute = false; + }; + } + ]; + routes = [ + { + routeConfig = { + Destination = "2a0e:e701:1120:b00c::/64"; + Metric = 256; + Table = "mwan"; + }; + } + { + routeConfig = { + Destination = "45.13.104.25/29"; + Metric = 256; + Table = "mwan"; + }; + } + ]; + networkConfig = { + Description = "MilkyWAN dual stack public interface"; + DHCPServer = true; + IPv6SendRA = true; + IPForward = true; + ConfigureWithoutCarrier = true; + }; + }; + "20-he-dmz" = { + matchConfig.Name = "he-dmz"; + addresses = [ + { + addressConfig = { + Address = "2001:470:1f13:187::1/64"; + # This will add it in the wrong table. + # TODO: add to systemd a `Table` option here. + AddPrefixRoute = false; + }; + } + ]; + routes = [ + { + routeConfig = { + Destination = "2001:470:1f13:187::/64"; + Metric = 256; + Table = "he"; + }; + } + ]; + networkConfig = { + Description = "Hurricane Electrical's 187 /64 unfirewalled zone"; + IPv6SendRA = true; + ConfigureWithoutCarrier = true; + }; + }; + }; + }; + + # services.keepalived.enable = true; + # services.keepalived.vrrpInstances.wan = { + # interface = "swp"; + # state = "MASTER"; + # priority = 50; + # virtualIps = [{ addr = "129.199.146.230"; }]; + # virtualRouterId = 1; + # }; + + + # systemd.services."systemd-networkd".environment.SYSTEMD_LOG_LEVEL = "debug"; + environment.systemPackages = [ pkgs.tcpdump pkgs.wireguard-tools ]; + + # Zone based firewall + + # Flow accounting in PostgreSQL. + services.postgresql = { + enable = true; + ensureUsers = []; + }; + # services.ulogd = { + # enable = true; + # settings = { + # }; + # }; + }; +} diff --git a/meta/nodes.nix b/meta/nodes.nix index 4591c0c..9309fa7 100644 --- a/meta/nodes.nix +++ b/meta/nodes.nix @@ -48,4 +48,17 @@ builtins.mapAttrs mkNode { stateVersion = "21.05"; }; + + router03 = { + admins = [ + "gdd" + "hubrecht" + "raito" + "sinavir" + ]; + + deployment.targetHost = "router03.internal.rz.ens.wtf"; + + stateVersion = "24.05"; + }; }