diff options
Diffstat (limited to 'modules/nixos/common')
-rw-r--r-- | modules/nixos/common/console.nix | 6 | ||||
-rw-r--r-- | modules/nixos/common/default.nix | 19 | ||||
-rw-r--r-- | modules/nixos/common/documentation.nix | 31 | ||||
-rw-r--r-- | modules/nixos/common/home-manager.nix | 3 | ||||
-rw-r--r-- | modules/nixos/common/kernel.nix | 39 | ||||
-rw-r--r-- | modules/nixos/common/locale.nix | 24 | ||||
-rw-r--r-- | modules/nixos/common/networking.nix | 108 | ||||
-rw-r--r-- | modules/nixos/common/nix.nix | 39 | ||||
-rw-r--r-- | modules/nixos/common/secrets.nix | 45 | ||||
-rw-r--r-- | modules/nixos/common/security.nix | 29 | ||||
-rw-r--r-- | modules/nixos/common/services.nix | 10 | ||||
-rw-r--r-- | modules/nixos/common/shell.nix | 3 | ||||
-rw-r--r-- | modules/nixos/common/systemd.nix | 22 | ||||
-rw-r--r-- | modules/nixos/common/tmp.nix | 18 | ||||
-rw-r--r-- | modules/nixos/common/users.nix | 19 | ||||
-rw-r--r-- | modules/nixos/common/xdg.nix | 87 |
16 files changed, 502 insertions, 0 deletions
diff --git a/modules/nixos/common/console.nix b/modules/nixos/common/console.nix new file mode 100644 index 0000000..3c73695 --- /dev/null +++ b/modules/nixos/common/console.nix @@ -0,0 +1,6 @@ +{config, ...}: { + console = { + earlySetup = true; + useXkbConfig = config.services.xserver.enable; + }; +} diff --git a/modules/nixos/common/default.nix b/modules/nixos/common/default.nix new file mode 100644 index 0000000..8724c8b --- /dev/null +++ b/modules/nixos/common/default.nix @@ -0,0 +1,19 @@ +_: { + imports = [ + ./console.nix + ./documentation.nix + ./home-manager.nix + ./kernel.nix + ./locale.nix + ./networking.nix + ./nix.nix + ./secrets.nix + ./security.nix + ./services.nix + ./shell.nix + ./systemd.nix + ./tmp.nix + ./users.nix + ./xdg.nix + ]; +} diff --git a/modules/nixos/common/documentation.nix b/modules/nixos/common/documentation.nix new file mode 100644 index 0000000..f909108 --- /dev/null +++ b/modules/nixos/common/documentation.nix @@ -0,0 +1,31 @@ +{ + config, + lib, + pkgs, + this, + ... +}: +with lib; { + config = mkIf this.isHeadful { + documentation = { + dev.enable = true; + nixos.enable = true; + + man.man-db.manualPages = + (pkgs.buildEnv { + name = "man-paths"; + paths = with config; + environment.systemPackages ++ hm.home.packages; + pathsToLink = ["/share/man"]; + extraOutputsToInstall = ["man"]; + ignoreCollisions = true; + }) + .overrideAttrs (_: _: {__contentAddressed = true;}); + }; + + environment.sessionVariables = { + MANOPT = "--no-hyphenation"; + MANPAGER = "${pkgs.less}/bin/less -+F"; + }; + }; +} diff --git a/modules/nixos/common/home-manager.nix b/modules/nixos/common/home-manager.nix new file mode 100644 index 0000000..52f2fd3 --- /dev/null +++ b/modules/nixos/common/home-manager.nix @@ -0,0 +1,3 @@ +{inputs, ...}: { + imports = [inputs.home-manager.nixosModule]; +} diff --git a/modules/nixos/common/kernel.nix b/modules/nixos/common/kernel.nix new file mode 100644 index 0000000..2fc40f9 --- /dev/null +++ b/modules/nixos/common/kernel.nix @@ -0,0 +1,39 @@ +{lib, ...}: +with lib; { + boot = { + # I don't use it even on laptops. It's also /required/ to disable it for + # ZFS[1]. + # [1]: https://github.com/openzfs/zfs/issues/260 + # [1]: https://github.com/openzfs/zfs/issues/12842 + kernelParams = ["hibernate=no"]; + + kernel.sysctl = { + "fs.file-max" = pow 2 17; + "fs.inotify.max_user_watches" = pow 2 19; + "fs.suid_dumpable" = 0; + "kernel.core_uses_pid" = 1; + "kernel.exec-shield" = 1; + "kernel.kptr_restrict" = 1; + "kernel.maps_protect" = 1; + "kernel.msgmax" = pow 2 16; + "kernel.msgmnb" = pow 2 16; + "kernel.pid_max" = pow 2 16; + "kernel.randomize_va_space" = 2; + "kernel.shmall" = pow 2 28; + "kernel.shmmax" = pow 2 28; + "kernel.sysrq" = 0; + "vm.dirty_background_bytes" = pow 2 22; + "vm.dirty_background_ratio" = 5; + "vm.dirty_bytes" = pow 2 22; + "vm.dirty_ratio" = 30; + "vm.min_free_kbytes" = pow 2 16; + "vm.mmap_min_addr" = pow 2 12; + "vm.overcommit_memory" = mkDefault 0; + "vm.overcommit_ratio" = mkDefault 50; + "vm.vfs_cache_pressure" = 50; + }; + }; + + # https://docs.kernel.org/admin-guide/mm/ksm.html + hardware.ksm.enable = true; +} diff --git a/modules/nixos/common/locale.nix b/modules/nixos/common/locale.nix new file mode 100644 index 0000000..62d19f4 --- /dev/null +++ b/modules/nixos/common/locale.nix @@ -0,0 +1,24 @@ +{lib, ...}: +with lib; { + i18n = { + defaultLocale = mkDefault "en_GB.UTF-8"; + supportedLocales = [ + "C.UTF-8/UTF-8" + "en_GB.UTF-8/UTF-8" + "en_US.UTF-8/UTF-8" + "ja_JP.UTF-8/UTF-8" + "ru_RU.UTF-8/UTF-8" + ]; + }; + + services.xserver = { + layout = comcat ["us" "ru"]; + xkbVariant = comcat ["" "phonetic"]; + xkbOptions = comcat [ + "terminate:ctrl_alt_bksp" + "caps:escape" + "compose:menu" + "grp:win_space_toggle" + ]; + }; +} diff --git a/modules/nixos/common/networking.nix b/modules/nixos/common/networking.nix new file mode 100644 index 0000000..6109933 --- /dev/null +++ b/modules/nixos/common/networking.nix @@ -0,0 +1,108 @@ +{ + config, + lib, + pkgs, + this, + ... +}: +with lib; { + # TODO Support multiple interfaces and IP addresses. + networking = mkMerge [ + { + domain = my.domain.shire; + + hostName = this.hostname; + hostId = substring 0 8 (builtins.hashString "md5" this.hostname); + + # Remove default hostname mappings. This is required at least by the current + # implementation of the montoring module. + hosts = { + "127.0.0.2" = mkForce []; + "::1" = mkForce []; + }; + + nameservers = mkDefault dns.const.quad9.default; + + useDHCP = false; + + firewall = { + enable = true; + + rejectPackets = false; + + allowPing = true; + pingLimit = "--limit 1/minute --limit-burst 5"; + + logRefusedConnections = false; + logRefusedPackets = false; + logRefusedUnicastsOnly = false; + logReversePathDrops = false; + }; + } + (let + interface = "eth0"; # This assumes `usePredictableInterfaceNames` is false. + in + mkIf (hasAttr "ipv4" this && hasAttr "ipv6" this) { + usePredictableInterfaceNames = false; # NOTE This can break something! + interfaces.${interface} = { + ipv4.addresses = with this.ipv4; + optional (isString address && isInt prefixLength) { + inherit address prefixLength; + }; + + ipv6.addresses = with this.ipv6; + optional (isString address && isInt prefixLength) { + inherit address prefixLength; + }; + }; + defaultGateway = with this.ipv4; + mkIf (isString gatewayAddress) { + inherit interface; + address = gatewayAddress; + }; + defaultGateway6 = with this.ipv6; + mkIf (isString gatewayAddress) { + inherit interface; + address = gatewayAddress; + }; + }) + (mkIf this.isHeadful { + interfaces = { + eth0.useDHCP = mkDefault true; + wlan0.useDHCP = mkDefault true; + }; + + networkmanager = { + enable = mkDefault true; + wifi.backend = "iwd"; + }; + + wireless = { + enable = false; + iwd.enable = mkDefault true; + userControlled.enable = true; + allowAuxiliaryImperativeNetworks = true; + }; + }) + ]; + + environment.shellAliases = listToAttrs (map + ({ + name, + value, + }: + nameValuePair name "${pkgs.iproute2}/bin/${value}") [ + { + name = "bridge"; + value = "bridge -color=always"; + } + { + name = "ip"; + value = "ip -color=always"; + } + { + name = "tc"; + value = "tc -color=always"; + } + ]); +} diff --git a/modules/nixos/common/nix.nix b/modules/nixos/common/nix.nix new file mode 100644 index 0000000..07136a0 --- /dev/null +++ b/modules/nixos/common/nix.nix @@ -0,0 +1,39 @@ +{ + config, + inputs, + lib, + this, + ... +}: +with lib; let + cfg = config.nixfiles.modules.common.nix; +in { + options.nixfiles.modules.common.nix.allowedUnfreePackages = mkOption { + description = "A list of allowed unfree packages."; + type = with types; listOf str; + default = []; + }; + + config = { + nix.settings.trusted-users = ["@wheel"]; + + nixpkgs = { + config.allowUnfreePredicate = p: elem (getName p) cfg.allowedUnfreePackages; + + overlays = with inputs; [ + agenix.overlay + # nix-minecraft-servers.overlays.default + xmonad-ng.overlays.default + ]; + }; + + system.stateVersion = with builtins; + head (split "\n" (readFile "${inputs.nixpkgs}/.version")); + + environment = { + sessionVariables.NIX_SHELL_PRESERVE_PROMPT = "1"; + localBinInPath = true; + defaultPackages = []; + }; + }; +} diff --git a/modules/nixos/common/secrets.nix b/modules/nixos/common/secrets.nix new file mode 100644 index 0000000..4fcdc61 --- /dev/null +++ b/modules/nixos/common/secrets.nix @@ -0,0 +1,45 @@ +{ + config, + inputs, + lib, + pkgs, + this, + ... +}: +with lib; { + imports = [ + inputs.agenix.nixosModule + (mkAliasOptionModule ["secrets"] ["age" "secrets"]) + ]; + + config = { + age = { + identityPaths = + if this.isHeadful + then ["${config.my.home}/.ssh/id_${my.ssh.type}"] + else + map (attr: attr.path) (filter (attr: attr.type == my.ssh.type) + config.services.openssh.hostKeys); + + # This can be used to auto-add all secrets, thus eleminating the need to + # specify path to each envrypted file. The drawback is that this will + # expose *all* secrets to all machines and try to decrypt them all even on + # machines where the secret will not be used. + # + # secrets = + # let + # secretsSourceDir = "${inputs.self}/age"; + # in + # mapAttrs' + # (name: _: + # nameValuePair name { + # file = "${secretsSourceDir}/${name}"; + # owner = mkDefault my.username; + # group = mkDefault config.my.group; + # }) + # (builtins.readDir secretsSourceDir); + }; + + environment.systemPackages = with pkgs; [agenix]; + }; +} diff --git a/modules/nixos/common/security.nix b/modules/nixos/common/security.nix new file mode 100644 index 0000000..09c5da1 --- /dev/null +++ b/modules/nixos/common/security.nix @@ -0,0 +1,29 @@ +{ + inputs, + lib, + ... +}: +with lib; { + security = { + sudo = { + enable = true; + execWheelOnly = true; + wheelNeedsPassword = false; + # https://mwl.io/archives/1000 + extraConfig = '' + Defaults env_keep += "SSH_CLIENT SSH_CONNECTION SSH_TTY SSH_AUTH_SOCK" + ''; + }; + + polkit = { + enable = true; + # https://wiki.archlinux.org/title/Polkit#Bypass_password_prompt + extraConfig = '' + polkit.addRule(function (action, subject) { + if (subject.isInGroup('wheel')) + return polkit.Result.YES; + }); + ''; + }; + }; +} diff --git a/modules/nixos/common/services.nix b/modules/nixos/common/services.nix new file mode 100644 index 0000000..725502a --- /dev/null +++ b/modules/nixos/common/services.nix @@ -0,0 +1,10 @@ +_: { + services = { + # https://github.com/Irqbalance/irqbalance/issues/54#issuecomment-319245584 + # https://unix.stackexchange.com/questions/710603/should-the-irqbalance-daemon-be-used-on-a-modern-desktop-x86-system + irqbalance.enable = true; + + # https://github.com/NixOS/nixpkgs/issues/135888 + nscd.enableNsncd = true; + }; +} diff --git a/modules/nixos/common/shell.nix b/modules/nixos/common/shell.nix new file mode 100644 index 0000000..5fbc441 --- /dev/null +++ b/modules/nixos/common/shell.nix @@ -0,0 +1,3 @@ +_: { + programs.command-not-found.enable = false; +} diff --git a/modules/nixos/common/systemd.nix b/modules/nixos/common/systemd.nix new file mode 100644 index 0000000..5c7282d --- /dev/null +++ b/modules/nixos/common/systemd.nix @@ -0,0 +1,22 @@ +{pkgs, ...}: { + hm.systemd.user.startServices = "sd-switch"; + + services.journald.extraConfig = '' + SystemMaxUse=5G + ''; + + systemd = let + extraConfig = '' + DefaultTimeoutStartSec=30s + DefaultTimeoutStopSec=15s + ''; + in { + inherit extraConfig; + user = {inherit extraConfig;}; + }; + + environment.sessionVariables = { + SYSTEMD_PAGER = "${pkgs.less}/bin/less"; + SYSTEMD_LESS = "FRSXMK"; + }; +} diff --git a/modules/nixos/common/tmp.nix b/modules/nixos/common/tmp.nix new file mode 100644 index 0000000..d56e2b6 --- /dev/null +++ b/modules/nixos/common/tmp.nix @@ -0,0 +1,18 @@ +_: { + systemd.mounts = [ + { + type = "tmpfs"; + what = "tmpfs"; + where = "/tmp"; + mountConfig.Options = [ + "huge=within_size" + "mode=1777" + "noatime" + "nodev" + "nosuid" + "rw" + "size=25%" + ]; + } + ]; +} diff --git a/modules/nixos/common/users.nix b/modules/nixos/common/users.nix new file mode 100644 index 0000000..22e8023 --- /dev/null +++ b/modules/nixos/common/users.nix @@ -0,0 +1,19 @@ +{lib, ...}: +with lib; { + users = { + mutableUsers = false; + + users = { + root.hashedPassword = "@HASHED_PASSWORD@"; + + ${my.username} = { + isNormalUser = true; + uid = 1000; + description = my.fullname; + inherit (my) hashedPassword; + openssh.authorizedKeys.keys = [my.ssh.key]; + extraGroups = ["wheel"]; + }; + }; + }; +} diff --git a/modules/nixos/common/xdg.nix b/modules/nixos/common/xdg.nix new file mode 100644 index 0000000..8ddf1ac --- /dev/null +++ b/modules/nixos/common/xdg.nix @@ -0,0 +1,87 @@ +{ + config, + lib, + this, + ... +}: +with lib; { + imports = let + withBase = s: ["home-manager" "users" my.username "xdg" s]; + in [ + (mkAliasOptionModule ["dirs" "cache"] (withBase "cacheHome")) + (mkAliasOptionModule ["dirs" "config"] (withBase "configHome")) + (mkAliasOptionModule ["dirs" "data"] (withBase "dataHome")) + (mkAliasOptionModule ["dirs" "state"] (withBase "stateHome")) + (mkAliasOptionModule ["userDirs"] (withBase "userDirs")) + ]; + + hm.xdg = mkMerge [ + { + enable = true; + + userDirs = let + inherit (config.my) home; + tmp = home + "/tmp"; + in { + enable = true; + + desktop = tmp; + documents = "${home}/doc"; + download = tmp; + music = tmp; + pictures = tmp; + publicShare = "${home}/share"; + templates = tmp; + videos = tmp; + }; + } + (mkIf this.isHeadful { + mimeApps = { + enable = true; + defaultApplications = mkMerge (mapAttrsToList + (n: v: genAttrs v (_: ["${n}.desktop"])) + { + emacsclient = [ + "application/json" + "application/vnd.ms-publisher" + "application/x-desktop" + "application/x-shellscript" + "application/x-trash" + "application/x-wine-extension-ini" + "application/xml" + "text/markdown" + "text/plain" + ]; + firefox = [ + "text/html" + "x-scheme-handler/http" + "x-scheme-handler/https" + ]; + imv = [ + "image/bmp" + "image/gif" + "image/jpeg" + "image/jpg" + "image/png" + "image/svg+xml" + "image/tiff" + "image/webp" + ]; + mpv = [ + "audio/aac" + "audio/flac" + "audio/mp3" + "audio/ogg" + "audio/wav" + "audio/webm" + "video/mkv" + "video/mp4" + "video/ogg" + "video/webm" + "video/x-matroska" + ]; + }); + }; + }) + ]; +} |