about summary refs log tree commit diff
path: root/users/aspen/system/system
diff options
context:
space:
mode:
Diffstat (limited to 'users/aspen/system/system')
-rw-r--r--users/aspen/system/system/.skip-subtree0
-rw-r--r--users/aspen/system/system/configuration.nix11
-rw-r--r--users/aspen/system/system/default.nix48
-rw-r--r--users/aspen/system/system/iso.nix22
-rw-r--r--users/aspen/system/system/machines/bumblebee.nix23
-rw-r--r--users/aspen/system/system/machines/lusca.nix142
-rw-r--r--users/aspen/system/system/machines/mugwump.nix306
-rw-r--r--users/aspen/system/system/machines/ogopogo.nix107
-rw-r--r--users/aspen/system/system/machines/roswell.nix27
-rw-r--r--users/aspen/system/system/machines/yeren.nix132
-rw-r--r--users/aspen/system/system/modules/common.nix97
-rw-r--r--users/aspen/system/system/modules/desktop.nix19
-rw-r--r--users/aspen/system/system/modules/development.nix15
-rw-r--r--users/aspen/system/system/modules/fcitx.nix10
-rw-r--r--users/aspen/system/system/modules/fonts.nix13
-rw-r--r--users/aspen/system/system/modules/laptop.nix23
-rw-r--r--users/aspen/system/system/modules/reusable/README.org2
-rw-r--r--users/aspen/system/system/modules/rtlsdr.nix17
-rw-r--r--users/aspen/system/system/modules/sound.nix16
-rw-r--r--users/aspen/system/system/modules/tvl.nix35
-rw-r--r--users/aspen/system/system/modules/wireshark.nix9
-rw-r--r--users/aspen/system/system/modules/xserver.nix16
22 files changed, 1090 insertions, 0 deletions
diff --git a/users/aspen/system/system/.skip-subtree b/users/aspen/system/system/.skip-subtree
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/users/aspen/system/system/.skip-subtree
diff --git a/users/aspen/system/system/configuration.nix b/users/aspen/system/system/configuration.nix
new file mode 100644
index 0000000000..eae567015b
--- /dev/null
+++ b/users/aspen/system/system/configuration.nix
@@ -0,0 +1,11 @@
+{ config, pkgs, ... }:
+
+let machine = throw "Pick a machine from ./machines"; in
+{
+  imports =
+    [
+      /etc/nixos/hardware-configuration.nix
+      ./modules/common.nix
+      machine
+    ];
+}
diff --git a/users/aspen/system/system/default.nix b/users/aspen/system/system/default.nix
new file mode 100644
index 0000000000..07bc886c6c
--- /dev/null
+++ b/users/aspen/system/system/default.nix
@@ -0,0 +1,48 @@
+args @ { depot, pkgs, ... }:
+
+rec {
+  mugwump = import ./machines/mugwump.nix;
+
+  mugwumpSystem = (depot.ops.nixos.nixosFor mugwump).system;
+
+  roswell = import ./machines/roswell.nix;
+
+  roswellSystem = (depot.ops.nixos.nixosFor ({ ... }: {
+    imports = [
+      ./machines/roswell.nix
+      "${pkgs.home-manager.src}/nixos"
+    ];
+
+    # Use the same nixpkgs as everything else
+    home-manager.useGlobalPkgs = true;
+
+    home-manager.users.aspen = { config, lib, ... }: {
+      imports = [ ../home/machines/roswell.nix ];
+      lib.depot = depot;
+    };
+  })).system;
+
+  ogopogo = import ./machines/ogopogo.nix;
+
+  ogopogoSystem = (depot.ops.nixos.nixosFor ogopogo).system;
+
+  yeren = import ./machines/yeren.nix;
+
+  yerenSystem = (depot.ops.nixos.nixosFor yeren).system;
+
+  lusca = import ./machines/lusca.nix;
+
+  luscaSystem = (depot.ops.nixos.nixosFor lusca).system;
+
+  iso = import ./iso.nix args;
+
+  meta.ci.targets = [
+    "mugwumpSystem"
+    "roswellSystem"
+    "luscaSystem"
+    "ogopogoSystem"
+    "yerenSystem"
+
+    "iso"
+  ];
+}
diff --git a/users/aspen/system/system/iso.nix b/users/aspen/system/system/iso.nix
new file mode 100644
index 0000000000..ef5d3ed78b
--- /dev/null
+++ b/users/aspen/system/system/iso.nix
@@ -0,0 +1,22 @@
+{ depot, lib, pkgs, ... }:
+
+let
+  configuration = { ... }: {
+    imports = [
+      (pkgs.path + "/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix")
+      (pkgs.path + "/nixos/modules/installer/cd-dvd/channel.nix")
+    ];
+
+    networking.networkmanager.enable = true;
+    networking.useDHCP = false;
+    networking.firewall.enable = false;
+    networking.wireless.enable = lib.mkForce false;
+
+    # TODO(aspen): enabling this (in the minimal profile) fails the iso build,
+    # since gtk+3 needs to be built which fails due to cairo without xlibs
+    environment.noXlibs = false;
+  };
+in
+(depot.third_party.nixos {
+  inherit configuration;
+}).config.system.build.isoImage
diff --git a/users/aspen/system/system/machines/bumblebee.nix b/users/aspen/system/system/machines/bumblebee.nix
new file mode 100644
index 0000000000..8bb52f75f0
--- /dev/null
+++ b/users/aspen/system/system/machines/bumblebee.nix
@@ -0,0 +1,23 @@
+{ config, lib, pkgs, ... }:
+{
+  imports = [
+    ../modules/reusable/battery.nix
+  ];
+
+  networking.hostName = "bumblebee";
+
+  powerManagement = {
+    enable = true;
+    cpuFreqGovernor = "powersave";
+    powertop.enable = true;
+  };
+
+  # Hibernate on low battery
+  laptop.onLowBattery = {
+    enable = true;
+    action = "hibernate";
+    thresholdPercentage = 5;
+  };
+
+  services.xserver.xkb.options = "caps:swapescape";
+}
diff --git a/users/aspen/system/system/machines/lusca.nix b/users/aspen/system/system/machines/lusca.nix
new file mode 100644
index 0000000000..782d504aa9
--- /dev/null
+++ b/users/aspen/system/system/machines/lusca.nix
@@ -0,0 +1,142 @@
+{ depot, modulesPath, config, lib, pkgs, ... }:
+
+{
+  imports = [
+    (modulesPath + "/installer/scan/not-detected.nix")
+    ../modules/common.nix
+    ../modules/laptop.nix
+    ../modules/xserver.nix
+    ../modules/fonts.nix
+    ../modules/sound.nix
+    ../modules/tvl.nix
+    ../modules/development.nix
+  ];
+
+  networking.hostName = "lusca";
+
+  system.stateVersion = "24.05";
+
+  time.timeZone = "America/New_York";
+
+  services.avahi = {
+    enable = true;
+    nssmdns4 = true;
+  };
+
+  boot = {
+    initrd = {
+      availableKernelModules =
+        [ "nvme" "xhci_pci" "thunderbolt" "usb_storage" "sd_mod" ];
+      kernelModules = [ ];
+
+      luks.devices."cryptroot".device =
+        "/dev/disk/by-uuid/9e525746-5bca-4451-8710-a6f0e09b751c";
+    };
+
+    kernelModules = [ "kvm-amd" ];
+
+    kernelParams = [
+      "resume=LABEL=SWAP"
+      "resume_offset=795904" # sudo btrfs inspect-internal map-swapfile -r /swap/swapfile
+    ];
+
+    resumeDevice = "/dev/disk/by-uuid/4c099cee-8d42-49c1-916c-62a0b5effbd2";
+
+    kernel.sysctl = { "kernel.perf_event_paranoid" = -1; };
+  };
+
+  hardware.cpu.amd.updateMicrocode =
+    lib.mkDefault config.hardware.enableRedistributableFirmware;
+
+  fileSystems = {
+    "/" = {
+      device = "/dev/disk/by-uuid/4c099cee-8d42-49c1-916c-62a0b5effbd2";
+      fsType = "btrfs";
+      options = [ "subvol=root" ];
+    };
+
+    "/home" = {
+      device = "/dev/disk/by-uuid/4c099cee-8d42-49c1-916c-62a0b5effbd2";
+      fsType = "btrfs";
+      options = [ "subvol=home" ];
+    };
+
+    "/nix" = {
+      device = "/dev/disk/by-uuid/4c099cee-8d42-49c1-916c-62a0b5effbd2";
+      fsType = "btrfs";
+      options = [ "subvol=nix" ];
+    };
+
+    "/swap" = {
+      device = "/dev/disk/by-uuid/4c099cee-8d42-49c1-916c-62a0b5effbd2";
+      fsType = "btrfs";
+      options = [ "subvol=swap" ];
+    };
+
+    "/boot" = {
+      device = "/dev/disk/by-uuid/0E7D-3C3F";
+      fsType = "vfat";
+    };
+  };
+
+  swapDevices = [{ device = "/swap/swapfile"; }];
+
+  systemd.sleep.extraConfig = ''
+    HibernateDelaySec=30m
+    SuspendState=mem
+  '';
+
+  services.earlyoom = {
+    enable = true;
+    freeMemThreshold = 5;
+  };
+
+  services.tailscale.enable = true;
+
+  services.fwupd = {
+    enable = true;
+    extraRemotes = [ "lvfs-testing" ];
+  };
+
+  services.tlp.enable = lib.mkForce false;
+  services.power-profiles-daemon.enable = true;
+
+  services.thermald.enable = true;
+
+  services.fprintd.enable = true;
+  security.pam.services = {
+    login.fprintAuth = true;
+    sudo.fprintAuth = true;
+    i3lock.fprintAuth = true;
+    i3lock-color.fprintAuth = true;
+    lightdm.fprintAuth = true;
+    lightdm-greeter.fprintAuth = true;
+  };
+
+  security.polkit.extraConfig = ''
+    polkit.addRule(function(action, subject) {
+      if (action.id.indexOf("net.reactivated.fprint.") == 0 || action.id.indexOf("net.reactivated.Fprint.") == 0) {
+          polkit.log("action=" + action);
+          polkit.log("subject=" + subject);
+          return polkit.Result.YES;
+      }
+    });
+  '';
+
+  services.udev.extraRules = ''
+    # Ethernet expansion card support
+    ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="0bda", ATTR{idProduct}=="8156", ATTR{power/autosuspend}="20"
+  '';
+
+  hardware.sensor.iio.enable = true;
+
+  hardware.opengl.driSupport32Bit = true;
+
+  # TPM
+  security.tpm2 = {
+    enable = true;
+    pkcs11.enable = true;
+    tctiEnvironment.enable = true;
+  };
+  users.users.aspen.extraGroups = [ "tss" ];
+}
diff --git a/users/aspen/system/system/machines/mugwump.nix b/users/aspen/system/system/machines/mugwump.nix
new file mode 100644
index 0000000000..4cfa117134
--- /dev/null
+++ b/users/aspen/system/system/machines/mugwump.nix
@@ -0,0 +1,306 @@
+{ config, lib, pkgs, modulesPath, depot, ... }:
+
+with lib;
+
+{
+  imports = [
+    ../modules/common.nix
+    (modulesPath + "/installer/scan/not-detected.nix")
+    (depot.path.origSrc + "/ops/modules/prometheus-fail2ban-exporter.nix")
+    (depot.path.origSrc + "/users/aspen/xanthous/server/module.nix")
+    (depot.third_party.agenix.src + "/modules/age.nix")
+    depot.third_party.ddclient.module
+  ];
+
+  networking.hostName = "mugwump";
+
+  system.stateVersion = "22.05";
+
+  boot = {
+    loader.systemd-boot.enable = true;
+
+    kernelModules = [ "kvm-intel" ];
+    extraModulePackages = [ ];
+
+    initrd = {
+      availableKernelModules = [ "xhci_pci" "ehci_pci" "ahci" "usb_storage" "usbhid" "sd_mod" ];
+      kernelModules = [
+        "uas"
+        "usbcore"
+        "usb_storage"
+        "vfat"
+        "nls_cp437"
+        "nls_iso8859_1"
+      ];
+
+      postDeviceCommands = pkgs.lib.mkBefore ''
+        mkdir -m 0755 -p /key
+        sleep 2
+        mount -n -t vfat -o ro `findfs UUID=9048-A9D5` /key
+      '';
+
+      luks.devices."cryptroot" = {
+        device = "/dev/disk/by-uuid/803a9028-339c-4617-a213-4fe138161f6d";
+        keyFile = "/key/keyfile";
+        preLVM = false;
+      };
+    };
+  };
+
+  fileSystems = {
+    "/" = {
+      device = "/dev/mapper/cryptroot";
+      fsType = "btrfs";
+    };
+    "/boot" = {
+      device = "/dev/disk/by-uuid/7D74-0E4B";
+      fsType = "vfat";
+    };
+  };
+
+  networking.interfaces = {
+    enp0s25.useDHCP = false;
+    wlp2s0.useDHCP = false;
+  };
+
+  networking.firewall.enable = true;
+  networking.firewall.allowedTCPPorts = [ 22 80 443 ];
+
+  security.sudo.extraRules = [{
+    groups = [ "wheel" ];
+    commands = [{ command = "ALL"; options = [ "NOPASSWD" ]; }];
+  }];
+
+  nix.gc.dates = "monthly";
+
+  users.users.aspen.openssh.authorizedKeys.keys = [
+    depot.users.aspen.keys.whitby
+  ];
+
+  age.secrets =
+    let
+      secret = name: depot.users.aspen.secrets."${name}.age";
+    in
+    {
+      cloudflare.file = secret "cloudflare";
+      ddclient-password.file = secret "ddclient-password";
+
+      buildkite-ssh-key = {
+        file = secret "buildkite-ssh-key";
+        group = "keys";
+        mode = "0440";
+      };
+
+      buildkite-token = {
+        file = secret "buildkite-token";
+        group = "keys";
+        mode = "0440";
+      };
+
+      windtunnel-bot-github-token = {
+        file = secret "windtunnel-bot-github-token";
+        group = "keys";
+        mode = "0440";
+      };
+    };
+
+  services.fail2ban = {
+    enable = true;
+    ignoreIP = [
+      "172.16.0.0/16"
+    ];
+  };
+
+  services.openssh = {
+    allowSFTP = false;
+    settings = {
+      PasswordAuthentication = false;
+      PermitRootLogin = "no";
+    };
+  };
+
+  services.grafana = {
+    enable = true;
+    dataDir = "/var/lib/grafana";
+
+    settings = {
+      server = {
+        http_port = 3000;
+        root_url = "https://metrics.gws.fyi";
+        domain = "metrics.gws.fyi";
+      };
+      analytics.reporting_enabled = false;
+    };
+
+    provision = {
+      enable = true;
+      datasources.settings.datasources = [{
+        name = "Prometheus";
+        type = "prometheus";
+        url = "http://localhost:9090";
+      }];
+    };
+  };
+
+  security.acme.defaults.email = "root@gws.fyi";
+  security.acme.acceptTerms = true;
+
+  services.nginx = {
+    enable = true;
+    statusPage = true;
+    recommendedGzipSettings = true;
+    recommendedOptimisation = true;
+    recommendedTlsSettings = true;
+    recommendedProxySettings = true;
+
+    virtualHosts = {
+      "metrics.gws.fyi" = {
+        enableACME = true;
+        forceSSL = true;
+        locations."/" = {
+          proxyPass = "http://localhost:${toString config.services.grafana.settings.server.http_port}";
+        };
+      };
+    };
+  };
+
+  services.deprecated-ddclient = {
+    package = depot.third_party.ddclient;
+    enable = true;
+    domains = [ "home.gws.fyi" ];
+    interval = "1d";
+    zone = "gws.fyi";
+    protocol = "cloudflare";
+    username = "root@gws.fyi";
+    passwordFile = config.age.secretsDir + "/ddclient-password";
+    quiet = true;
+  };
+
+  security.acme.certs."metrics.gws.fyi" = {
+    dnsProvider = "cloudflare";
+    credentialsFile = config.age.secretsDir + "/cloudflare";
+    webroot = mkForce null;
+  };
+
+  services.prometheus = {
+    enable = true;
+    exporters = {
+      node = {
+        enable = true;
+        openFirewall = false;
+
+        enabledCollectors = [
+          "processes"
+          "systemd"
+          "tcpstat"
+          "wifi"
+        ];
+      };
+
+      nginx = {
+        enable = true;
+        openFirewall = true;
+        sslVerify = false;
+        constLabels = [ "host=mugwump" ];
+      };
+
+      blackbox = {
+        enable = true;
+        openFirewall = true;
+        configFile = pkgs.writeText "blackbox-exporter.yaml" (builtins.toJSON {
+          modules = {
+            https_2xx = {
+              prober = "http";
+              http = {
+                method = "GET";
+                fail_if_ssl = false;
+                fail_if_not_ssl = true;
+                preferred_ip_protocol = "ip4";
+              };
+            };
+          };
+        });
+      };
+    };
+
+    scrapeConfigs = [
+      {
+        job_name = "node";
+        scrape_interval = "5s";
+        static_configs = [{
+          targets = [ "localhost:${toString config.services.prometheus.exporters.node.port}" ];
+        }];
+      }
+      {
+        job_name = "nginx";
+        scrape_interval = "5s";
+        static_configs = [{
+          targets = [ "localhost:${toString config.services.prometheus.exporters.nginx.port}" ];
+        }];
+      }
+      {
+        job_name = "xanthous_server";
+        scrape_interval = "1s";
+        static_configs = [{
+          targets = [ "localhost:${toString config.services.xanthous-server.metricsPort}" ];
+        }];
+      }
+      {
+        job_name = "blackbox";
+        metrics_path = "/probe";
+        params.module = [ "https_2xx" ];
+        scrape_interval = "5s";
+        static_configs = [{
+          targets = [
+            "https://gws.fyi"
+            "https://windtunnel.ci"
+            "https://app.windtunnel.ci"
+            "https://metrics.gws.fyi"
+          ];
+        }];
+        relabel_configs = [{
+          source_labels = [ "__address__" ];
+          target_label = "__param_target";
+        }
+          {
+            source_labels = [ "__param_target" ];
+            target_label = "instance";
+          }
+          {
+            target_label = "__address__";
+            replacement = "localhost:${toString config.services.prometheus.exporters.blackbox.port}";
+          }];
+      }
+    ];
+  };
+
+  services.xanthous-server.enable = true;
+
+  virtualisation.docker = {
+    enable = true;
+    storageDriver = "btrfs";
+  };
+
+  services.buildkite-agents = listToAttrs (map
+    (n: rec {
+      name = "mugwump-${toString n}";
+      value = {
+        inherit name;
+        enable = true;
+        tokenPath = config.age.secretsDir + "/buildkite-token";
+        privateSshKeyPath = config.age.secretsDir + "/buildkite-ssh-key";
+        runtimePackages = with pkgs; [
+          docker
+          nix
+          gnutar
+          gzip
+        ];
+      };
+    })
+    (range 1 1));
+
+  users.users."buildkite-agent-mugwump-1" = {
+    isSystemUser = true;
+    extraGroups = [ "docker" "keys" ];
+  };
+}
diff --git a/users/aspen/system/system/machines/ogopogo.nix b/users/aspen/system/system/machines/ogopogo.nix
new file mode 100644
index 0000000000..e80a0906db
--- /dev/null
+++ b/users/aspen/system/system/machines/ogopogo.nix
@@ -0,0 +1,107 @@
+{ depot, modulesPath, config, lib, pkgs, ... }:
+
+{
+  imports = [
+    (modulesPath + "/installer/scan/not-detected.nix")
+    (depot.third_party.agenix.src + "/modules/age.nix")
+    ../modules/common.nix
+    ../modules/xserver.nix
+    ../modules/fonts.nix
+    ../modules/sound.nix
+    ../modules/tvl.nix
+    ../modules/development.nix
+    ../modules/wireshark.nix
+  ];
+
+  networking.hostName = "ogopogo";
+
+  system.stateVersion = "22.11";
+
+  boot = {
+    initrd = {
+      availableKernelModules = [ "nvme" "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];
+      kernelModules = [ ];
+    };
+
+    kernelModules = [ "kvm-amd" ];
+    blacklistedKernelModules = [ ];
+    extraModulePackages = [ ];
+
+    kernel.sysctl = {
+      "kernel.perf_event_paranoid" = -1;
+    };
+  };
+
+  fileSystems = {
+    "/" = {
+      device = "/dev/disk/by-uuid/d67506cf-7039-484d-97c0-00321a7858dc";
+      fsType = "ext4";
+    };
+
+    "/boot" = {
+      device = "/dev/disk/by-uuid/AE73-03A3";
+      fsType = "vfat";
+    };
+
+    "/data" = {
+      device = "/dev/disk/by-uuid/03e0f4dc-9778-42e2-a59e-45522610e509";
+      fsType = "ext4";
+    };
+  };
+
+  swapDevices = [{
+    device = "/dev/disk/by-uuid/8bdae7c8-5160-491f-8cd0-4f0a79acadf9";
+  }];
+
+  services.earlyoom = {
+    enable = true;
+    freeMemThreshold = 5;
+  };
+
+  hardware.enableAllFirmware = true;
+
+  hardware.pulseaudio.extraConfig = ''
+    load-module module-remap-source source_name=KompleteAudio6_1 source_properties=device.description=KompleteAudio6Input1 master=alsa_input.usb-Native_Instruments_Komplete_Audio_6_458E0FFD-00.multichannel-input remix=no channels=1 master_channel_map=front-left channel_map=mono
+    load-module module-remap-source source_name=KompleteAudio6_2 source_properties=device.description=KompleteAudio6Input2 master=alsa_input.usb-Native_Instruments_Komplete_Audio_6_458E0FFD-00.multichannel-input remix=no channels=1 master_channel_map=front-right channel_map=mono
+    load-module module-remap-sink sink_name=KompleteAudio6_12 sink_properties=device.description=KompleteAudio6_12 remix=no master=alsa_output.usb-Native_Instruments_Komplete_Audio_6_458E0FFD-00.analog-surround-21 channels=2 master_channel_map=front-left,front-right channel_map=front-left,front-right
+  '';
+
+  services.fwupd.enable = true;
+
+  services.tailscale.enable = true;
+
+  hardware.keyboard.zsa.enable = true;
+
+  # Nvidia
+  services.xserver = {
+    videoDrivers = [ "nvidia" ];
+    dpi = 100;
+  };
+  hardware.opengl.enable = true;
+  services.picom = {
+    enable = true;
+    vSync = true;
+  };
+  hardware.opengl.driSupport32Bit = true;
+
+  services.postgresql = {
+    enable = true;
+    enableTCPIP = true;
+    authentication = "host all all 0.0.0.0/0 md5";
+    dataDir = "/data/postgresql";
+    package = pkgs.postgresql_15;
+    port = 5431;
+    settings = {
+      wal_level = "logical";
+    };
+  };
+
+  nix.settings.substituters = [ "ssh://grfn@172.16.0.5" ];
+  nix.settings.trusted-substituters = [ "ssh://grfn@172.16.0.5" ];
+  programs.ssh.knownHosts.mugwump = {
+    extraHostNames = [ "172.16.0.5" ];
+    publicKeyFile = pkgs.writeText "mugwump.pub" ''
+      ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFE2fxPgWO+zeQoLBTgsgxP7Vg7QNHlrQ+Rb3fHFTomB
+    '';
+  };
+}
diff --git a/users/aspen/system/system/machines/roswell.nix b/users/aspen/system/system/machines/roswell.nix
new file mode 100644
index 0000000000..da62eec93e
--- /dev/null
+++ b/users/aspen/system/system/machines/roswell.nix
@@ -0,0 +1,27 @@
+{ depot, config, lib, pkgs, modulesPath, ... }:
+
+{
+  imports = [
+    ../modules/common.nix
+    ../modules/development.nix
+    "${modulesPath}/installer/scan/not-detected.nix"
+    "${modulesPath}/virtualisation/amazon-image.nix"
+  ];
+
+  system.stateVersion = "22.05";
+
+  networking.hostName = "roswell";
+
+  boot.loader.systemd-boot.enable = lib.mkForce false;
+  boot.loader.efi.canTouchEfiVariables = lib.mkForce false;
+
+  services.openssh.settings.PasswordAuthentication = false;
+
+  services.tailscale.enable = true;
+
+  security.sudo.wheelNeedsPassword = false;
+
+  environment.systemPackages = with pkgs; [
+    cloud-utils
+  ];
+}
diff --git a/users/aspen/system/system/machines/yeren.nix b/users/aspen/system/system/machines/yeren.nix
new file mode 100644
index 0000000000..653f0cd44c
--- /dev/null
+++ b/users/aspen/system/system/machines/yeren.nix
@@ -0,0 +1,132 @@
+{ depot, modulesPath, config, lib, pkgs, ... }:
+
+{
+  imports = [
+    (modulesPath + "/installer/scan/not-detected.nix")
+    ../modules/common.nix
+    ../modules/laptop.nix
+    ../modules/xserver.nix
+    ../modules/fonts.nix
+    ../modules/sound.nix
+    ../modules/tvl.nix
+    ../modules/development.nix
+  ];
+
+  networking.hostName = "yeren";
+
+  system.stateVersion = "21.03";
+
+  time.timeZone = "America/New_York";
+
+  services.avahi = {
+    enable = true;
+    nssmdns4 = true;
+  };
+
+  boot = {
+    initrd = {
+      availableKernelModules = [ "xhci_pci" "thunderbolt" "nvme" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ];
+      kernelModules = [ ];
+
+      luks.devices = {
+        "cryptroot".device = "/dev/disk/by-uuid/dcfbc22d-e0d2-411b-8dd3-96704d3aae2e";
+      };
+    };
+
+    kernelModules = [ "kvm-intel" ];
+    blacklistedKernelModules = [ "psmouse" ];
+    extraModulePackages = [
+      config.boot.kernelPackages.digimend
+    ];
+    kernelParams = [
+      "i915.preliminary_hw_support=1"
+      "pcie_aspm=force"
+    ];
+
+    # https://bbs.archlinux.org/viewtopic.php?pid=1933643#p1933643
+    extraModprobeConfig = ''
+      options snd-intel-dspcfg dsp_driver=1
+    '';
+
+    kernel.sysctl = {
+      "kernel.perf_event_paranoid" = -1;
+    };
+  };
+
+  fileSystems = {
+    "/" = {
+      device = "/dev/mapper/cryptroot";
+      fsType = "btrfs";
+    };
+
+    "/boot" = {
+      device = "/dev/disk/by-uuid/53A9-248B";
+      fsType = "vfat";
+    };
+  };
+
+  swapDevices = [{
+    device = "/dev/disk/by-uuid/b627cb0e-0451-4f25-94d0-6497e01f0da4";
+  }];
+
+  services.earlyoom = {
+    enable = true;
+    freeMemThreshold = 5;
+  };
+
+  services.xserver = {
+    exportConfiguration = true;
+    extraConfig = ''
+      Section "Device"
+        Identifier  "Intel Graphics"
+        Driver      "intel"
+        Option      "TripleBuffer" "true"
+        Option      "TearFree"     "true"
+        Option      "DRI"          "true"
+        Option      "AccelMethod"  "sna"
+      EndSection
+    '';
+  };
+
+  hardware.firmware = with pkgs; [
+    alsa-firmware
+    sof-firmware
+  ];
+
+  hardware.opengl.extraPackages = with pkgs; [
+    vaapiIntel
+    vaapiVdpau
+    libvdpau-va-gl
+    intel-media-driver
+  ];
+
+  # Disabled for now until libfprint-tod can get a version bump
+  # services.fprintd = {
+  #   enable = true;
+  #   package = pkgs.fprintd-tod;
+  # };
+
+  systemd.services.fprintd.environment.FP_TOD_DRIVERS_DIR =
+    "${pkgs.libfprint-2-tod1-goodix}/usr/lib/libfprint-2/tod-1";
+
+  security.pam.services = {
+    login.fprintAuth = true;
+    sudo.fprintAuth = true;
+    i3lock.fprintAuth = false;
+    i3lock-color.fprintAuth = false;
+    lightdm.fprintAuth = true;
+    lightdm-greeter.fprintAuth = true;
+  };
+
+  hardware.opengl.driSupport32Bit = true;
+
+  hardware.pulseaudio.extraConfig = ''
+    load-module module-remap-source source_name=KompleteAudio6_1 source_properties=device.description=KompleteAudio6Input1 master=alsa_input.usb-Native_Instruments_Komplete_Audio_6_458E0FFD-00.multichannel-input remix=no channels=1 master_channel_map=front-left channel_map=mono
+    load-module module-remap-source source_name=KompleteAudio6_2 source_properties=device.description=KompleteAudio6Input2 master=alsa_input.usb-Native_Instruments_Komplete_Audio_6_458E0FFD-00.multichannel-input remix=no channels=1 master_channel_map=front-right channel_map=mono
+    load-module module-remap-sink sink_name=KompleteAudio6_12 sink_properties=device.description=KompleteAudio6_12 remix=no master=alsa_output.usb-Native_Instruments_Komplete_Audio_6_458E0FFD-00.analog-surround-21 channels=2 master_channel_map=front-left,front-right channel_map=front-left,front-right
+  '';
+
+  services.fwupd.enable = true;
+
+  services.tailscale.enable = true;
+}
diff --git a/users/aspen/system/system/modules/common.nix b/users/aspen/system/system/modules/common.nix
new file mode 100644
index 0000000000..3eaeb2efc6
--- /dev/null
+++ b/users/aspen/system/system/modules/common.nix
@@ -0,0 +1,97 @@
+{ config, lib, pkgs, ... }:
+
+let
+
+  depot = import ../../../../.. { };
+
+in
+
+with lib;
+
+{
+  boot = {
+    loader.systemd-boot.enable = true;
+    loader.efi.canTouchEfiVariables = true;
+    tmp.cleanOnBoot = true;
+  };
+
+  networking.useDHCP = false;
+  networking.networkmanager.enable = true;
+  systemd.services.NetworkManager-wait-online.enable = lib.mkForce false;
+  systemd.services.systemd-networkd-wait-online.enable = lib.mkForce false;
+
+  i18n = {
+    defaultLocale = "en_US.UTF-8";
+  };
+
+  time.timeZone = lib.mkDefault "America/New_York";
+
+  environment.systemPackages = with pkgs; [
+    wget
+    vim
+    zsh
+    git
+    w3m
+    libnotify
+    file
+    lm_sensors
+    dnsutils
+    htop
+    man-pages
+    man-pages-posix
+  ];
+
+  documentation.dev.enable = true;
+  documentation.man.generateCaches = true;
+
+  services.openssh = {
+    enable = true;
+    settings = { X11Forwarding = true; };
+  };
+
+  users.users.aspen.openssh.authorizedKeys.keys =
+    [ depot.users.aspen.keys.main ];
+
+  programs.ssh.startAgent = true;
+
+  networking.firewall.enable = mkDefault false;
+
+  users.mutableUsers = true;
+  programs.zsh.enable = true;
+  environment.pathsToLink = [ "/share/zsh" ];
+  users.users.aspen = {
+    isNormalUser = true;
+    initialPassword = "password";
+    extraGroups = [
+      "wheel"
+      "networkmanager"
+      "audio"
+    ];
+    shell = pkgs.zsh;
+  };
+
+  nix = {
+    settings.trusted-users = [ "aspen" ];
+    distributedBuilds = true;
+
+    gc = {
+      automatic = true;
+      dates = mkDefault "weekly";
+      options = "--delete-older-than 30d";
+    };
+  };
+
+  services.udev.packages = with pkgs; [
+    yubikey-personalization
+  ];
+
+  services.pcscd.enable = true;
+
+  services.udev.extraRules = ''
+    # UDEV rules for Teensy USB devices
+    ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789B]?", ENV{ID_MM_DEVICE_IGNORE}="1"
+    ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789A]?", ENV{MTP_NO_PROBE}="1"
+    SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789ABCD]?", MODE:="0666"
+    KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789B]?", MODE:="0666"
+  '';
+}
diff --git a/users/aspen/system/system/modules/desktop.nix b/users/aspen/system/system/modules/desktop.nix
new file mode 100644
index 0000000000..9a5fc825e1
--- /dev/null
+++ b/users/aspen/system/system/modules/desktop.nix
@@ -0,0 +1,19 @@
+{ config, lib, pkgs, ... }:
+
+{
+  imports = [
+    ./xserver.nix
+    ./fonts.nix
+    ./sound.nix
+    ./kernel.nix
+  ];
+
+  programs.nm-applet.enable = true;
+
+  users.users.aspen.extraGroups = [
+    "audio"
+    "video"
+  ];
+
+  services.geoclue2.enable = true;
+}
diff --git a/users/aspen/system/system/modules/development.nix b/users/aspen/system/system/modules/development.nix
new file mode 100644
index 0000000000..bd5e326b2e
--- /dev/null
+++ b/users/aspen/system/system/modules/development.nix
@@ -0,0 +1,15 @@
+{ config, lib, pkgs, ... }:
+
+{
+  virtualisation.docker.enable = true;
+  users.users.aspen.extraGroups = [ "docker" ];
+
+  security.pam.loginLimits = [
+    {
+      domain = "aspen";
+      type = "soft";
+      item = "nofile";
+      value = "65535";
+    }
+  ];
+}
diff --git a/users/aspen/system/system/modules/fcitx.nix b/users/aspen/system/system/modules/fcitx.nix
new file mode 100644
index 0000000000..812f598f9f
--- /dev/null
+++ b/users/aspen/system/system/modules/fcitx.nix
@@ -0,0 +1,10 @@
+{ config, lib, pkgs, ... }:
+
+{
+  i18n.inputMethod = {
+    enabled = "fcitx";
+    fcitx.engines = with pkgs.fcitx-engines; [
+      cloudpinyin
+    ];
+  };
+}
diff --git a/users/aspen/system/system/modules/fonts.nix b/users/aspen/system/system/modules/fonts.nix
new file mode 100644
index 0000000000..598336790a
--- /dev/null
+++ b/users/aspen/system/system/modules/fonts.nix
@@ -0,0 +1,13 @@
+{ config, lib, pkgs, ... }:
+{
+  fonts = {
+    packages = with pkgs; [
+      nerdfonts
+      noto-fonts-emoji
+      twitter-color-emoji
+      weather-icons
+    ];
+
+    fontconfig.defaultFonts.emoji = [ "Twitter Color Emoji" ];
+  };
+}
diff --git a/users/aspen/system/system/modules/laptop.nix b/users/aspen/system/system/modules/laptop.nix
new file mode 100644
index 0000000000..89c880973d
--- /dev/null
+++ b/users/aspen/system/system/modules/laptop.nix
@@ -0,0 +1,23 @@
+{ config, lib, pkgs, ... }:
+
+{
+  services.logind = {
+    powerKey = "hibernate";
+    powerKeyLongPress = "poweroff";
+    lidSwitch = "suspend-then-hibernate";
+    lidSwitchExternalPower = "ignore";
+  };
+
+  systemd.sleep.extraConfig = ''
+    HibernateDelaySec=30m
+    SuspendState=mem
+  '';
+
+  services.tlp.enable = true;
+
+  services.upower = {
+    enable = true;
+    criticalPowerAction = "Hibernate";
+    percentageAction = 3;
+  };
+}
diff --git a/users/aspen/system/system/modules/reusable/README.org b/users/aspen/system/system/modules/reusable/README.org
new file mode 100644
index 0000000000..34d9bfdcb7
--- /dev/null
+++ b/users/aspen/system/system/modules/reusable/README.org
@@ -0,0 +1,2 @@
+This directory contains things I'm eventually planning on contributing upstream
+to nixpkgs
diff --git a/users/aspen/system/system/modules/rtlsdr.nix b/users/aspen/system/system/modules/rtlsdr.nix
new file mode 100644
index 0000000000..ce58ebb0dc
--- /dev/null
+++ b/users/aspen/system/system/modules/rtlsdr.nix
@@ -0,0 +1,17 @@
+{ config, lib, pkgs, ... }:
+
+{
+
+  environment.systemPackages = with pkgs; [
+    rtl-sdr
+  ];
+
+  services.udev.packages = with pkgs; [
+    rtl-sdr
+  ];
+
+  # blacklist for rtl-sdr
+  boot.blacklistedKernelModules = [
+    "dvb_usb_rtl28xxu"
+  ];
+}
diff --git a/users/aspen/system/system/modules/sound.nix b/users/aspen/system/system/modules/sound.nix
new file mode 100644
index 0000000000..07a67a1ec4
--- /dev/null
+++ b/users/aspen/system/system/modules/sound.nix
@@ -0,0 +1,16 @@
+{ config, lib, pkgs, ... }:
+
+{
+  # Enable sound.
+  sound.enable = true;
+  hardware.pulseaudio.enable = true;
+
+  environment.systemPackages = with pkgs; [
+    pulseaudio-ctl
+    paprefs
+    pasystray
+    pavucontrol
+  ];
+
+  hardware.pulseaudio.package = pkgs.pulseaudioFull;
+}
diff --git a/users/aspen/system/system/modules/tvl.nix b/users/aspen/system/system/modules/tvl.nix
new file mode 100644
index 0000000000..f91315fc79
--- /dev/null
+++ b/users/aspen/system/system/modules/tvl.nix
@@ -0,0 +1,35 @@
+{ config, lib, pkgs, ... }:
+
+{
+  nix = {
+    buildMachines = [{
+      hostName = "whitby.tvl.fyi";
+      sshUser = "aspen";
+      sshKey = "/root/.ssh/id_rsa";
+      system = "x86_64-linux";
+      maxJobs = 64;
+      supportedFeatures = [ "big-parallel" "kvm" "nixos-test" "benchmark" ];
+    }];
+
+    extraOptions = ''
+      builders-use-substitutes = true
+    '';
+
+    settings = {
+      substituters = [
+        "https://cache.nixos.org"
+      ];
+      trusted-substituters = [
+        "https://cache.nixos.org"
+        "ssh://nix-ssh@whitby.tvl.fyi"
+      ];
+    };
+  };
+
+  programs.ssh.knownHosts.whitby = {
+    extraHostNames = [ "whitby" "whitby.tvl.fyi" "49.12.129.211" ];
+    publicKeyFile = pkgs.writeText "whitby.pub" ''
+      ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILNh/w4BSKov0jdz3gKBc98tpoLta5bb87fQXWBhAl2I
+    '';
+  };
+}
diff --git a/users/aspen/system/system/modules/wireshark.nix b/users/aspen/system/system/modules/wireshark.nix
new file mode 100644
index 0000000000..b233d40041
--- /dev/null
+++ b/users/aspen/system/system/modules/wireshark.nix
@@ -0,0 +1,9 @@
+{ config, lib, pkgs, ... }:
+
+{
+  programs.wireshark = {
+    enable = true;
+    package = pkgs.wireshark;
+  };
+  users.users.aspen.extraGroups = [ "wireshark" ];
+}
diff --git a/users/aspen/system/system/modules/xserver.nix b/users/aspen/system/system/modules/xserver.nix
new file mode 100644
index 0000000000..f78edb207e
--- /dev/null
+++ b/users/aspen/system/system/modules/xserver.nix
@@ -0,0 +1,16 @@
+{ config, pkgs, ... }:
+{
+  # Enable the X11 windowing system.
+  services.xserver = {
+    enable = true;
+    xkb.layout = "us";
+
+    libinput.enable = true;
+
+    displayManager = {
+      defaultSession = "none+i3";
+    };
+
+    windowManager.i3.enable = true;
+  };
+}