selfFlake: { lib, config, pkgs, modulesPath, ... }: with lib; let cfg = config.local; in { imports = [ "${modulesPath}/installer/scan/not-detected.nix" ]; options.local = with lib.types; { hostname = mkOption { type = str; }; portable = mkOption { type = bool; }; loader = mkOption { type = enum [ "grub" "systemd-boot" ]; }; canTouchEfiVariables = mkOption { type = bool; }; dhcpInterface = mkOption { type = nullOr str; default = null; }; videoDrivers = mkOption { type = listOf str; }; initrdModules = mkOption { type = listOf str; }; crypt = mkOption { type = submodule { options = { toplevel = mkOption { type = submodule { options = { device = mkOption { type = str; }; target = mkOption { type = str; }; headerFromBoot = mkOption { type = str; }; }; }; }; aux = mkOption { default = []; type = listOf (submodule { options = { device = mkOption { type = str; }; target = mkOption { type = str; }; header = mkOption { type = str; }; keyfile = mkOption { type = str; }; }; }); }; }; }; }; fs = mkOption { type = submodule { options = { boot = mkOption { type = submodule { options = { device = mkOption { type = str; }; }; }; }; sys = mkOption { type = submodule { options = { device = mkOption { type = str; }; ssd = mkOption { type = bool; }; root = mkOption { type = str; }; toplevel = mkOption { type = str; }; }; }; }; hdd = mkOption { type = submodule { options = { device = mkOption { type = str; }; home = mkOption { type = str; }; }; }; }; }; }; }; }; config = { nixpkgs.overlays = [ selfFlake.overlay ]; # 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 = "21.11"; # Did you read the comment? nix = { package = pkgs.nixFlakes; extraOptions = '' experimental-features = nix-command flakes ''; }; boot = { # !!! tmpOnTmpfs = true; loader = (if cfg.loader == "grub" then { grub = { enable = true; device = "nodev"; efiSupport = true; }; } else { systemd-boot.enable = true; }) // { efi = { inherit (cfg) canTouchEfiVariables; }; }; initrd = let crypt = cfg.crypt.toplevel; headerPathEscaped = escapeShellArg "/initrd-boot/${crypt.headerFromBoot}"; in { availableKernelModules = cfg.initrdModules; supportedFilesystems = [ "vfat" ]; preDeviceCommands = '' mkdir -p `dirname ${headerPathEscaped}` touch ${headerPathEscaped} ''; preLVMCommands = optionalString cfg.portable '' sleep 2 #TODO ''; postMountCommands = let fromRoot = path: escapeShellArg "/mnt-root/${path}"; auxOpen = aux: '' cryptsetup -v open \ --header ${fromRoot aux.header} \ --key-file ${fromRoot aux.keyfile} \ ${aux.device} ${aux.target} ''; in concatStringsSep "\n" (map auxOpen cfg.crypt.aux); luks.devices."${crypt.target}" = { inherit (crypt) device; header = "/initrd-boot/${crypt.headerFromBoot}"; preLVM = false; preOpenCommands = '' mount -o ro -t vfat ${escapeShellArg cfg.fs.boot.device} /initrd-boot ''; postOpenCommands = '' umount /initrd-boot ''; }; #network = { # enable = true; # ssh = { # enable = true; # port = 2234; # }; #}; }; }; hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware; fileSystems = let inherit (cfg) fs; btrfs = { device, subvol, isSys }: { inherit device; fsType = "btrfs"; options = let ssd = optional (isSys && fs.sys.ssd) "ssd"; in [ "noatime" "compress=zstd" "subvol=${subvol}" ] ++ ssd; }; in { "/" = btrfs { inherit (fs.sys) device; subvol = fs.sys.root; isSys = true; }; "/toplevel" = btrfs { inherit (fs.sys) device; subvol = fs.sys.toplevel; isSys = true; }; "/hdd" = btrfs { inherit (fs.hdd) device; subvol = "/"; isSys = false; }; "/home" = btrfs { inherit (fs.hdd) device; subvol = fs.hdd.home; isSys = false; }; "/boot" = { inherit (fs.boot) device; fsType = "vfat"; options = [ "noatime" "umask=027" ]; }; }; time.timeZone = "America/Costa_Rica"; networking = { hostName = cfg.hostname; useDHCP = false; interfaces = mkIf (cfg.dhcpInterface != null) { "${cfg.dhcpInterface}".useDHCP = true; }; wireguard.enable = true; }; i18n.defaultLocale = "es_CR.UTF-8"; sound.enable = true; hardware.pulseaudio.enable = true; services.xserver = { enable = true; videoDrivers = cfg.videoDrivers ++ [ "modesetting" "fbdev" ]; libinput.enable = true; displayManager.startx.enable = true; }; security.pam = { oath = { usersFile = "/var/trust/users.oath"; digits = 6; window = 30; }; services.sshd.oathAuth = true; }; services.openssh = { enable = true; openFirewall = false; ports = [ 2234 ]; forwardX11 = true; permitRootLogin = "no"; passwordAuthentication = false; hostKeys = [ { bits = 4096; path = "/etc/ssh/ssh_host_rsa_key"; type = "rsa"; } { path = "/etc/ssh/ssh_host_ed25519_key"; type = "ed25519"; } #TODO: Desfasar, inseguro { path = "/etc/ssh/ssh_host_ecdsa_key"; type = "ecdsa"; } ]; }; networking.firewall.allowedTCPPorts = [ 2234 ]; programs = { dconf.enable = true; zsh.enable = true; }; environment.pathsToLink = [ "/share/zsh" ]; users.users = { ale = { isNormalUser = true; uid = 1000; group = "ale"; extraGroups = [ "users" "wheel" ]; shell = pkgs.zsh; }; tutorias = { isNormalUser = true; uid = 1004; group = "tutorias"; extraGroups = [ "users" ]; shell = pkgs.zsh; }; }; users.groups = { ale.gid = 1001; tutorias.gid = 1007; }; }; }