about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFranck Cuny <franck@fcuny.net>2023-03-18 11:58:35 -0700
committerFranck Cuny <franck@fcuny.net>2023-04-03 17:53:02 -0700
commitc5a78751f96587bf4a3704143ac81598ee6c3e5b (patch)
treedaf41e9b05ade02118eaa08aabf9bac771e12c71
parentflake: fix URL for sendsms (diff)
downloadworld-c5a78751f96587bf4a3704143ac81598ee6c3e5b.tar.gz
hosts/carmel: reconfigure the host as a router
I'm not using it as a desktop, and the current router is getting old and
will likely fail in the near future. It's also a debian machine
configured manually, so let's reconfigure carmel as our new router.

There are three NICs in the host: 2 are 10Gb and one is 1Gb. The 1Gb
will be used as the upstream interface, and one of the 10Gb will be for
the LAN.

There are 2 VLANs to configure: one for IoT devices and one for guest.
Diffstat (limited to '')
-rw-r--r--.gitignore1
-rw-r--r--hosts/aptos/hardware.nix3
-rw-r--r--hosts/carmel/boot.nix22
-rw-r--r--hosts/carmel/default.nix13
-rw-r--r--hosts/carmel/hardware.nix41
-rw-r--r--hosts/carmel/home.nix42
-rw-r--r--hosts/carmel/networking.nix117
-rw-r--r--hosts/carmel/services.nix81
-rw-r--r--hosts/carmel/sound.nix1
-rw-r--r--hosts/tahoe/hardware.nix3
-rw-r--r--modules/services/avahi/default.nix9
-rw-r--r--modules/system/boot/default.nix1
-rw-r--r--modules/system/btrfs/default.nix15
-rw-r--r--nix/mkSystem.nix2
14 files changed, 233 insertions, 118 deletions
diff --git a/.gitignore b/.gitignore
index d9cf8e7..3eceeeb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,4 @@
 /tools/gerrit-hook/gerrit-hook
 /.pre-commit-config.yaml
 **/target/
