commit 132a109da8ac5818e83aea97d4767902c5043fa3 Author: reidlab Date: Thu Mar 28 01:38:40 2024 -0700 init diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..e3207ea --- /dev/null +++ b/.editorconfig @@ -0,0 +1,5 @@ +root = true + +[*] +indent_style = space +indent_size = 2 \ No newline at end of file diff --git a/default.nix b/default.nix new file mode 100755 index 0000000..5f373fb --- /dev/null +++ b/default.nix @@ -0,0 +1,59 @@ +{ config, inputs, lib, pkgs, ... }: + +let + inherit (builtins) toString; + inherit (lib.modules) mkDefault mkIf; + inherit (lib.my) mapModulesRec'; +in { + imports = + [ + inputs.home-manager.nixosModules.home-manager + (mkAliasOptionModule ["hm"] ["home-manager" "users" config.user.name]) + ] + ++ (mapModulesRec' (toString ./modules) import); + + nix = { + package = pkgs.nix; + + # flake registry and nix path pinning + # might not be needed? see: https://github.com/NixOS/nixpkgs/commit/e456032addae76701eb17e6c03fc515fd78ad74f + nixPath = [ "nixpkgs=${inputs.nixpkgs}" ]; + registry.nixpkgs.flake = inputs.nixpkgs; + + settings = { + experimental-features = [ "nix-command" "flakes" ]; + auto-optimise-store = true; + keep-outputs = true; + keep-derivations = true; + substituters = [ + "https://nix-community.cachix.org" + ]; + trusted-public-keys = [ + "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" + ]; + }; + }; + + # set our git revision inside `nixos-version` + system.configurationRevision = with inputs; mkIf (self ? rev) self.rev; + + # set home stateversion to system stateversion. Just Makes Sense + hm.home.stateVersion = config.system.stateVersion; + + time.timeZone = mkDefault "America/Los_Angeles"; + + i18n.defaultLocale = mkDefault "en_US.UTF-8"; + + hardware.enableRedistributableFirmware = true; + + environment.systemPackages = with pkgs; [ + unrar unzip + micro + curl wget + # im pretty sure removing this breaks nixos-rebuild + # have fun + git + ]; + + system.stateVersion = mkDefault "23.11"; +} diff --git a/flake.nix b/flake.nix new file mode 100755 index 0000000..e26fc20 --- /dev/null +++ b/flake.nix @@ -0,0 +1,48 @@ +{ + description = "a collection of personal nix configurations"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + + home-manager.url = "github:nix-community/home-manager"; + home-manager.inputs.nixpkgs.follows = "nixpkgs"; + }; + + outputs = inputs @ { self, nixpkgs, ... }: + let + inherit (lib.my) mapModules mapModulesRec mapHosts; + system = "x86_64-linux"; + + mkPkgs = pkgs: extraOverlays: + import pkgs { + inherit system; + config.allowUnfree = true; + config.allowAliases = false; + overlays = extraOverlays ++ (lib.attrValues self.overlays); + }; + pkgs = mkPkgs nixpkgs [ self.overlays.default ]; + + lib = nixpkgs.lib.extend (final: prev: { + my = import ./lib { + inherit pkgs inputs; + lib = final; + }; + }); + in { + lib = lib.my; + + overlays = + (mapModules ./overlays import) + // { + default = final: prev: { + my = self.packages.${system}; + }; + }; + + packages."${system}" = mapModules ./packages (p: pkgs.callPackage p {}); + + nixosModules = mapModulesRec ./modules import; + + nixosConfigurations = mapHosts ./hosts {}; + }; +} diff --git a/hosts/goopnet-interface/default.nix b/hosts/goopnet-interface/default.nix new file mode 100755 index 0000000..86ca36a --- /dev/null +++ b/hosts/goopnet-interface/default.nix @@ -0,0 +1,28 @@ +{ config, lib, pkgs, ... }: + +in { + imports = [ + ./hardware.nix + ]; + + hm.home.packages = with pkgs; [ + # archives + zip xz unzip p7zip + # utils + ripgrep jq + # nix + nix-output-monitor + # system + btop duf killall + # misc + file which tree + ] ++ (with pkgs.my; [ + # none yet + ]); + + modules = { + security.useDoas = false; + }; + + networking.networkmanager.enable = true; +} diff --git a/hosts/goopnet-interface/hardware.nix b/hosts/goopnet-interface/hardware.nix new file mode 100755 index 0000000..83a985a --- /dev/null +++ b/hosts/goopnet-interface/hardware.nix @@ -0,0 +1,41 @@ +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ + (modulesPath + "/installer/scan/not-detected.nix") + ]; + + boot = { + initrd.availableKernelModules = [ "xhci_pci" "ehci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" "sdhci_pci" ]; + initrd.kernelModules = [ ]; + kernelModules = [ ]; + extraModulePackages = [ ]; + # TODO: move bootloader, networking, boot speed to another file? + kernelPackages = pkgs.linuxPackages_latest; + loader = { + # use u-boot over grub + grub.enable = lib.mkForce false; + generic-extlinux-compatible.enable = true; + }; + }; + + fileSystems."/" = { + device = "/dev/disk/by-uuid/44444444-4444-4444-8888-888888888888"; + fsType = "ext4"; + }; + + swapDevices = + [ ]; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.end0.useDHCP = lib.mkDefault true; + # networking.interfaces.wlan0.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "aarch64-linux"; + powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand"; +} diff --git a/lib/attrs.nix b/lib/attrs.nix new file mode 100644 index 0000000..e5890b4 --- /dev/null +++ b/lib/attrs.nix @@ -0,0 +1,25 @@ +{lib, ...}: let + inherit (lib.lists) any count; + inherit (lib.attrsets) filterAttrs listToAttrs mapAttrs' mapAttrsToList; +in rec { + # attrsToList + attrsToList = attrs: + mapAttrsToList (name: value: {inherit name value;}) attrs; + + # mapFilterAttrs :: + # (name -> value -> bool) + # (name -> value -> { name = any; value = any; }) + # attrs + mapFilterAttrs = pred: f: attrs: filterAttrs pred (mapAttrs' f attrs); + + # Generate an attribute set by mapping a function over a list of values. + genAttrs' = values: f: listToAttrs (map f values); + + # anyAttrs :: (name -> value -> bool) attrs + anyAttrs = pred: attrs: + any (attr: pred attr.name attr.value) (attrsToList attrs); + + # countAttrs :: (name -> value -> bool) attrs + countAttrs = pred: attrs: + count (attr: pred attr.name attr.value) (attrsToList attrs); +} diff --git a/lib/default.nix b/lib/default.nix new file mode 100755 index 0000000..1bb3d04 --- /dev/null +++ b/lib/default.nix @@ -0,0 +1,20 @@ +{ inputs, lib, pkgs, ... }: + + let + inherit (lib.attrsets) attrValues; + inherit (lib.fixedPoints) makeExtensible; + inherit (lib.lists) foldr; + inherit (modules) mapModules; + + modules = import ./modules.nix { + inherit lib; + self.attrs = import ./attrs.nix { + inherit lib; + self = {}; + }; + }; + mylib = + makeExtensible (self: + mapModules ./. (file: import file {inherit self lib pkgs inputs;})); + in + mylib.extend (self: super: foldr (a: b: a // b) {} (attrValues super)) diff --git a/lib/modules.nix b/lib/modules.nix new file mode 100755 index 0000000..bb30ed5 --- /dev/null +++ b/lib/modules.nix @@ -0,0 +1,43 @@ +{ + lib, + self, + ... +}: let + inherit (builtins) attrValues readDir pathExists concatLists; + inherit (lib.attrsets) mapAttrsToList filterAttrs nameValuePair; + inherit (lib.strings) hasPrefix hasSuffix removeSuffix; + inherit (lib.trivial) id; + inherit (self.attrs) mapFilterAttrs; +in rec { + mapModules = dir: fn: + mapFilterAttrs (n: v: v != null && !(hasPrefix "_" n)) (n: v: let + path = "${toString dir}/${n}"; + in + if v == "directory" && pathExists "${path}/default.nix" + then nameValuePair n (fn path) + else if v == "regular" && n != "default.nix" && hasSuffix ".nix" n + then nameValuePair (removeSuffix ".nix" n) (fn path) + else nameValuePair "" null) (readDir dir); + + mapModules' = dir: fn: attrValues (mapModules dir fn); + + mapModulesRec = dir: fn: + mapFilterAttrs (n: v: v != null && !(hasPrefix "_" n)) (n: v: let + path = "${toString dir}/${n}"; + in + if v == "directory" + then nameValuePair n (mapModulesRec path fn) + else if v == "regular" && n != "default.nix" && hasSuffix ".nix" n + then nameValuePair (removeSuffix ".nix" n) (fn path) + else nameValuePair "" null) (readDir dir); + + mapModulesRec' = dir: fn: let + dirs = + mapAttrsToList (k: _: "${dir}/${k}") + (filterAttrs (n: v: v == "directory" && !(hasPrefix "_" n)) + (readDir dir)); + files = attrValues (mapModules dir id); + paths = files ++ concatLists (map (d: mapModulesRec' d id) dirs); + in + map fn paths; +} diff --git a/lib/nixos.nix b/lib/nixos.nix new file mode 100755 index 0000000..40c0032 --- /dev/null +++ b/lib/nixos.nix @@ -0,0 +1,35 @@ +{ + inputs, + lib, + pkgs, + self, + ... +}: let + inherit (inputs.nixpkgs.lib) nixosSystem; + inherit (builtins) baseNameOf elem; + inherit (lib.attrsets) filterAttrs; + inherit (lib.modules) mkDefault; + inherit (lib.strings) removeSuffix; + inherit (self.modules) mapModules; +in rec { + mkHost = path: attrs @ {system ? "x86_64-linux", ...}: + nixosSystem { + inherit system; + + specialArgs = {inherit lib inputs system;}; + + modules = [ + { + nixpkgs.pkgs = pkgs; + networking.hostName = + mkDefault (removeSuffix ".nix" (baseNameOf path)); + } + (filterAttrs (n: v: !elem n ["system"]) attrs) + ../. # /default.nix + (import path) + ]; + }; + + mapHosts = dir: attrs @ {system ? system, ...}: + mapModules dir (hostPath: mkHost hostPath attrs); +} diff --git a/modules/security.nix b/modules/security.nix new file mode 100755 index 0000000..14162ad --- /dev/null +++ b/modules/security.nix @@ -0,0 +1,70 @@ +{ config, lib, options, pkgs, ... }: + +with lib; +let + cfg = config.modules.security; +in { + options.modules.security = { + useDoas = mkEnableOption "use opendoas instead of sudo"; + }; + + config = mkIf cfg.enable { + boot = { + tmp.useTmpfs = lib.mkDefault true; + tmp.cleanOnBoot = lib.mkDefault (!config.boot.tmp.useTmpfs); + + kernel.sysctl = { + # magic sysrq key, allows low-level commands through keyboard input + "kernel.sysrq" = 0; + + ## TCP hardening + # prevent bogus ICMP errors from filling up logs + "net.ipv4.icmp_ignore_bogus_error_responses" = 1; + # do not accept IP source packets (we are not a router) + "net.ipv4.conf.all.accept_source_route" = 0; + "net.ipv6.conf.all.accept_source_route" = 0; + # don't send ICMP redirects (again, we're not a router) + "net.ipv4.conf.all.send_redirects" = 0; + "net.ipv4.conf.default.send_redirects" = 0; + # refuse ICMP redirects (MITM mitigations) + "net.ipv4.conf.all.accept_redirects" = 0; + "net.ipv4.conf.default.accept_redirects" = 0; + "net.ipv4.conf.all.secure_redirects" = 0; + "net.ipv4.conf.default.secure_redirects" = 0; + "net.ipv6.conf.all.accept_redirects" = 0; + "net.ipv6.conf.default.accept_redirects" = 0; + # protects against SYN flood attacks + "net.ipv4.tcp_syncookies" = 1; + # incomplete protection against TIME-WAIT assassination + "net.ipv4.tcp_rfc1337" = 1; + + ## TCP optimization + # TCP fastopen + "net.ipv4.tcp_fastopen" = 3; + # bufferbloat mitigations + improvement in throughput and latency + "net.ipv4.tcp_conjestion_control" = "bbr"; + "net.core.default_qdisc" = "cake"; + }; + kernelModules = [ "tcp_bbr" ]; + }; + + security = { + # prevents replacing the kernel without a reboot + protectKernelImage = true; + # rtkit allows unprivileged processes to use realtime scheduling + # polkit allows unprivileged processes to speak to privileged processes (ex. nmtui, reboot) + rtkit.enable = true; + polkit.enable = true; + }; + + # personal computer? no firewall ty :3 + networking.firewall.enable = false; + } // (mkIf cfg.useDoas { + security.sudo.enable = false; + security.doas.enable = true; + security.doas.extraRules = [ + { users = [ config.user.name ]; noPass = true; persist = false; keepEnv = true; } + ]; + environment.systemPackages = with pkgs; [ doas-sudo-shim ]; + }); +} diff --git a/modules/user.nix b/modules/user.nix new file mode 100644 index 0000000..86a57ed --- /dev/null +++ b/modules/user.nix @@ -0,0 +1,29 @@ +{ config, pkgs, lib, options, ... }: + +with lib; +with lib.my; +{ + options = { + user = mkOpt types.attrs {}; + }; + + config = { + user = rec { + name = "reidlab"; + description = "awesome guy"; + extraGroups = ["wheel" "input" "audio" "video" "storage"]; + isNormalUser = true; + home = "/home/${name}"; + group = name; + uid = 1000; + }; + users.groups.${config.user.group} = {}; + + users.users.${config.user.name} = mkAliasDefinitions options.user; + + home-manager.useUserPackages = true; + + hm.home.username = config.user.name; + hm.home.homeDirectory = lib.mkForce config.user.home; + }; +} diff --git a/modules/xdg.nix b/modules/xdg.nix new file mode 100644 index 0000000..7ce9551 --- /dev/null +++ b/modules/xdg.nix @@ -0,0 +1,19 @@ +{ ... }: +{ + config = { + hm.xdg.enable = true; + hm.xdg.userDirs = { + enable = true; + createDirectories = true; + + desktop = "$HOME/desktop"; + documents = "$HOME/documents"; + download = "$HOME/downloads"; + music = "$HOME/music"; + pictures = "$HOME/pictures"; + publicShare = "$HOME/public"; + templates = "$HOME/templates"; + videos = "$HOME/videos"; + }; + }; +} diff --git a/overlays/.gitkeep b/overlays/.gitkeep new file mode 100755 index 0000000..e69de29 diff --git a/packages/.gitkeep b/packages/.gitkeep new file mode 100755 index 0000000..e69de29 diff --git a/readme.md b/readme.md new file mode 100755 index 0000000..f0b279f --- /dev/null +++ b/readme.md @@ -0,0 +1,14 @@ +# dotfiles + +nix flake config! this is just used on my personal computer + +## users + +this flake is built upon a single user system for all hosts, enforced by [`modules/user.nix`](./modules/user.nix). this makes it alot easier to make moduels that use nixos and `home-manager` + +## todo + +- some weird perl error abt locales when building using doas - `keepEnv` might fix this +- move common config such as bootloader and networking settings to [`default.nix`](./default.nix) +- leverage nixos-hardware +- flake-parts (hopefully we can merge the 2 repositories once we find a user solution)