summaryrefslogtreecommitdiff
path: root/modules/nixos/common
diff options
context:
space:
mode:
Diffstat (limited to 'modules/nixos/common')
-rw-r--r--modules/nixos/common/console.nix6
-rw-r--r--modules/nixos/common/default.nix19
-rw-r--r--modules/nixos/common/documentation.nix31
-rw-r--r--modules/nixos/common/home-manager.nix3
-rw-r--r--modules/nixos/common/kernel.nix39
-rw-r--r--modules/nixos/common/locale.nix24
-rw-r--r--modules/nixos/common/networking.nix108
-rw-r--r--modules/nixos/common/nix.nix39
-rw-r--r--modules/nixos/common/secrets.nix45
-rw-r--r--modules/nixos/common/security.nix29
-rw-r--r--modules/nixos/common/services.nix10
-rw-r--r--modules/nixos/common/shell.nix3
-rw-r--r--modules/nixos/common/systemd.nix22
-rw-r--r--modules/nixos/common/tmp.nix18
-rw-r--r--modules/nixos/common/users.nix19
-rw-r--r--modules/nixos/common/xdg.nix87
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"
+ ];
+ });
+ };
+ })
+ ];
+}