+/*.qcow2
diff --git a/hosts/aptos/hardware.nix b/hosts/aptos/hardware.nix
index 0569203..990ab60 100644
--- a/hosts/aptos/hardware.nix
+++ b/hosts/aptos/hardware.nix
@@ -17,6 +17,7 @@
     options = [ "subvol=nixos" ];
   };
 
+  boot.initrd.luks.devices."system".allowDiscards = true;
   boot.initrd.luks.devices."system".device =
     "/dev/disk/by-uuid/c83a8db7-4215-4864-8a46-b8ca839d8c05";
 
@@ -46,5 +47,7 @@
   my.hardware.intel.enable = true;
   my.hardware.bluetooth.enable = true;
 
+  my.systems.btrfs.enable = true;
+
   powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
 }
diff --git a/hosts/carmel/boot.nix b/hosts/carmel/boot.nix
index 606215e..5beb31b 100644
--- a/hosts/carmel/boot.nix
+++ b/hosts/carmel/boot.nix
@@ -2,13 +2,21 @@
 
 {
   boot = {
-    # get an IP address on boot, so we can unlock the root disk remotely
-    kernelParams = [ "ip=dhcp" ];
-    initrd = {
-      # driver for the NIC, required in order to get an IP address
-      kernelModules = [ "igb" ];
+    loader = {
+      systemd-boot = {
+        enable = true;
+        # see https://www.man7.org/linux/man-pages/man5/loader.conf.5.html
+        consoleMode = "max";
+      };
+      efi.canTouchEfiVariables = true;
+      efi.efiSysMountPoint = "/boot/efi";
     };
-  };
 
-  my.system.boot = { initrd = { network.enable = true; }; };
+    kernel.sysctl = {
+      "net.ipv4.conf.all.forwarding" = true;
+      "net.ipv4.conf.default.forwarding" = true;
+      "net.core.default_qdisc" = "fq";
+      "net.ipv4.tcp_congestion_control" = "bbr";
+    };
+  };
 }
diff --git a/hosts/carmel/default.nix b/hosts/carmel/default.nix
index e9f0d64..83d6317 100644
--- a/hosts/carmel/default.nix
+++ b/hosts/carmel/default.nix
@@ -2,18 +2,7 @@
 
 {
   imports =
-    [ ./hardware.nix ./boot.nix ./sound.nix ./networking.nix ./services.nix ];
-
-  # Allow setting GTK configuration using home-manager
-  programs.dconf.enable = true;
-
-  # install and configure the fonts
-  my.systems.fonts.enable = true;
-
-  # install and configure sway
-  my.programs.sway.enable = true;
-
-  hardware.opengl.driSupport = true;
+    [ ./hardware.nix ./boot.nix ./networking.nix ./services.nix ];
 
   # This value determines the NixOS release from which the default
   # settings for stateful data, like file locations and database versions
diff --git a/hosts/carmel/hardware.nix b/hosts/carmel/hardware.nix
index aa86049..94ece14 100644
--- a/hosts/carmel/hardware.nix
+++ b/hosts/carmel/hardware.nix
@@ -11,36 +11,21 @@
   boot.initrd.kernelModules = [ ];
   boot.extraModulePackages = [ ];
 
-  fileSystems."/" = {
-    device = "/dev/disk/by-uuid/7d4e07d8-1104-4ab8-8ead-8ca28da2d344";
-    fsType = "btrfs";
-    options = [ "subvol=nixos" ];
-  };
+  fileSystems."/" =
+    {
+      device = "/dev/disk/by-uuid/88b61fbd-a74e-4458-bf2e-65721bb06497";
+      fsType = "ext4";
+    };
 
-  boot.initrd.luks.devices."system".device =
-    "/dev/disk/by-uuid/dd1b3673-ece0-49f8-bf71-8cc4e1a06634";
+  fileSystems."/boot/efi" =
+    {
+      device = "/dev/disk/by-uuid/779F-4030";
+      fsType = "vfat";
+    };
 
-  fileSystems."/home" = {
-    device = "/dev/disk/by-uuid/7d4e07d8-1104-4ab8-8ead-8ca28da2d344";
-    fsType = "btrfs";
-    options = [ "subvol=home" ];
-  };
-
-  fileSystems."/.snapshots" = {
-    device = "/dev/disk/by-uuid/7d4e07d8-1104-4ab8-8ead-8ca28da2d344";
-    fsType = "btrfs";
-    options = [ "subvol=snapshots" ];
-  };
-
-  fileSystems."/boot" = {
-    device = "/dev/disk/by-uuid/7430-1C58";
-    fsType = "vfat";
-  };
-
-  swapDevices =
-    [{ device = "/dev/disk/by-uuid/ebcb04f3-4227-4ec3-af52-bd775ef38027"; }];
+  swapDevices = [ ];
 
   my.hardware.amd.enable = true;
-  # high-resolution display
-  hardware.video.hidpi.enable = lib.mkDefault true;
+
+  powerManagement.cpuFreqGovernor = "schedutil";
 }
diff --git a/hosts/carmel/home.nix b/hosts/carmel/home.nix
index 4353abb..eb6c9ab 100644
--- a/hosts/carmel/home.nix
+++ b/hosts/carmel/home.nix
@@ -1,54 +1,14 @@
 { ... }: {
   my.home = {
-    my.home.wm.windowManager = "sway";
-
     # default packages I want on all hosts
     packages.enable = true;
 
-    # desktop
-    evince.enable = true;
-    gtk.enable = true;
-    pcmanfm.enable = true;
-
-    # multimedia
-    bluetooth.enable = true;
-    eog.enable = true;
-    mpv.enable = true;
-    scanner.enable = true;
-    sublime-music.enable = true;
-    vlc.enable = true;
-
-    # communication
-    element.enable = true;
-    mail.enable = true;
-
     # terminal
-    direnv.enable = true;
-    gcloud.enable = true;
-    shell.name = "fish";
+    shell.name = "zsh";
     ssh.enable = true;
-    terminal.program = "alacritty";
     tmux.enable = true;
-    xdg.enable = true;
 
     # software development
-    emacs.enable = true;
     git.enable = true;
-    go.enable = true;
-    python.enable = true;
-
-    # web
-    firefox.enable = true;
-    transmission-remote.enable = true;
-    yt-dlp.enable = true;
-
-    # security
-    gpg = {
-      enable = true;
-      pinentry = "gnome3";
-      defaultKey = "23348B57F01D4234B5CFBA0923208AC01EB6EEA1";
-    };
-    pass.enable = true;
-    seahorse.enable = true;
   };
 }
diff --git a/hosts/carmel/networking.nix b/hosts/carmel/networking.nix
index 8ad9d3e..22d4e42 100644
--- a/hosts/carmel/networking.nix
+++ b/hosts/carmel/networking.nix
@@ -1,35 +1,112 @@
 { lib, ... }:
+let
+  ethLink = (name:
+    (mac: {
+      matchConfig = {
+        Type = "ether";
+        MACAddress = mac;
+      };
+      linkConfig.Name = name;
+    }));
+
+  vlanNetdev = (name:
+    (id: {
+      netdevConfig = {
+        Name = name;
+        Kind = "vlan";
+      };
+      vlanConfig.Id = id;
+    }));
 
+  vlanNetwork = (name:
+    (id: {
+      matchConfig.Name = name;
+
+      # Embed ID directly in IPv4 address for clarity.
+      address = [ "192.168.${toString id}.1/24" ];
+    }));
+in
 {
-  # Use systemd-networkd for networking
   systemd.network = {
     enable = true;
-    networks = {
-      enp9s0 = {
-        matchConfig.Name = "enp9s0";
-        networkConfig = { DHCP = "yes"; };
-        extraConfig = ''
-          [DHCPv4]
-          UseDNS=yes
-          UseDomains=yes
-        '';
+
+    links."10-wan0" = ethLink "wan0" "a8:a1:59:43:95:36";
+    networks."10-wan0" = {
+      matchConfig.Name = "wan0";
+      networkConfig.DHCP = "ipv4";
+      dhcpV4Config = {
+        UseDNS = true;
+        UseDomains = true;
       };
     };
+
+    links."15-mgmt0" = ethLink "mgmt0" "a0:36:9f:fa:5d:6c";
+    networks."15-mgmt0" = {
+      matchConfig.Name = "mgmt0";
+      address = [ "192.168.0.1/24" ];
+      vlan = [ "iot" "guest" ];
+      networkConfig = {
+        DHCP = "no";
+        Domains = "home";
+      };
+    };
+
+    # unused interface
+    links."16-mgmt1" = ethLink "mgmt1" "a0:36:9f:fa:5d:6d";
+
+    # IoT VLAN.
+    netdevs."25-iot" = vlanNetdev "iot" 10;
+    networks."25-iot" = vlanNetwork "iot" 10;
+
+    # Guest VLAN.
+    netdevs."30-guest" = vlanNetdev "guest" 20;
+    networks."30-guest" = vlanNetwork "guest" 20;
+
+    # ignore these interfaces, as they are not used
+    wait-online.ignoredInterfaces = [ "mgmt1" "wlp8s0" ];
   };
 
-  services.nscd.enable = false;
-  system.nssModules = lib.mkForce [ ];
+  # don't use systemd-resolved on the router
+  services.resolved.enable = false;
+
+  networking.hostName = "carmel";
+  networking.useDHCP = false;
 
-  # Use systemd-resolved
-  services.resolved = {
+  networking.firewall = {
     enable = true;
-    dnssec = "false";
+    allowPing = true;
+    # If rejectPackets = true, refused packets are rejected rather than dropped (ignored). This
+    # means that an ICMP "port unreachable" error message is sent back to the client (or a TCP RST
+    # packet in case of an existing connection). Rejecting packets makes port scanning somewhat
+    # easier.
+    rejectPackets = false;
+
+    trustedInterfaces = [ "mgmt0" "iot" "guest" ];
+
+    logRefusedConnections = true;
+    logRefusedPackets = false;
+    logReversePathDrops = true;
+
+    # Do not perform reverse path filter test on a packet.
+    checkReversePath = false;
+
+    interfaces = {
+      "wan0" = {
+        allowedTCPPorts = [
+          22 # ssh
+          51413 # transmission
+        ];
+        allowedUDPPorts = [
+          35947 # wireguard
+          51413 # transmission
+        ];
+      };
+    };
   };
 
-  networking = {
-    hostName = "carmel";
-    useNetworkd = true;
-    useDHCP = false;
-    private-wireguard.enable = true;
+  networking.nat = {
+    enable = true;
+    externalInterface = "wan0";
+    internalInterfaces = [ "mgmt0" "guest" "iot" ];
   };
 }
diff --git a/hosts/carmel/services.nix b/hosts/carmel/services.nix
index e1432b2..63d749e 100644
--- a/hosts/carmel/services.nix
+++ b/hosts/carmel/services.nix
@@ -1,9 +1,82 @@
 { config, ... }: {
   my.services = {
-    # enable a few services related to the gnome desktop
-    gnome.enable = true;
+    metrics-exporter = { enable = true; };
+    avahi = {
+      enable = true;
+      withReflector = true;
+      interfaces = [ "mgmt0" "iot" ];
+    };
+  };
+
+  services.dnsmasq = {
+    enable = true;
+    resolveLocalQueries = true;
+    extraConfig = ''
+      log-dhcp
+
+      bind-interfaces
+
+      domain=home
+
+      dhcp-authoritative
+
+      interface=mgmt0
+      dhcp-range=set:mgmt0,192.168.0.100,192.168.0.199,30m
+      dhcp-option=tag:mgmt0,option:router,192.168.0.1
+
+      interface=iot
+      dhcp-range=set:iot,192.168.10.100,192.168.10.199,30m
+      dhcp-option=tag:iot,option:router,192.168.10.1
+
+      interface=guest
+      dhcp-range=set:guest,192.168.20.100,192.168.20.199,30m
+      dhcp-option=tag:guest,option:router,192.168.20.1
+
+      dhcp-option=option:dns-server,192.168.0.1,8.8.8.8
+
+      dhcp-host=b4:fb:e4:81:4f:0f,ap-media-room,192.168.0.30,infinite
+      dhcp-host=74:83:c2:12:67:2d,ap-living-room,192.168.0.31,infinite
+      dhcp-host=b4:fb:e4:81:52:6c,ap-office,192.168.0.32,infinite
+      dhcp-host=b4:fb:e4:b2:bd:b8,switch-garage,192.168.0.33,infinite
+      dhcp-host=fc:ec:da:78:d8:92,switch-media-room,192.168.0.34,infinite
+      dhcp-host=b4:fb:e4:8f:69:0e,switch-office,192.168.0.35,infinite
+      dhcp-host=d8:bb:c1:44:1c:d3,tahoe,192.168.0.40,infinite
+    '';
+  };
+
+  # DNS / DHCPv4 / DHCPv6
+  networking.firewall.allowedUDPPorts = [ 53 67 547 ];
+
+  services.nginx = {
+    enable = true;
+    recommendedProxySettings = true;
+    recommendedTlsSettings = true;
+    recommendedGzipSettings = true;
+    recommendedOptimisation = true;
+
+    virtualHosts."localhost" = {
+      listen = [
+        {
+          addr = "127.0.0.1";
+          port = 8080;
+        }
+      ];
+      locations."/" = { };
+    };
+
+    streamConfig = ''
+      server {
+        listen 443;
+        proxy_timeout 2s;
+        proxy_pass 192.168.0.40:443;
+      }
 
-    # we need avahi in order to use the printer/scanner
-    avahi.enable = true;
+      server {
+        listen 80 reuseport;
+        proxy_timeout 2s;
+        proxy_pass 192.168.0.40:80;
+      }
+    '';
   };
+  networking.firewall.allowedTCPPorts = [ 80 443 ];
 }
diff --git a/hosts/carmel/sound.nix b/hosts/carmel/sound.nix
deleted file mode 100644
index 947f9cd..0000000
--- a/hosts/carmel/sound.nix
+++ /dev/null
@@ -1 +0,0 @@
-{ ... }: { my.hardware.sound = { pipewire = { enable = true; }; }; }
diff --git a/hosts/tahoe/hardware.nix b/hosts/tahoe/hardware.nix
index 34c278b..dbfffff 100644
--- a/hosts/tahoe/hardware.nix
+++ b/hosts/tahoe/hardware.nix
@@ -17,6 +17,7 @@
     options = [ "subvol=nixos" ];
   };
 
+  boot.initrd.luks.devices."system".allowDiscards = true;
   boot.initrd.luks.devices."system".device =
     "/dev/disk/by-uuid/0d11e090-d88f-4313-8a41-8ef52eea0870";
 
@@ -61,6 +62,8 @@
 
   my.hardware.amd.enable = true;
 
+  my.systems.btrfs.enable = true;
+
   # high-resolution display
   hardware.video.hidpi.enable = lib.mkDefault true;
 
diff --git a/modules/services/avahi/default.nix b/modules/services/avahi/default.nix
index 8275f02..3a6eb58 100644
--- a/modules/services/avahi/default.nix
+++ b/modules/services/avahi/default.nix
@@ -4,6 +4,12 @@ in
 {
   options.my.services.avahi = with lib; {
     enable = mkEnableOption "avahi service";
+    withReflector = mkEnableOption "enable reflector";
+    interfaces = mkOption {
+      type = types.nullOr (types.listOf types.str);
+      default = null;
+      description = "List of network interfaces that should be used by the {command}`avahi-daemon`.";
+    };
   };
 
   config = lib.mkIf cfg.enable {
@@ -11,5 +17,8 @@ in
     # Important to resolve .local domains of printers, otherwise you get an error
     # like  "Impossible to connect to XXX.local: Name or service not known"
     services.avahi.nssmdns = true;
+
+    services.avahi.reflector = cfg.withReflector;
+    services.avahi.interfaces = cfg.interfaces;
   };
 }
diff --git a/modules/system/boot/default.nix b/modules/system/boot/default.nix
index cac1cec..5a5ac25 100644
--- a/modules/system/boot/default.nix
+++ b/modules/system/boot/default.nix
@@ -24,7 +24,6 @@ in
       tmpOnTmpfs = true;
 
       initrd = {
-        luks.devices."system".allowDiscards = true;
         network = lib.mkIf cfg.initrd.network.enable {
           enable = true;
           postCommands = ''
diff --git a/modules/system/btrfs/default.nix b/modules/system/btrfs/default.nix
index d569c78..3446b2c 100644
--- a/modules/system/btrfs/default.nix
+++ b/modules/system/btrfs/default.nix
@@ -1,5 +1,14 @@
-{ ... }:
-
+{ lib, config, ... }:
+let
+  cfg = config.my.systems.btrfs;
+in
 {
-  services.btrfs.autoScrub.enable = true;
+  options.my.systems.btrfs = with lib; {
+    enable = mkEnableOption "btrfs configuration";
+  };
+
+  config = lib.mkIf cfg.enable
+    {
+      services.btrfs.autoScrub.enable = !config.virtualisation.libvirtd.enable;
+    };
 }
diff --git a/nix/mkSystem.nix b/nix/mkSystem.nix
index 1cb450f..9b5fcd5 100644
--- a/nix/mkSystem.nix
+++ b/nix/mkSystem.nix
@@ -5,7 +5,7 @@ let
 in
 inputs.nixpkgs.lib.nixosSystem {
   inherit system;
-  specialArgs = { inherit inputs system hostname; };
+  specialArgs = { inherit inputs system hostname self; };
   modules = [
     "${self}/modules"
     "${self}/hosts/${hostname}"