diff options
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | flake.lock | 86 | ||||
-rw-r--r-- | flake.nix | 43 | ||||
-rw-r--r-- | hosts/ahmed/configuration.nix | 68 | ||||
-rw-r--r-- | hosts/ahmed/hardware-configuration.nix | 41 | ||||
-rw-r--r-- | hosts/ahmed/ssh.nix | 19 | ||||
-rw-r--r-- | hosts/muhammed/configuration.nix | 31 | ||||
-rw-r--r-- | lib/secrets/default.nix | 92 | ||||
-rw-r--r-- | lib/secrets/metadata.toml | 5 | ||||
-rw-r--r-- | use-cases/default.nix | 43 | ||||
-rw-r--r-- | use-cases/development/default.nix | 10 | ||||
-rw-r--r-- | use-cases/development/git.nix | 18 | ||||
-rw-r--r-- | use-cases/development/neovim.nix | 60 | ||||
-rw-r--r-- | use-cases/development/zsh.nix | 14 | ||||
-rw-r--r-- | use-cases/sysadmin/default.nix | 16 |
15 files changed, 549 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..adbc2b5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# Generated symlink +result +*/result diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..660b056 --- /dev/null +++ b/flake.lock @@ -0,0 +1,86 @@ +{ + "nodes": { + "home-manager": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ], + "utils": "utils" + }, + "locked": { + "lastModified": 1685325875, + "narHash": "sha256-tevlLIMPeVNNYPd9UgjHApAUoFAnw9iohqUyj+LPp88=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "b372d7f8d5518aaba8a4058a453957460481afbc", + "type": "github" + }, + "original": { + "owner": "nix-community", + "ref": "release-22.11", + "repo": "home-manager", + "type": "github" + } + }, + "nix-darwin": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1692248770, + "narHash": "sha256-tZeFpETKQGbgnaSIO1AGWD27IyTcBm4D+A9d7ulQ4NM=", + "owner": "LnL7", + "repo": "nix-darwin", + "rev": "511177ffe8226c78c9cf6a92a7b5f2df3684956b", + "type": "github" + }, + "original": { + "owner": "LnL7", + "repo": "nix-darwin", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1688392541, + "narHash": "sha256-lHrKvEkCPTUO+7tPfjIcb7Trk6k31rz18vkyqmkeJfY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "ea4c80b39be4c09702b0cb3b42eab59e2ba4f24b", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-22.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "home-manager": "home-manager", + "nix-darwin": "nix-darwin", + "nixpkgs": "nixpkgs" + } + }, + "utils": { + "locked": { + "lastModified": 1667395993, + "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..e9b375b --- /dev/null +++ b/flake.nix @@ -0,0 +1,43 @@ +{ + inputs = { + nixpkgs = { + url = "github:NixOS/nixpkgs/nixos-22.11"; + }; + home-manager = { + url = "github:nix-community/home-manager/release-22.11"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + nix-darwin = { + url = "github:LnL7/nix-darwin"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = { nixpkgs, home-manager, nix-darwin, ... }@inputs: + { + darwinConfigurations = { + muhammed = nix-darwin.lib.darwinSystem { + inherit inputs; + system = "aarch64-darwin"; + modules = [ + { _module.args = { flakeInputs = inputs; }; } + ./hosts/muhammed/configuration.nix + home-manager.darwinModules.home-manager + ./use-cases/default.nix + ]; + }; + }; + + nixosConfigurations = { + ahmed = nixpkgs.lib.nixosSystem { + system = "x86_64-linux"; + modules = [ + { _module.args = { inherit inputs; }; } + ./hosts/ahmed/configuration.nix + home-manager.nixosModules.home-manager + ./use-cases/default.nix + ]; + }; + }; + }; +} diff --git a/hosts/ahmed/configuration.nix b/hosts/ahmed/configuration.nix new file mode 100644 index 0000000..7d7afcb --- /dev/null +++ b/hosts/ahmed/configuration.nix @@ -0,0 +1,68 @@ +# This file conatins the host-specific configuration for a shitty webserver in +# my closet. + +{ config, pkgs, lib, ... }: + +{ + imports = + [ + ./hardware-configuration.nix + ./ssh.nix + ]; + + # Create the main user + users.users.linus = { + isNormalUser = true; + hashedPassword = "$y$j9T$kNJ5L50Si0sAhdrHyO19I1$YcwXZ46dI.ApLMgZSj7qImq9FrSL0CEUeoJUS8P1103"; + extraGroups = [ "wheel" ]; + shell = pkgs.zsh; + }; + home-manager.users.linus.home.stateVersion = "22.05"; + my.use-cases.development.enable = true; + my.use-cases.sysadmin.enable = true; + # Following are recommended when changing the default shell. + # https://nixos.wiki/wiki/Command_Shell#Changing_default_shelltrue; + programs.zsh.enable = true; + environment.shells = [ pkgs.zsh ]; + + # Use the systemd-boot EFI boot loader. + boot.loader.systemd-boot.enable = true; + boot.loader.grub.device = "/dev/mmcblk0p3"; # FIXME: Do we need to specify GRUB device? + boot.loader.efi.canTouchEfiVariables = false; + + # The hostname should match the containing folder. + networking.hostName = "ahmed"; + + # This host is located in Denmark. + time.timeZone = "Europe/Copenhagen"; + + console = { + font = "sun12x22"; # This font is pretty readable on the cracked display. + keyMap = "dk"; # This host has a Danish keyboard layout. + }; + + # Disable sleep on lid close. + # FIXME: Screen does not appear to turn off when closed. + services.logind.extraConfig = + let + lidSwitchAction = "ignore"; + in + '' + HandleLidSwitch=${lidSwitchAction} + HandleLidSwitchDocked=${lidSwitchAction} + HandleLidSwitchExternalPower=${lidSwitchAction} + ''; + + # Configure WiFi at computer's location. + # FIXME: Don't store in plain text. + networking.wireless.enable = true; + networking.wireless.networks."Rumpenettet_Guest".psk = "Rumpenerglad"; # NOCOMMIT + + # This value determines the NixOS release from which the default + # settings for stateful data, like file locations and database versions + # on your system were taken. It's perfectly fine and recommended to leave + # this value at the release version of the first install of this system. + # Before changing this value read the documentation for this option + # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). + system.stateVersion = "23.05"; # Did you read the comment? +} diff --git a/hosts/ahmed/hardware-configuration.nix b/hosts/ahmed/hardware-configuration.nix new file mode 100644 index 0000000..bae3db1 --- /dev/null +++ b/hosts/ahmed/hardware-configuration.nix @@ -0,0 +1,41 @@ +# 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 + "/installer/scan/not-detected.nix") + ]; + + boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "usb_storage" "sd_mod" "sdhci_pci" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-intel" ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { + device = "/dev/disk/by-label/nixos"; #"/dev/disk/by-uuid/a51aa876-0ba2-437f-b2fd-04ef18bdea79"; + fsType = "ext4"; + }; + + fileSystems."/boot" = + { + device = "/dev/disk/by-label/boot"; + fsType = "vfat"; + }; + + swapDevices = + [{ device = "/dev/disk/by-label/swap"; }]; + + # 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.<interface>.useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.wlp1s0.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; + hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; +} diff --git a/hosts/ahmed/ssh.nix b/hosts/ahmed/ssh.nix new file mode 100644 index 0000000..cedf56e --- /dev/null +++ b/hosts/ahmed/ssh.nix @@ -0,0 +1,19 @@ +# This file configures openSSH on this host. + +{ config, pkgs, lib, ... }: + +{ + # Who is allowed/expected to connect to this machine? + networking.firewall.allowedTCPPorts = [ 22 ]; + services.openssh = { + enable = true; + passwordAuthentication = false; + }; + + users.users = lib.genAttrs ["root" "linus"] (_: { + openssh.authorizedKeys.keys = + [ + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDcmUCfFA/arYpT0zBWoOXcyxN5bgk5cMrWgTIol5RsHB82VzoS+LG3IV4IwBz4QALaCj5DlhfbasGKMkFRgFvLerEtBleIb58RtOXIOf6TIUaqpyHB3h2CjdwrbmyjjWEl9W2BTpadrR5uPr0HoeED8dCFYE5cPjrSELtrYxEW0o1DBJw8bXfpgyYB21loBzrcOhRsrPSaS0gYHZLGY7Av7FGfncVZDLNYL0/pZ/t0UWD6JF+6FgOdGWAuuwSt5WR9DVxGilVG5aFktDB14fNPEBIVf7tkT4/McAihR/u344yaiUWA4bV7w039Ubhn9NdnoBSvGrP6jTy/zDgq5ywFj8aqcdlahxtELNWgxYYrI8HZzvITKo1FU7BOcUN1vNS4npOvyWBl7s3jFCO+R2E/BoyjfsjYTylacpepf26D87U32jNsh39OKdHxRF3/qmMGYa1L7N4M0iT9WFEMCcKB/MMAcHgE25vWPQaY1orU8X8NZPhxjfIVcw1rqcjwCryNwb1ZOMTIEc9kbGiP99MhE7ZA0yvHZfMezeymSwg1kN+iJDTp24gSsFtYuz5vm9lRu/PzfU9lNlp2KHdaLISUouSCCHPgF7zZSWtXa1B920zrAg2Fco8/Iymh+Fa0UNnrbnfyQTgLeNT12SLD4Y5gHimUsuq8tFkxjR6WffmrRw== [email protected]" + ]; + }); +} diff --git a/hosts/muhammed/configuration.nix b/hosts/muhammed/configuration.nix new file mode 100644 index 0000000..2645b80 --- /dev/null +++ b/hosts/muhammed/configuration.nix @@ -0,0 +1,31 @@ +# This file contains the configuration for my Macbook Pro. + +{ pkgs, inputs, lib, ... }: + +{ + # Specify the location of this configuration file. Very meta. + # environment.darwinConfig = inputs.self + "/hosts/muhammed/configuration.nix"; + + # Use the Nix daemon. + services.nix-daemon.enable = true; + + # Set up main account. + users.users.linus = { + description = "Personal user account"; + home = "/Users/linus"; + }; + + # Don't request password for running pmset. + environment.etc."sudoers.d/10-unauthenticated-commands".text = + let + commands = [ + "/usr/bin/pmset" + ]; + in + '' + %admin ALL=(ALL:ALL) NOPASSWD: ${builtins.concatStringsSep ", " commands} + ''; + + # Backwards compatability. Check `darwin-rebuild changelog` before bumping. + system.stateVersion = 4; +} diff --git a/lib/secrets/default.nix b/lib/secrets/default.nix new file mode 100644 index 0000000..401d4a5 --- /dev/null +++ b/lib/secrets/default.nix @@ -0,0 +1,92 @@ +{ pkgs, config, lib, ... }: + +with lib; + +let + cfg = config.my.secrets; + + secret = types.submodule { + options = { + source = mkOption { + type = types.path; + description = "local secret path"; + }; + + dest = mkOption { + type = types.str; + description = "where to write the decrypted secret to"; + }; + + owner = mkOption { + default = "root"; + type = types.str; + description = "who should own the secret"; + }; + + group = mkOption { + default = "root"; + type = types.str; + description = "what group should own the secret"; + }; + + permissions = mkOption { + default = "0400"; + type = types.str; + description = "Permissions expressed as octal."; + }; + }; + }; + + metadata = lib.importTOML ./metadata.toml; + + mkSecretOnDisk = name: + { source, ... }: + pkgs.stdenv.mkDerivation { + name = "${name}-secret"; + phases = "installPhase"; + buildInputs = [ pkgs.rage ]; + installPhase = + let + key = metadata.hosts."${config.networking.hostName}".sshPubKey; + in + '' + rage -a -r '${key}' -o "$out" '${source}' + ''; + }; + + mkService = name: + { source, dest, owner, group, permissions, ... }: { + description = "decrypt secret for ${name}"; + wantedBy = [ "multi-user.target" ]; + + serviceConfig.Type = "oneshot"; + + script = with pkgs; '' + rm -rf ${dest} + "${rage}"/bin/rage -d -i /etc/ssh/ssh_host_ed25519_key -o '${dest}' '${ + mkSecretOnDisk name { inherit source; } + }' + + chown '${owner}':'${group}' '${dest}' + chmod '${permissions}' '${dest}' + ''; + }; +in +{ + options.my.secrets = mkOption { + type = types.attrsOf secret; + description = "secret configuration"; + default = { }; + }; + + config.systemd.services = + let + units = mapAttrs' + (name: info: { + name = "${name}-key"; + value = (mkService name info); + }) + cfg; + in + units; +} diff --git a/lib/secrets/metadata.toml b/lib/secrets/metadata.toml new file mode 100644 index 0000000..a956c31 --- /dev/null +++ b/lib/secrets/metadata.toml @@ -0,0 +1,5 @@ +# This file specifies metadata for each host. + +[hosts.ahmed] +ipAddress = "192.168.68.126" +sshPubKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL3/DjOuKMN18fs/0ZHI3kKLHGytXOFEDBbx+09ZrS3G" diff --git a/use-cases/default.nix b/use-cases/default.nix new file mode 100644 index 0000000..5af2903 --- /dev/null +++ b/use-cases/default.nix @@ -0,0 +1,43 @@ +# This configuration is centered around use cases, rather than profiles. Since +# all of the machines I manage are single-user machines, there's no point in +# creating multiple users. +# +# While the users don't differ, the use cases definitely do. I use some +# machines for homework and gaming, while others are used for web-browsing and +# development. Each use case is a subdirectory with (home-manager) +# configuration options. +# +# Note that e.g. "running a DNS server" is not a use case. That's specified in +# the respective host's `configuration.nix`. + +{ config, lib, flakeInputs, ... }: + +let + inherit (lib) mkEnableOption mkIf; + cfg = config.my.use-cases; +in +{ + options.my.use-cases = { + development.enable = mkEnableOption "development use case"; + sysadmin.enable = mkEnableOption "sysadmin use case"; + }; + + config = { + home-manager.users.linus = { + imports = + (lib.optional cfg.development.enable ./development) ++ + (lib.optional cfg.sysadmin.enable ./sysadmin); + # TODO: Graphical linux config (remember assertion). + + xdg.enable = true; + }; + + # Pass + home-manager.extraSpecialArgs = { + super = config; + inherit flakeInputs; + }; + + home-manager.useGlobalPkgs = true; + }; +} diff --git a/use-cases/development/default.nix b/use-cases/development/default.nix new file mode 100644 index 0000000..a2c3675 --- /dev/null +++ b/use-cases/development/default.nix @@ -0,0 +1,10 @@ +{ config, lib, ... }: + +{ + imports = + [ + ./git.nix + ./neovim.nix + ./zsh.nix + ]; +} diff --git a/use-cases/development/git.nix b/use-cases/development/git.nix new file mode 100644 index 0000000..8df44db --- /dev/null +++ b/use-cases/development/git.nix @@ -0,0 +1,18 @@ +{ ... }: + +{ + programs.git = { + enable = true; + + # Set privacy-respecting user information. + userName = "Linnnus"; + userEmail = "[email protected]"; + }; + + home.shellAliases = { + gs = "git status"; + gd = "git diff"; + gc = "git commit"; + gap = "git add --patch"; + }; +} diff --git a/use-cases/development/neovim.nix b/use-cases/development/neovim.nix new file mode 100644 index 0000000..fb7acf3 --- /dev/null +++ b/use-cases/development/neovim.nix @@ -0,0 +1,60 @@ + +# This file contains the HM configuration options for Neovim for the user +# 'linus'. Don't know him. + +{ pkgs, lib, ... }: + +{ + programs.neovim = { + enable = true; + + # Wrap neovim with LSP dependencies. + # TODO: Build fails with permission error. What? I hate computers... + # package = + # let + # base = pkgs.neovim-unwrapped; + # deps = with pkgs; [ pyright ]; + # neovim' = pkgs.runCommandLocal "neovim-with-deps" { + # buildInputs = [ pkgs.makeWrapper ]; + # } '' + # mkdir $out + # # Link every top-level folder from pkgs.hello to our new target + # ln -s ${base}/* $out + # # Except the bin folder + # rm $out/bin + # mkdir $out/bin + # # We create the bin folder ourselves and link every binary in it + # ln -s ${base}/bin/* $out/bin + # # Except the nvim binary + # rm $out/bin/nvim + # # Because we create this ourself, by creating a wrapper + # makeWrapper ${base}/bin/nvim $out/bin/nvim \ + # --prefix PATH : ${lib.makeBinPath deps} + # ''; + # in + # neovim'; + + plugins = with pkgs.vimPlugins; [ + { + plugin = nvim-lspconfig; + type = "lua"; + config = '' + local lspconfig = require("lspconfig"); + lspconfig.pyright.setup { } + ''; + } + ]; + + # Typing `vi`, `vim`, or `vimdiff` will also run neovim. + viAlias = true; + vimAlias = true; + vimdiffAlias = true; + }; + + # Set Neovim as the default editor. + home.sessionVariables.EDITOR = "nvim"; + home.sessionVariables.VISUAL = "nvim"; + + # Use neovim as man pager. + home.sessionVariables.MANPAGER = "nvim +Man!"; +} diff --git a/use-cases/development/zsh.nix b/use-cases/development/zsh.nix new file mode 100644 index 0000000..4db241d --- /dev/null +++ b/use-cases/development/zsh.nix @@ -0,0 +1,14 @@ +{ pkgs, config, ... }: + +{ + programs.zsh = { + enable = true; + + defaultKeymap = "viins"; + + # Feeble attempt at cleaning up home directory. + # TODO: dotDir = (pathRelativeTo config.xdg.configHome config.home) + "/zsh"; + dotDir = ".config/zsh"; + history.path = config.xdg.cacheHome + "/zsh/history"; + }; +} diff --git a/use-cases/sysadmin/default.nix b/use-cases/sysadmin/default.nix new file mode 100644 index 0000000..1958797 --- /dev/null +++ b/use-cases/sysadmin/default.nix @@ -0,0 +1,16 @@ +# This module defines Home Manager configuration options for the 'sysadmin' use +# case. That is, basic system administration. + +{ pkgs, super, lib, ... }: + +let + inherit (lib) optional; +in +{ + home.packages = with pkgs; [ + tree + jc + jq + # is this not the right it is the one passed to home-manager not nixos ???? 'config'? + ] ++ (optional (!super.my.use-cases.development.enable) vim); +} |