diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 120000 index 0000000..3d8ebf1 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1 @@ +/nix/store/9vwq8yq418pgq8y5d2qmd9vfl4nx8bqp-pre-commit-config.json \ No newline at end of file diff --git a/flake-module.nix b/flake-module.nix new file mode 100644 index 0000000..ea957de --- /dev/null +++ b/flake-module.nix @@ -0,0 +1,83 @@ +{ + inputs, + lib, + ... +}: +{ + # debug = true; + # We only define machines config in this flake yet, so we only include + # the module that builds these. This file might get fuller, if we need to + # build our own packages, that are not flakes. + imports = [ + ./nixos/flake-module.nix + # ./packages/flake-module.nix + inputs.pre-commit-hooks.flakeModule + # To import a flake module + # 1. Add foo to inputs + # 2. Add foo as a parameter to the outputs function + # 3. Add here: foo.flakeModule + ]; + systems = [ "x86_64-linux" ]; + perSystem = + { + config, + pkgs, + system, + ... + }: + { + devShells.default = config.pre-commit.devShell; + + pre-commit = + let + generatedFiles = [ + "hardware-configuration\\.nix" + ]; + in + { + check.enable = true; + settings = { + hooks = { + nil.enable = true; + statix = { + enable = true; + settings = { + format = "stderr"; + ignore = generatedFiles; + }; + }; + deadnix = { + enable = true; + excludes = generatedFiles; + }; + nixfmt-rfc-style.enable = true; + }; + }; + }; + + formatter = pkgs.nixfmt-rfc-style; + _module.args.pkgs = import inputs.nixpkgs { + inherit system; + config.allowUnfreePredicate = + pkg: + builtins.elem (lib.getName pkg) [ + "steam" + "steam-original" + "steam-unwrapped" + "steam-run" + ]; + }; + + # Per-system attributes can be defined here. The self' and inputs' + # module parameters provide easy access to attributes of the same + # system. + }; + + # Equivalent to inputs'.nixpkgs.legacyPackages.hello; + # flake = { + # The usual flake attributes can be defined here, including system- + # agnostic ones like nixosModule and system-enumerating ones, although + # those are more easily expressed in perSystem. + + # }; +} diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..501192b --- /dev/null +++ b/flake.lock @@ -0,0 +1,139 @@ +{ + "nodes": { + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1743550720, + "narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "c621e8422220273271f52058f618c94e405bb0f5", + "type": "github" + }, + "original": { + "id": "flake-parts", + "type": "indirect" + } + }, + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1746317522, + "narHash": "sha256-/jZ4Wd4HHUEWPSlNj48k1E4Mh+1fUbwI/vSlPPIMG3U=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "621986fed37c5d0cb8df010ed8369694dc47c09b", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "impermanence": { + "locked": { + "lastModified": 1737831083, + "narHash": "sha256-LJggUHbpyeDvNagTUrdhe/pRVp4pnS6wVKALS782gRI=", + "owner": "nix-community", + "repo": "impermanence", + "rev": "4b3e914cdf97a5b536a889e939fb2fd2b043a170", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "impermanence", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1746141548, + "narHash": "sha256-IgBWhX7A2oJmZFIrpRuMnw5RAufVnfvOgHWgIdds+hc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "f02fddb8acef29a8b32f10a335d44828d7825b78", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1743296961, + "narHash": "sha256-b1EdN3cULCqtorQ4QeWgLMrd5ZGOjLSLemfa00heasc=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "e4822aea2a6d1cdd36653c134cacfd64c97ff4fa", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "pre-commit-hooks": { + "inputs": { + "flake-compat": [], + "gitignore": [], + "nixpkgs": [] + }, + "locked": { + "lastModified": 1742649964, + "narHash": "sha256-DwOTp7nvfi8mRfuL1escHDXabVXFGT1VlPD1JHrtrco=", + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "rev": "dcf5072734cb576d2b0c59b2ac44f5050b5eac82", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "pre-commit-hooks.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-parts": "flake-parts", + "home-manager": "home-manager", + "impermanence": "impermanence", + "nixpkgs": "nixpkgs", + "pre-commit-hooks": "pre-commit-hooks", + "sops-nix": "sops-nix" + } + }, + "sops-nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1745310711, + "narHash": "sha256-ePyTpKEJTgX0gvgNQWd7tQYQ3glIkbqcW778RpHlqgA=", + "owner": "Mic92", + "repo": "sops-nix", + "rev": "5e3e92b16d6fdf9923425a8d4df7496b2434f39c", + "type": "github" + }, + "original": { + "owner": "Mic92", + "repo": "sops-nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..87d3ef3 --- /dev/null +++ b/flake.nix @@ -0,0 +1,30 @@ +{ + description = "Description for the project"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + sops-nix = { + url = "github:Mic92/sops-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + impermanence = { + url = "github:nix-community/impermanence"; + }; + home-manager = { + url = "github:nix-community/home-manager"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + pre-commit-hooks = { + url = "github:cachix/pre-commit-hooks.nix"; + inputs = { + flake-compat.follows = ""; + gitignore.follows = ""; + nixpkgs.follows = ""; + }; + }; + }; + + outputs = + inputs@{ flake-parts, ... }: + flake-parts.lib.mkFlake { inherit inputs; } (import ./flake-module.nix); +} diff --git a/nixos/flake-module.nix b/nixos/flake-module.nix new file mode 100644 index 0000000..978df62 --- /dev/null +++ b/nixos/flake-module.nix @@ -0,0 +1,45 @@ +# copied and adopted from maralorns config +# This automatically searches for nixos configs in ./machines/${name}/configuration.nix +# and exposes them as outputs.nixosConfigurations.${name} +{ + withSystem, + lib, + inputs, + ... +}: +{ + flake = { + nixosConfigurations = withSystem "x86_64-linux" ( + { pkgs, ... }: + let + machines = builtins.attrNames (builtins.readDir ./machines); + makeSystem = + name: + let + importedConfig = import (./. + "/machines/${name}/configuration.nix"); + systemConfig = + if lib.isFunction importedConfig then + x: + importedConfig ( + x + // { + flake-inputs = inputs; + inherit pkgs; + } + ) + else + importedConfig; + in + pkgs.nixos { + imports = [ + systemConfig + inputs.sops-nix.nixosModules.sops + inputs.impermanence.nixosModules.impermanence + inputs.home-manager.nixosModules.home-manager + ]; + }; + in + lib.genAttrs machines makeSystem + ); + }; +} diff --git a/nixos/machines/nerflap3/configuration.nix b/nixos/machines/nerflap3/configuration.nix new file mode 100644 index 0000000..384e946 --- /dev/null +++ b/nixos/machines/nerflap3/configuration.nix @@ -0,0 +1,36 @@ +{ + imports = [ + ./hardware-configuration.nix + ../../roles + ]; + + networking.hostName = "nerflap3"; + system.stateVersion = "25.05"; + + networking.networkmanager.enable = true; + users.users.nerf.extraGroups = [ "networkmanager" ]; + + services.pipewire = { + enable = true; + audio.enable = true; + pulse.enable = true; + jack.enable = true; + alsa.enable = true; + }; + + programs = { + git.enable = true; + steam = { + enable = true; + remotePlay.openFirewall = true; + dedicatedServer.openFirewall = true; + localNetworkGameTransfers.openFirewall = true; + }; + hyprland.enable = true; + }; + home-manager = { + useGlobalPkgs = true; + useUserPackages = true; + users.nerf = ./home.nix; + }; +} diff --git a/nixos/machines/nerflap3/hardware-configuration.nix b/nixos/machines/nerflap3/hardware-configuration.nix new file mode 100644 index 0000000..27b2a8a --- /dev/null +++ b/nixos/machines/nerflap3/hardware-configuration.nix @@ -0,0 +1,44 @@ +{ + lib, + pkgs, + ... +}: +{ + imports = [ ]; + + fileSystems."/" = { + device = "root"; + fsType = "tmpfs"; + options = [ + "size=1G" + "mode=755" + ]; + }; + fileSystems."/persist" = { + device = "/dev/disk/by-label/nixos"; + fsType = "btrfs"; + options = [ "subvol=persist" ]; + neededForBoot = true; + }; + fileSystems."/boot" = { + device = "/dev/disk/by-label/boot"; + fsType = "ext4"; + }; + fileSystems."/nix" = { + device = "/dev/disk/by-label/nixos"; + fsType = "btrfs"; + options = [ "subvol=nix" ]; + }; + fileSystems."/home" = { + device = "/dev/disk/by-label/nixos"; + fsType = "btrfs"; + options = [ "subvol=home" ]; + }; + + boot = { + loader.systemd-boot.enable = true; + initrd.luks.devices.cryptroot.device = "/dev/disk/by-uuid/597B-4974"; + }; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; +} diff --git a/nixos/machines/nerflap3/home.nix b/nixos/machines/nerflap3/home.nix new file mode 100644 index 0000000..63ffcad --- /dev/null +++ b/nixos/machines/nerflap3/home.nix @@ -0,0 +1,93 @@ +{ pkgs, ... }: +{ + home = { + username = "nerf"; + homeDirectory = "/home/nerf"; + stateVersion = "25.05"; + packages = [ + pkgs.pavucontrol + ]; + }; + programs = { + + kitty.enable = true; + wofi.enable = true; + helix.enable = true; + waybar.enable = true; + + }; + wayland.windowManager.hyprland = { + enable = true; + package = null; + portalPackage = null; + systemd.variables = [ "--all" ]; # import environment (like PATH) into the systemd unit + settings = { + input = { + kb_layout = "de"; + kb_variant = "neo"; + }; + general = { + gaps_in = 0; + gaps_out = 0; + boarder_size = 1; + "col.active_border" = "rgba(22ccffee) rgba(00ff99ee) 45deg"; + "col.inactive_border" = "rgba(595959aa)"; + layout = "master"; + allow_tearing = false; + }; + decoration = { + rounding = 0; + blur = { + enabled = false; + size = 3; + passes = 1; + }; + }; + animations = { + enabled = true; + bezier = "myBezier, 0.05, 0.9, 0.1, 1.05"; + animation = [ + "windows, 1, 7, myBezier" + "windowsOut, 1, 7, default, popin 80%" + "border, 1, 8, default" + "fade, 1, 7, default" + "workspace, 1, 6, default" + ]; + }; + master = { + new_on_top = true; + }; + "$mainMod" = "SUPER"; + "$menu" = "wofi --show drun"; + bind = + [ + "$mainMod, Return, exec, kitty" + "$mainMod, C, killactive," + "$mainMod, M, exit," + "$mainMod, V, togglefloating," + "$mainMod, P, exec, $menu" + "$mainMod, Space, layoutmsg, swapwithmaster auto" + "$mainMod, N, layoutmsg, cyclenext" + "$mainMod, R, layoutmsg, cycleprev" + "$mainMod, S, togglespecialwokspace, magic" + "$mainMod, SHIFT, S, movetoworkspace, special:magic" + ] + ++ (builtins.concatLists ( + builtins.genList ( + i: + let + ws = i + 1; + in + [ + "$mainMod, code:1${toString i}, workspace, ${toString ws}" + "$mainMod SHIFT, code:1${toString i}, movetoworkspace, ${toString ws}" + ] + ) 9 + )); + bindm = [ + "$mainMod, mouse:272, movewindow" + "$mainMod, mouse:273, resizewindow" + ]; + }; + }; +} diff --git a/nixos/modules/impermanence.nix b/nixos/modules/impermanence.nix new file mode 100644 index 0000000..26da2fb --- /dev/null +++ b/nixos/modules/impermanence.nix @@ -0,0 +1,48 @@ +{ + lib, + config, + ... +}: +let + inherit (lib) + mkEnableOption + mkIf + mkOption + types + ; + cfg = config.impermanence; +in +{ + imports = [ ]; + + options.impermanence = { + enable = mkEnableOption "impermanence"; + storagePath = mkOption { + type = types.path; + default = "/persist"; + description = "The path where persistent data is stored"; + }; + name = mkOption { + type = types.str; + default = "persist"; + description = "the name of the persistent data store"; + }; + }; + + config = mkIf cfg.enable { + environment.persistence.${cfg.name} = { + persistentStoragePath = cfg.storagePath; + directories = [ + "/var/log" + "/var/lib/nixos" + ]; + files = [ + "/etc/ssh/ssh_host_ed25519_key" + "/etc/ssh/ssh_host_ed25519_key.pub" + "/etc/ssh/ssh_host_rsa_key" + "/etc/ssh/ssh_host_rsa_key.pub" + ]; + }; + environment.etc.machine-id.source = "${cfg.storagePath}/machine-id"; + }; +} diff --git a/nixos/roles/admins.nix b/nixos/roles/admins.nix new file mode 100644 index 0000000..d55d3b3 --- /dev/null +++ b/nixos/roles/admins.nix @@ -0,0 +1,42 @@ +{ lib, ... }: +with lib; +let + admins = { + nerf = { + hashedPassword = "$y$j9T$b3ZDy/YaHDNiqcFFZyEcS.$HlWj1JiqbEMTsD0bMKSwKcJGO7cfpC4P8W8VAlvUTK/"; + sshKeys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEdA4LpEGUUmN8esFyrNZXFb2GiBID9/S6zzhcnofQuP nerf@nerflap2" + "sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIEdfOWD1DLuB1Ho69uRC3VgQu+X3gExFzVHhu2CAl8JSAAAABHNzaDo= laptop_child-sk" + ]; + nixKeys = [ + "nerflap2-1:pDZCg0oo9PxNQxwVSQSvycw7WXTl53PGvVeZWvxuqJc=" + ]; + }; + }; + + mkAdmin = + name: + { + hashedPassword, + sshKeys, + ... + }: + { + "${name}" = { + isNormalUser = true; + createHome = true; + extraGroups = [ "wheel" ]; + group = "users"; + home = "/home/${name}"; + openssh.authorizedKeys = { + keys = sshKeys; + }; + inherit hashedPassword; + }; + }; + mkNixKeys = _: { nixKeys, ... }: nixKeys; +in +{ + users.users = mkMerge (mapAttrsToList mkAdmin admins); + nix.settings.trusted-public-keys = lists.concatLists (mapAttrsToList mkNixKeys admins); +} diff --git a/nixos/roles/default.nix b/nixos/roles/default.nix new file mode 100644 index 0000000..e044b36 --- /dev/null +++ b/nixos/roles/default.nix @@ -0,0 +1,63 @@ +{ + pkgs, + lib, + ... +}: +{ + imports = [ + ./admins.nix + ./nix.nix + ./keyboard.nix + ../modules/impermanence.nix + ]; + + networking = { + firewall = { + # these shoud be default, but better make sure! + enable = true; + allowPing = true; + }; + nftables.enable = true; + }; + + users = { + mutableUsers = false; + users.root.hashedPassword = "!"; + }; + + impermanence.enable = true; + + sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ]; + + environment = { + systemPackages = builtins.attrValues { + inherit (pkgs) + htop + lsof + tmux + btop + helix + ; + }; + }; + + services = { + journald.extraConfig = "SystemMaxUse=1G"; + + nginx = { + recommendedOptimisation = true; + recommendedGzipSettings = true; + recommendedTlsSettings = true; + }; + + openssh = { + enable = true; + settings = { + PermitRootLogin = "no"; + PasswordAuthentication = false; + }; + }; + #Prevent clock drift due to interaction problem with xen hardware clock + timesyncd.enable = lib.mkForce true; + }; +} diff --git a/nixos/roles/keyboard.nix b/nixos/roles/keyboard.nix new file mode 100644 index 0000000..9ace547 --- /dev/null +++ b/nixos/roles/keyboard.nix @@ -0,0 +1,7 @@ +{ + services.xserver = { + xkb.layout = "de"; + xkb.variant = "neo"; + }; + console.useXkbConfig = true; +} diff --git a/nixos/roles/nix.nix b/nixos/roles/nix.nix new file mode 100644 index 0000000..63a3c0c --- /dev/null +++ b/nixos/roles/nix.nix @@ -0,0 +1,22 @@ +{ + nix = { + settings = { + # trusted-public-keys belonging to specific persons are set in rolse/admins.nix + trusted-public-keys = [ ]; + experimental-features = [ + "flakes" + "nix-command" + ]; + auto-optimise-store = true; + fallback = true; + builders-use-substitutes = true; + }; + gc = { + automatic = true; + persistent = false; + dates = "weekly"; + options = "-d"; + randomizedDelaySec = "5h"; + }; + }; +}