diff options
Diffstat (limited to '')
58 files changed, 1517 insertions, 740 deletions
diff --git a/modules/acme.nix b/modules/acme.nix index 6a75818..9a2f3f1 100644 --- a/modules/acme.nix +++ b/modules/acme.nix @@ -5,11 +5,14 @@ let in { imports = [ - (mkAliasOptionModule [ "certs" ] [ - "security" - "acme" - "certs" - ]) + (mkAliasOptionModule + [ "certs" ] + [ + "security" + "acme" + "certs" + ] + ) ]; options.nixfiles.modules.acme = { diff --git a/modules/android.nix b/modules/android.nix index 363bd6c..65710ca 100644 --- a/modules/android.nix +++ b/modules/android.nix @@ -1,12 +1,11 @@ { config, lib, ... }: -with lib; let cfg = config.nixfiles.modules.android; in { - options.nixfiles.modules.android.enable = mkEnableOption "support for Android devices"; + options.nixfiles.modules.android.enable = lib.mkEnableOption "support for Android devices"; - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { programs.adb.enable = true; my.extraGroups = [ "adbusers" ]; diff --git a/modules/chromium.nix b/modules/chromium.nix index c7842d5..bc34ecd 100644 --- a/modules/chromium.nix +++ b/modules/chromium.nix @@ -18,10 +18,11 @@ in programs.chromium = { enable = true; - package = pkgs.ungoogled-chromium; + # package = pkgs.ungoogled-chromium; extensions = [ { id = "cjpalhdlnbpafiamejdnhcphjbkeiagm"; } # uBlock Origin + { id = "nkbihfbeogaeaoehlefnkodbefgpgknn"; } # MetaMask ]; }; }; diff --git a/modules/common/ark.nix b/modules/common/ark.nix index 1e43ef8..007e209 100644 --- a/modules/common/ark.nix +++ b/modules/common/ark.nix @@ -4,32 +4,34 @@ lib, ... }: -with lib; let cfg = config.nixfiles.modules.ark; in { imports = [ inputs.impermanence.nixosModules.impermanence - (mkAliasOptionModule [ "ark" ] [ - "nixfiles" - "modules" - "ark" - ]) + (lib.mkAliasOptionModule + [ "ark" ] + [ + "nixfiles" + "modules" + "ark" + ] + ) ]; options.nixfiles.modules.ark = let - mkListOfAnythingOption = mkOption { - type = with types; listOf anything; # Assumed to be matching with the upstream type. + mkListOfAnythingOption = lib.mkOption { + type = with lib.types; listOf anything; # Assumed to be matching with the upstream type. default = [ ]; }; in { - enable = mkEnableOption "persistent storage support via impermanence"; + enable = lib.mkEnableOption "persistent storage support via impermanence"; - path = mkOption { - type = types.str; + path = lib.mkOption { + type = lib.types.str; default = "/ark"; }; @@ -41,7 +43,7 @@ in # }; }; - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { environment.persistence.${cfg.path} = { hideMounts = true; enableDebugging = false; diff --git a/modules/common/default.nix b/modules/common/default.nix index ef9fb18..38094e7 100644 --- a/modules/common/default.nix +++ b/modules/common/default.nix @@ -1 +1,4 @@ -{ lib, ... }: with lib; { imports = attrValues (modulesIn ./.); } +{ lib, ... }: +{ + imports = lib.attrValues (lib.modulesIn ./.); +} diff --git a/modules/common/documentation.nix b/modules/common/documentation.nix index 33e767c..f9e0fcb 100644 --- a/modules/common/documentation.nix +++ b/modules/common/documentation.nix @@ -5,7 +5,6 @@ this, ... }: -with lib; { config = { hm.manual = { @@ -34,7 +33,7 @@ with lib; environment.variables = { MANOPT = "--no-hyphenation"; - MANPAGER = "${getExe pkgs.less} -+F"; + MANPAGER = "${lib.getExe pkgs.less} -+F"; }; }; } diff --git a/modules/common/home-manager.nix b/modules/common/home-manager.nix index f2fc8a8..118fc0e 100644 --- a/modules/common/home-manager.nix +++ b/modules/common/home-manager.nix @@ -4,15 +4,17 @@ lib, ... }: -with lib; { imports = [ inputs.home-manager.nixosModule - (mkAliasOptionModule [ "hm" ] [ - "home-manager" - "users" - my.username - ]) + (lib.mkAliasOptionModule + [ "hm" ] + [ + "home-manager" + "users" + lib.my.username + ] + ) ]; hm = { diff --git a/modules/common/kernel.nix b/modules/common/kernel.nix index ddc4f62..f7e520a 100644 --- a/modules/common/kernel.nix +++ b/modules/common/kernel.nix @@ -1,29 +1,28 @@ { lib, ... }: -with lib; { boot.kernel.sysctl = { - "fs.file-max" = pow 2 17; - "fs.inotify.max_user_watches" = pow 2 19; + "fs.file-max" = lib.pow 2 17; + "fs.inotify.max_user_watches" = lib.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.msgmax" = lib.pow 2 16; + "kernel.msgmnb" = lib.pow 2 16; + "kernel.pid_max" = lib.pow 2 16; "kernel.randomize_va_space" = 2; - "kernel.shmall" = pow 2 28; - "kernel.shmmax" = pow 2 28; + "kernel.shmall" = lib.pow 2 28; + "kernel.shmmax" = lib.pow 2 28; "kernel.sysrq" = 0; - "vm.dirty_background_bytes" = pow 2 22; + "vm.dirty_background_bytes" = lib.pow 2 22; "vm.dirty_background_ratio" = 5; - "vm.dirty_bytes" = pow 2 22; + "vm.dirty_bytes" = lib.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.min_free_kbytes" = lib.pow 2 16; + "vm.mmap_min_addr" = lib.pow 2 12; + "vm.overcommit_memory" = lib.mkDefault 0; + "vm.overcommit_ratio" = lib.mkDefault 50; "vm.vfs_cache_pressure" = 50; }; diff --git a/modules/common/locale.nix b/modules/common/locale.nix index 372b69b..acd1ecd 100644 --- a/modules/common/locale.nix +++ b/modules/common/locale.nix @@ -51,7 +51,6 @@ with lib; "caps:escape" "compose:menu" "grp:win_space_toggle" - "terminate:ctrl_alt_bksp" ]; }; } diff --git a/modules/common/networking.nix b/modules/common/networking.nix index f681deb..2e9c218 100644 --- a/modules/common/networking.nix +++ b/modules/common/networking.nix @@ -5,47 +5,35 @@ this, ... }: -with lib; let cfg = config.nixfiles.modules.common.networking; + + interface = "eth0"; # This assumes `usePredictableInterfaceNames` is false. in { - options.nixfiles.modules.common.networking.onlyDefault = mkEnableOption "custom networking settings"; + options.nixfiles.modules.common.networking.onlyDefault = + lib.mkEnableOption "custom networking settings"; - config = mkIf (!cfg.onlyDefault) { + config = lib.mkIf (!cfg.onlyDefault) { ark.directories = with config.networking; - optional networkmanager.enable "/etc/NetworkManager/system-connections" - ++ optional wireless.iwd.enable "/var/lib/iwd"; + lib.optional networkmanager.enable "/etc/NetworkManager/system-connections" + ++ lib.optional wireless.iwd.enable "/var/lib/iwd"; - networking = mkMerge [ + networking = lib.mkMerge [ { - domain = my.domain.shire; + domain = lib.my.domain.shire; hostName = this.hostname; - hostId = substring 0 8 (builtins.hashString "md5" this.hostname); + hostId = lib.substring 0 8 (builtins.hashString "md5" this.hostname); # Remove default hostname mappings. This is required at least by the # current implementation of the monitoring module. hosts = { - "127.0.0.2" = mkForce [ ]; - "::1" = mkForce [ ]; + "127.0.0.2" = lib.mkForce [ ]; + "::1" = lib.mkForce [ ]; }; - # There's no way[1] to configure DNS server priority in - # systemd-resolved. The only solution for dealing with a broken VPN - # connection is to delete /etc/systemd/resolved.conf and restart the - # systemd-resolved service. Otherwise I'll just end up with a random - # server from the list most of the time because systemd-resolved - # "conveniently" will manage server priority for me... - # - # [1]: https://askubuntu.com/questions/1116732/how-do-i-list-dns-server-order-in-systemd-resolve - # [2]: https://github.com/systemd/systemd/issues/6076 - nameservers = with my.configurations.manwe.wireguard; [ - ipv6.address - ipv4.address - ]; - useDHCP = false; nftables.enable = true; @@ -63,70 +51,101 @@ in logRefusedUnicastsOnly = false; logReversePathDrops = false; }; + + usePredictableInterfaceNames = 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; }; + (lib.mkIf (lib.hasAttr "ipv4" this) { + interfaces.${interface}.ipv4.addresses = + with this.ipv4; + lib.optional (lib.isString address && lib.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; - + defaultGateway = + with this.ipv4; + lib.mkIf (lib.isString gatewayAddress) { + inherit interface; + address = gatewayAddress; + }; + }) + (lib.mkIf (lib.hasAttr "ipv6" this) { + interfaces.${interface}.ipv6.addresses = + with this.ipv6; + lib.optional (lib.isString address && lib.isInt prefixLength) { + inherit address prefixLength; + }; + defaultGateway6 = + with this.ipv6; + lib.mkIf (lib.isString gatewayAddress) { + inherit interface; + address = gatewayAddress; + }; + }) + (lib.mkIf this.isHeadless { + nameservers = with lib.my.configurations.manwe.wireguard; [ + ipv6.address + ipv4.address + ]; + }) + (lib.mkIf this.isHeadful { networkmanager = { - enable = mkDefault true; - unmanaged = [ - "bridge" - "ethernet" - "loopback" - "wireguard" - ]; - plugins = mkForce [ ]; + enable = true; wifi.backend = "iwd"; + dns = "none"; }; wireless = { enable = false; - iwd.enable = mkDefault true; + iwd.enable = lib.mkDefault true; userControlled.enable = true; allowAuxiliaryImperativeNetworks = true; }; + + resolvconf.extraConfig = '' + append_nameservers='127.0.0.1' + ''; }) ]; - services.resolved = { - llmnr = "false"; - dnsovertls = "opportunistic"; - dnssec = "allow-downgrade"; - fallbackDns = dns.mkDoT dns.const.quad9.ecs; - }; + services = lib.mkMerge [ + (lib.mkIf this.isHeadless { + resolved = { + enable = true; + llmnr = "false"; + dnsovertls = "opportunistic"; + dnssec = "allow-downgrade"; + fallbackDns = lib.dns.mkDoT lib.dns.const.quad9.ecs; + }; + }) + (lib.mkIf this.isHeadful { + resolved.enable = false; + + dnscrypt-proxy2 = { + enable = true; + settings = { + ipv4_servers = true; + ipv6_servers = false; + dnscrypt_servers = true; + doh_servers = true; + odoh_servers = false; + require_dnssec = true; + require_nolog = true; + require_nofilter = true; + + disabled_server_names = [ + "cloudflare" + "cloudflare-ipv6" + ]; + + cache = true; + cache_size = lib.pow 2 13; + }; + }; + }) + ]; environment = { - shellAliases = listToAttrs ( - map ({ name, value }: nameValuePair name "${pkgs.iproute2}/bin/${value}") [ + shellAliases = lib.listToAttrs ( + map ({ name, value }: lib.nameValuePair name "${pkgs.iproute2}/bin/${value}") [ { name = "bridge"; value = "bridge -color=always"; diff --git a/modules/common/nix.nix b/modules/common/nix.nix index 58d572f..2054185 100644 --- a/modules/common/nix.nix +++ b/modules/common/nix.nix @@ -72,6 +72,11 @@ in keep-going = true; + experimental-features = [ + "fetch-tree" + "pipe-operators" + ]; + trusted-users = [ my.username ]; substituters = [ @@ -80,12 +85,12 @@ in "https://nix-community.cachix.org" "https://numtide.cachix.org" ]; - trusted-substituters = [ - "https://cache.tvl.su" - ]; trusted-public-keys = [ "cache.tvl.su:kjc6KOMupXc1vHVufJUoDUYeLzbwSr9abcAKdn/U1Jk=" ]; + + # https://github.com/NixOS/nix/issues/6901 + fallback = true; }; }; @@ -95,6 +100,8 @@ in overlays = [ inputs.self.overlays.default ]; }; + programs.nh.enable = this.isHeadful; + environment = { defaultPackages = [ ]; systemPackages = diff --git a/modules/common/secrets.nix b/modules/common/secrets.nix index 03a2eeb..77dee44 100644 --- a/modules/common/secrets.nix +++ b/modules/common/secrets.nix @@ -10,10 +10,13 @@ with lib; { imports = [ inputs.agenix.nixosModules.default - (mkAliasOptionModule [ "secrets" ] [ - "age" - "secrets" - ]) + (mkAliasOptionModule + [ "secrets" ] + [ + "age" + "secrets" + ] + ) ]; config = { @@ -23,7 +26,10 @@ with lib; else map (attr: attr.path) (filter (attr: attr.type == my.ssh.type) config.services.openssh.hostKeys); - environment.systemPackages = with pkgs; [ agenix ]; + environment.systemPackages = with pkgs; [ + age + agenix + ]; nixpkgs.overlays = [ inputs.agenix.overlays.default ]; }; diff --git a/modules/common/shell/default.nix b/modules/common/shell/default.nix index 4ae41d8..cacb411 100644 --- a/modules/common/shell/default.nix +++ b/modules/common/shell/default.nix @@ -5,14 +5,13 @@ this, ... }: -with lib; let cfg = config.nixfiles.modules.common.shell; in { - options.nixfiles.modules.common.shell.aliases = mkOption { + options.nixfiles.modules.common.shell.aliases = lib.mkOption { description = "An attribute set of shell aliases."; - type = with types; attrsOf str; + type = with lib.types; attrsOf str; default = { }; }; @@ -24,8 +23,8 @@ in initExtra = let - aliasCompletions = concatStringsSep "\n" ( - mapAttrsToList (name: _: "complete -F _complete_alias ${name}") cfg.aliases + aliasCompletions = lib.concatStringsSep "\n" ( + lib.mapAttrsToList (name: _: "complete -F _complete_alias ${name}") cfg.aliases ); in '' @@ -45,7 +44,7 @@ in source "${./functions.bash}" - source "${getExe' pkgs.complete-alias "complete_alias"}" + source "${lib.getExe' pkgs.complete-alias "complete_alias"}" ${aliasCompletions} # https://github.com/garabik/grc?tab=readme-ov-file#bash @@ -73,19 +72,18 @@ in ]; shellAliases = - listToAttrs ( + lib.listToAttrs ( map ( { name, value }: - nameValuePair name ( - with pkgs; + lib.nameValuePair name ( let pkg = if this.isHeadful then (pkgs.coreutils.overrideAttrs ( _: super: { patches = (super.patches or [ ]) ++ [ - (fetchpatch { + (pkgs.fetchpatch { url = "https://raw.githubusercontent.com/jarun/advcpmv/1e2b1c6b74fa0974896bf94604279a3f74b37a63/advcpmv-0.9-9.5.patch"; hash = "sha256-LRfb4heZlAUKiXl/hC/HgoqeGMxCt8ruBYZUrbzSH+Y="; }) @@ -93,24 +91,24 @@ in } )) else - coreutils; + pkgs.coreutils; in - "${getExe' pkg "coreutils"} --coreutils-prog=${value}" + "${lib.getExe' pkg "coreutils"} --coreutils-prog=${value}" ) ) ( let mkAlias = { - name ? head command, + name ? lib.head command, command, }: { inherit name; - value = concatStringsSep " " command; + value = lib.concatStringsSep " " command; }; - progressBar = optionalString this.isHeadful "--progress-bar"; + progressBar = lib.optionalString this.isHeadful "--progress-bar"; in [ (mkAlias { @@ -171,7 +169,7 @@ in ] ) ) - // (genAttrs [ + // (lib.genAttrs [ "grep" "egrep" "fgrep" diff --git a/modules/common/stylix.nix b/modules/common/stylix.nix index f1e0417..f17cb4c 100644 --- a/modules/common/stylix.nix +++ b/modules/common/stylix.nix @@ -10,11 +10,14 @@ with lib; { imports = [ inputs.stylix.nixosModules.stylix - (mkAliasOptionModule [ "colors" ] [ - "lib" - "stylix" - "colors" - ]) + (mkAliasOptionModule + [ "colors" ] + [ + "lib" + "stylix" + "colors" + ] + ) ]; options.nixfiles.modules.common.stylix.fonts.extraPackages = mkOption { diff --git a/modules/common/systemd.nix b/modules/common/systemd.nix index f832518..996096e 100644 --- a/modules/common/systemd.nix +++ b/modules/common/systemd.nix @@ -1,5 +1,6 @@ { config, + lib, ... }: { @@ -35,8 +36,16 @@ user = { inherit extraConfig; }; + + suppressedSystemUnits = lib.optionals config.nixfiles.modules.ark.enable [ + "systemd-machine-id-commit.service" + ]; }; + boot.initrd.systemd.suppressedUnits = lib.optionals config.nixfiles.modules.ark.enable [ + "systemd-machine-id-commit.service" + ]; + environment.variables = { SYSTEMD_PAGERSECURE = "1"; SYSTEMD_PAGER = "less"; diff --git a/modules/common/users.nix b/modules/common/users.nix index b8aca28..e0811b7 100644 --- a/modules/common/users.nix +++ b/modules/common/users.nix @@ -5,11 +5,14 @@ let in { imports = [ - (mkAliasOptionModule [ "my" ] [ - "users" - "users" - my.username - ]) + (mkAliasOptionModule + [ "my" ] + [ + "users" + "users" + my.username + ] + ) ]; ark.directories = [ home ]; diff --git a/modules/common/xdg.nix b/modules/common/xdg.nix index 0b807b7..df7d624 100644 --- a/modules/common/xdg.nix +++ b/modules/common/xdg.nix @@ -4,7 +4,6 @@ this, ... }: -with lib; let cfg = config.nixfiles.modules.common.xdg; in @@ -20,44 +19,44 @@ in ]; in [ - (mkAliasOptionModule [ + (lib.mkAliasOptionModule [ "dirs" "cache" ] (withBase "cacheHome")) - (mkAliasOptionModule [ + (lib.mkAliasOptionModule [ "dirs" "config" ] (withBase "configHome")) - (mkAliasOptionModule [ + (lib.mkAliasOptionModule [ "dirs" "data" ] (withBase "dataHome")) - (mkAliasOptionModule [ + (lib.mkAliasOptionModule [ "dirs" "state" ] (withBase "stateHome")) - (mkAliasOptionModule [ "userDirs" ] (withBase "userDirs")) + (lib.mkAliasOptionModule [ "userDirs" ] (withBase "userDirs")) ]; options.nixfiles.modules.common.xdg = { - cacheHome = mkOption { - type = types.str; + cacheHome = lib.mkOption { + type = lib.types.str; default = "${config.hm.home.homeDirectory}/.cache"; }; - configHome = mkOption { - type = types.str; + configHome = lib.mkOption { + type = lib.types.str; default = "${config.hm.home.homeDirectory}/.config"; }; - dataHome = mkOption { - type = types.str; + dataHome = lib.mkOption { + type = lib.types.str; default = "${config.hm.home.homeDirectory}/.local/share"; }; - stateHome = mkOption { - type = types.str; + stateHome = lib.mkOption { + type = lib.types.str; default = "${config.hm.home.homeDirectory}/.local/state"; }; - userDirs = mkOption { - type = types.attrs; + userDirs = lib.mkOption { + type = lib.types.attrs; default = let inherit (config.my) home; @@ -76,9 +75,9 @@ in videos = tmp; }; }; - defaultApplications = mkOption { + defaultApplications = lib.mkOption { description = "Default applications."; - type = with types; attrsOf (listOf str); + type = with lib.types; attrsOf (listOf str); default = { }; }; }; @@ -89,7 +88,7 @@ in sounds.enable = this.isHeadful; }; - hm.xdg = mkMerge [ + hm.xdg = lib.mkMerge [ (with cfg; { enable = true; @@ -99,11 +98,11 @@ in inherit stateHome; inherit userDirs; }) - (mkIf this.isHeadful { + (lib.mkIf this.isHeadful { mimeApps = { enable = true; - defaultApplications = mkMerge ( - mapAttrsToList (n: v: genAttrs v (_: [ "${n}.desktop" ])) cfg.defaultApplications + defaultApplications = lib.mkMerge ( + lib.mapAttrsToList (n: v: lib.genAttrs v (_: [ "${n}.desktop" ])) cfg.defaultApplications ); }; }) diff --git a/modules/curl.nix b/modules/curl.nix index 6895262..3c318fc 100644 --- a/modules/curl.nix +++ b/modules/curl.nix @@ -20,7 +20,7 @@ in ''; environment.systemPackages = with pkgs; [ - curl + curlHTTP3 (writeShellScriptBin "0x0" '' url="https://0x0.st" form="file=@" diff --git a/modules/docker.nix b/modules/docker.nix index 62dc095..330d417 100644 --- a/modules/docker.nix +++ b/modules/docker.nix @@ -5,14 +5,13 @@ pkgs, ... }: -with lib; let cfg = config.nixfiles.modules.docker; in { - options.nixfiles.modules.docker.enable = mkEnableOption "Docker"; + options.nixfiles.modules.docker.enable = lib.mkEnableOption "Docker"; - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { assertions = [ { assertion = cfg.enable -> !config.nixfiles.modules.podman.enable; @@ -20,12 +19,14 @@ in } ]; + ark.directories = [ "/var/lib/docker" ]; + nixfiles.modules.common.shell.aliases.d = "docker"; secrets.containers-auth = { file = "${inputs.self}/secrets/containers-auth"; path = "${config.my.home}/.docker/config.json"; - owner = my.username; + owner = lib.my.username; inherit (config.my) group; }; diff --git a/modules/emacs/default.nix b/modules/emacs/default.nix index 455f710..71bc24c 100644 --- a/modules/emacs/default.nix +++ b/modules/emacs/default.nix @@ -231,9 +231,8 @@ in (mu4e-drafts-folder . "/${name}/${folders.drafts}") (mu4e-trash-folder . "/${name}/${folders.trash}") (mu4e-refile-folder . "/${name}/Archive") - ${ - optionalString (signature.showSignature != "none") - ''(mu4e-compose-signature . "${replaceStrings [ "\n" ] [ "\\n" ] signature.text}")'' + ${optionalString (signature.showSignature != "none") + ''(mu4e-compose-signature . "${replaceStrings [ "\n" ] [ "\\n" ] signature.text}")'' } (+mu4e-personal-addresses . (${personalAddresses}))) t) diff --git a/modules/emacs/doom/config.el b/modules/emacs/doom/config.el index 85fe4a9..a212e17 100644 --- a/modules/emacs/doom/config.el +++ b/modules/emacs/doom/config.el @@ -260,3 +260,118 @@ (setq-local company-idle-delay 0.1)))) :init (setq! hledger-input-buffer-height 20)) + +;; +;;; LLM +;; + +(use-package! gptel + :config + (setq! gptel-model 'codegemma:7b + gptel-backend (gptel-make-ollama "ollama" + :host "eonwe.shire.net:11434" + :stream t + :models '(dagbs/qwen2.5-coder-7b-instruct-abliterated:latest + qwen2.5-coder:7b + deepseek-coder-v2:16b + codegemma:7b + codellama:7b + llama3.2:3b + mistral:7b)))) + +(use-package! ellama + :init + (setq! ellama-naming-scheme 'ellama-generate-name-by-time) + :config + (require 'llm-ollama) + (setq! ellama-provider (make-llm-ollama + :scheme "http" + :host "eonwe.shire.net" + :port 11434 + :chat-model "llama3.2:3b" + :embedding-model "nomic-embed-text:latest") + ellama-providers '(("llama" . (make-llm-ollama + :scheme "http" + :host "eonwe.shire.net" + :port 11434 + :chat-model "llama3.2:3b" + :embedding-model "nomic-embed-text:latest")) + ("codellama" . (make-llm-ollama + :scheme "http" + :host "eonwe.shire.net" + :port 11434 + :chat-model "codellama:7b" + :embedding-model "nomic-embed-text:latest")) + ("qwen" . (make-llm-ollama + :scheme "http" + :host "eonwe.shire.net" + :port 11434 + :chat-model "qwen2.5:7b" + :embedding-model "nomic-embed-text:latest")) + ("qwen-coder" . (make-llm-ollama + :scheme "http" + :host "eonwe.shire.net" + :port 11434 + :chat-model "qwen2.5-coder:7b" + :embedding-model "nomic-embed-text:latest")) + ("qwen-coder-instruct" . (make-llm-ollama + :scheme "http" + :host "eonwe.shire.net" + :port 11434 + :chat-model "dagbs/qwen2.5-coder-7b-instruct-abliterated:latest" + :embedding-model "nomic-embed-text:latest")) + ("gemma" . (make-llm-ollama + :scheme "http" + :host "eonwe.shire.net" + :port 11434 + :chat-model "gemma2:9b" + :embedding-model "nomic-embed-text:latest")) + ("codegemma" . (make-llm-ollama + :scheme "http" + :host "eonwe.shire.net" + :port 11434 + :chat-model "codegemma:7b" + :embedding-model "nomic-embed-text:latest")) + ("mistral" . (make-llm-ollama + :scheme "http" + :host "eonwe.shire.net" + :port 11434 + :chat-model "mistral:7b" + :embedding-model "nomic-embed-text:latest")) + ("hermes" . (make-llm-ollama + :scheme "http" + :host "eonwe.shire.net" + :port 11434 + :chat-model "hermes3:8b" + :embedding-model "nomic-embed-text:latest")) + ("deepseek" . (make-llm-ollama + :scheme "http" + :host "eonwe.shire.net" + :port 11434 + :chat-model "deepseek-coder-v2:16b" + :embedding-model "nomic-embed-text:latest"))) + ellama-translation-provider (make-llm-ollama + :scheme "http" + :host "eonwe.shire.net" + :port 11434 + :chat-model "qwen2.5:7b" + :embedding-model "nomic-embed-text:latest") + ellama-summarization-provider (make-llm-ollama + :scheme "http" + :host "eonwe.shire.net" + :port 11434 + :chat-model "mistral:7b" + :embedding-model "nomic-embed-text:latest"))) + +(use-package! magit-gptcommit + :after magit + :config + (require 'llm-ollama) + (setq! magit-gptcommit-llm-provider (make-llm-ollama + :scheme "http" + :host "eonwe.shire.net" + :port 11434 + :chat-model "dagbs/qwen2.5-coder-7b-instruct-abliterated:latest" + :embedding-model "nomic-embed-text:latest")) + + (magit-gptcommit-status-buffer-setup)) diff --git a/modules/emacs/doom/init.el b/modules/emacs/doom/init.el index 8575c3f..3845fd6 100644 --- a/modules/emacs/doom/init.el +++ b/modules/emacs/doom/init.el @@ -48,7 +48,7 @@ :checkers syntax - (spell +everywhere +icons) + (spell +flyspell +everywhere +icons) grammar :tools diff --git a/modules/emacs/doom/packages.el b/modules/emacs/doom/packages.el index fb521bc..a7085da 100644 --- a/modules/emacs/doom/packages.el +++ b/modules/emacs/doom/packages.el @@ -8,18 +8,23 @@ (package! org-roam-ui) +;; https://github.com/doomemacs/doomemacs/issues/8166 +;; https://github.com/org-roam/org-roam/issues/2485 +(unpin! emacsql) +(package! emacsql + :recipe (:host github :repo "magit/emacsql") + :pin "491105a01f58bf0b346cbc0254766c6800b229a2") + (package! nickel-mode) (package! hledger-mode) (package! sops - :recipe (:host github - :repo "djgoku/sops")) + :recipe (:host github :repo "djgoku/sops")) -(unpin! ansible) -(package! ansible - :recipe (:host gitlab - :repo "emacs-ansible/emacs-ansible")) +(package! gptel) +(package! ellama) +(package! magit-gptcommit) ;; (package! tvl ;; :recipe (:host nil diff --git a/modules/firefox/addons.json b/modules/firefox/addons.json index 5c6a090..c194368 100644 --- a/modules/firefox/addons.json +++ b/modules/firefox/addons.json @@ -7,9 +7,6 @@ "slug": "consent-o-matic" }, { - "slug": "darkreader" - }, - { "slug": "furiganaize" }, { @@ -19,9 +16,16 @@ "slug": "languagetool" }, { + "pname": "metamask", + "slug": "ether-metamask" + }, + { "slug": "no-pdf-download" }, { + "slug": "plasma-integration" + }, + { "pname": "rikaichamp", "slug": "10ten-ja-reader" }, @@ -32,6 +36,9 @@ "slug": "skip-redirect" }, { + "slug": "switchyomega" + }, + { "slug": "ublock-origin" }, { @@ -40,8 +47,5 @@ }, { "slug": "violentmonkey" - }, - { - "slug": "switchyomega" } ] diff --git a/modules/firefox/addons.nix b/modules/firefox/addons.nix index e416a3f..5a08549 100644 --- a/modules/firefox/addons.nix +++ b/modules/firefox/addons.nix @@ -5,10 +5,10 @@ { "bitwarden" = buildFirefoxXpiAddon { pname = "bitwarden"; - version = "2024.10.0"; + version = "2024.10.1"; addonId = "{446900e4-71c2-419f-a6a7-df9c091e268b}"; - url = "https://addons.mozilla.org/firefox/downloads/file/4363548/bitwarden_password_manager-2024.10.0.xpi"; - sha256 = "9ea9428444870a74ae1999d77eb12d97a45275c85e83d6afdcbc4597fa3eccfb"; + url = "https://addons.mozilla.org/firefox/downloads/file/4371752/bitwarden_password_manager-2024.10.1.xpi"; + sha256 = "7b7357ddce2756dc536b86b5c14139ec09731c1c114ac82807c60fba3ced12a5"; meta = with lib; { homepage = "https://bitwarden.com"; description = "At home, at work, or on the go, Bitwarden easily secures all your passwords, passkeys, and sensitive information."; @@ -52,27 +52,6 @@ platforms = platforms.all; }; }; - "darkreader" = buildFirefoxXpiAddon { - pname = "darkreader"; - version = "4.9.94"; - addonId = "addon@darkreader.org"; - url = "https://addons.mozilla.org/firefox/downloads/file/4359254/darkreader-4.9.94.xpi"; - sha256 = "251c4e7d0a30c0cab006803600e59ab92dcc0c606429740d42677846d4c9ccd6"; - meta = with lib; { - homepage = "https://darkreader.org/"; - description = "Dark mode for every website. Take care of your eyes, use dark theme for night and daily browsing."; - license = licenses.mit; - mozPermissions = [ - "alarms" - "contextMenus" - "storage" - "tabs" - "theme" - "<all_urls>" - ]; - platforms = platforms.all; - }; - }; "furiganaize" = buildFirefoxXpiAddon { pname = "furiganaize"; version = "0.7.2"; @@ -144,6 +123,36 @@ platforms = platforms.all; }; }; + "metamask" = buildFirefoxXpiAddon { + pname = "metamask"; + version = "12.0.6"; + addonId = "webextension@metamask.io"; + url = "https://addons.mozilla.org/firefox/downloads/file/4342782/ether_metamask-12.0.6.xpi"; + sha256 = "a66e20bbe5ded1b9408420e4c2ffc82369cc3bfd27350afe25f2c0ef6b26ff3b"; + meta = with lib; { + description = "Ethereum Browser Extension"; + mozPermissions = [ + "storage" + "unlimitedStorage" + "clipboardWrite" + "http://localhost:8545/" + "https://*.infura.io/" + "https://*.codefi.network/" + "https://*.cx.metamask.io/" + "https://chainid.network/chains.json" + "https://lattice.gridplus.io/*" + "activeTab" + "webRequest" + "*://*.eth/" + "notifications" + "file://*/*" + "http://*/*" + "https://*/*" + "*://connect.trezor.io/*/popup.html" + ]; + platforms = platforms.all; + }; + }; "no-pdf-download" = buildFirefoxXpiAddon { pname = "no-pdf-download"; version = "1.0.6"; @@ -162,6 +171,29 @@ platforms = platforms.all; }; }; + "plasma-integration" = buildFirefoxXpiAddon { + pname = "plasma-integration"; + version = "1.9.1"; + addonId = "plasma-browser-integration@kde.org"; + url = "https://addons.mozilla.org/firefox/downloads/file/4298512/plasma_integration-1.9.1.xpi"; + sha256 = "394a3525185679dd5430d05f980ab6be19d96557560fe86208c21a8807669b33"; + meta = with lib; { + homepage = "http://kde.org"; + description = "Multitask efficiently by controlling browser functions from the Plasma desktop."; + license = licenses.gpl3; + mozPermissions = [ + "nativeMessaging" + "notifications" + "storage" + "downloads" + "tabs" + "<all_urls>" + "contextMenus" + "*://*/*" + ]; + platforms = platforms.all; + }; + }; "redirector" = buildFirefoxXpiAddon { pname = "redirector"; version = "3.5.3"; @@ -187,10 +219,10 @@ }; "rikaichamp" = buildFirefoxXpiAddon { pname = "rikaichamp"; - version = "1.21.1"; + version = "1.22.0"; addonId = "{59812185-ea92-4cca-8ab7-cfcacee81281}"; - url = "https://addons.mozilla.org/firefox/downloads/file/4355635/10ten_ja_reader-1.21.1.xpi"; - sha256 = "81d85cfdc03cb0c921cac84547e7a7a539af11ff9a81dd901b3f3bfa67ba45f1"; + url = "https://addons.mozilla.org/firefox/downloads/file/4371439/10ten_ja_reader-1.22.0.xpi"; + sha256 = "d6f3197b7e3383f2723b9376d93e03fe515e5c610f9c0723d9618b10d3cc4bf1"; meta = with lib; { homepage = "https://github.com/birchill/10ten-ja-reader/"; description = "Quickly translate Japanese by hovering over words. Formerly released as Rikaichamp."; @@ -258,10 +290,10 @@ }; "ublock-origin" = buildFirefoxXpiAddon { pname = "ublock-origin"; - version = "1.60.0"; + version = "1.61.0"; addonId = "uBlock0@raymondhill.net"; - url = "https://addons.mozilla.org/firefox/downloads/file/4359936/ublock_origin-1.60.0.xpi"; - sha256 = "e2cda9b2a1b0a7f6e5ef0da9f87f28df52f8560587ba2e51a3003121cfb81600"; + url = "https://addons.mozilla.org/firefox/downloads/file/4382536/ublock_origin-1.61.0.xpi"; + sha256 = "e6fd55b799a568c66c10892a8f22428e6773fe16d7466ce9dee2952f224b203d"; meta = with lib; { homepage = "https://github.com/gorhill/uBlock#ublock-origin"; description = "Finally, an efficient wide-spectrum content blocker. Easy on CPU and memory."; @@ -318,10 +350,10 @@ }; "violentmonkey" = buildFirefoxXpiAddon { pname = "violentmonkey"; - version = "2.26.0"; + version = "2.28.0"; addonId = "{aecec67f-0d10-4fa7-b7c7-609a2db280cf}"; - url = "https://addons.mozilla.org/firefox/downloads/file/4362578/violentmonkey-2.26.0.xpi"; - sha256 = "47b61fd463602a38bf67591ab94c60d3f1a02ad4f81b9a8a3de97d5461b2e12e"; + url = "https://addons.mozilla.org/firefox/downloads/file/4379821/violentmonkey-2.28.0.xpi"; + sha256 = "30bc3db14194a5197e4721d419123f3a02b9c6f3e94646724aa991137121bcba"; meta = with lib; { homepage = "https://violentmonkey.github.io/"; description = "Userscript support for browsers, open source."; diff --git a/modules/firefox/default.nix b/modules/firefox/default.nix index b7e47b6..ee45434 100644 --- a/modules/firefox/default.nix +++ b/modules/firefox/default.nix @@ -41,28 +41,6 @@ in mkCssWithRoot = css: mkMerge [ - # https://github.com/tinted-theming/base24/blob/master/styling.md - (with config.colors.withHashtag; '' - :root { - --black: ${base01}; - --red: ${base08}; - --green: ${base0B}; - --yellow: ${base09}; - --blue: ${base0D}; - --magenta: ${base0E}; - --cyan: ${base0C}; - --white: ${base06}; - --bright-black: ${base02}; - --bright-red: ${base12}; - --bright-green: ${base14}; - --bright-yellow: ${base13}; - --bright-blue: ${base16}; - --bright-magenta: ${base17}; - --bright-cyan: ${base15}; - --bright-white: ${base07}; - --background: ${base00}; - --foreground: ${base05}; - '') ( let mapFonts = concatMapStringsSep ", " (font: ''"${font}"''); @@ -70,6 +48,7 @@ in in with config.fonts.fontconfig.defaultFonts; '' + :root { --serif-font-family: ${mapFonts serif}, serif; --serif-font-size: ${size}; --sans-serif-font-family: ${mapFonts sansSerif}, sans-serif; @@ -124,9 +103,9 @@ in with addons; [ consent-o-matic - darkreader furiganaize languagetool + metamask no-pdf-download redirector rikaichamp @@ -136,6 +115,7 @@ in user-agent-switcher violentmonkey ] + ++ optional config.nixfiles.modules.kde.enable plasma-integration ++ optional config.nixfiles.modules.ipfs.enable ipfs-companion; search = { @@ -222,7 +202,7 @@ in "GitHub" = { urls = [ { template = "https://github.com/search?q={searchTerms}"; } ]; - icon = getIcon "https://github.githubassets.com/favicons/favicon-dark.svg" "sha256-qu/d9ftvsntplFuxw9RFL8BpI9b2g5b6xfeGw6Ekh6w="; + icon = getIcon "https://github.githubassets.com/favicons/favicon.svg" "sha256-apV3zU9/prdb3hAlr4W5ROndE4g3O1XMum6fgKwurmA="; definedAliases = [ "@github" "@gh" @@ -373,7 +353,7 @@ in "SourceHut" = { urls = [ { template = "https://sr.ht/projects?search={searchTerms}"; } ]; - icon = getIcon "https://sr.ht/static/logo.png" "sha256-NBzKZhqE9//zVJlOwYiwyW/jRFh8+nS2YvC3zMCQ1fU="; + icon = getIcon "https://sourcehut.org/logo.svg" "sha256-tX7ppdGitgaVFCI1aGc41n6er7srHi+GMv5+lpFvYBc="; definedAliases = [ "@sourcehut" "@srht" @@ -421,6 +401,10 @@ in name = "Bookmarks Toolbar"; toolbar = true; bookmarks = with config.nixfiles.modules; [ + { + name = "XUL"; + url = "chrome://browser/content/browser.xhtml"; + } (mkIf syncthing.enable { name = "Syncthing"; url = "http://${config.services.syncthing.guiAddress}"; @@ -529,6 +513,7 @@ in "browser.tabs.warnOnClose" = false; "browser.tabs.warnOnCloseOtherTabs" = false; "browser.tabs.warnOnOpen" = false; + "browser.theme.dark-private-windows" = false; "browser.toolbars.bookmarks.visibility" = "newtab"; "browser.translations.enable" = false; "browser.urlbar.decodeURLsOnCopy" = true; @@ -551,6 +536,7 @@ in "media.autoplay.blocking_policy" = 2; "media.autoplay.default" = 5; "media.hardwaremediakeys.enabled" = false; + "media.videocontrols.picture-in-picture.video-toggle.enabled" = false; "reader.parse-on-load.enabled" = false; "toolkit.legacyUserProfileCustomizations.stylesheets" = true; }; diff --git a/modules/firefox/userChrome.css b/modules/firefox/userChrome.css index 80d1f7a..aeb1c8f 100644 --- a/modules/firefox/userChrome.css +++ b/modules/firefox/userChrome.css @@ -1,23 +1,9 @@ @-moz-document url(chrome://browser/content/browser.xhtml) { - /* - *** - * Tabbar - *** - */ - - /* - * Apply colours and fonts. - */ - .tabbrowser-tab { - color: var(--background-alt) !important; + #urlbar { font-family: var(--sans-serif-font-family) !important; font-size: var(--sans-serif-font-size) !important; } - .tabbrowser-tab[visuallyselected="true"] { - background: var(--background) !important; - color: var(--foreground) !important; - } /* * Not sure why is this shit even exists... @@ -34,32 +20,6 @@ } /* - * Disable borders and margins. - */ - #tabbrowser-tabs { - border-inline-start: 0 !important; - /* padding-inline-start: 0 !important; */ - margin-inline-start: 0 !important; - } - #tabbrowser-tabs[haspinnedtabs]:not([positionpinnedtabs]) - > #tabbrowser-arrowscrollbox - > .tabbrowser-tab[first-visible-unpinned-tab] { - margin-inline-start: none !important; - } - .tabbrowser-tab::after, - .tabbrowser-tab::before { - border: none !important; - } - - /* - * Make tabs backgroundless. - */ - /* .tab-background, */ - /* .tab-line { */ - /* display: none !important; */ - /* } */ - - /* * Stretch tabs to the max by default. */ .tabbrowser-tab[fadein]:not([pinned="true"]) { @@ -67,14 +27,6 @@ } /* - * Fix favicon location. - */ - .tab-icon-image { - margin-inline-end: 10px !important; - margin-top: 0px !important; - } - - /* * "C-t" exists. */ #tabs-newtab-button, @@ -90,64 +42,13 @@ } /* - *** - * Navbar & urlbar. - *** - */ - - /* - * Remove padding between urlbar and side elements. + * Remove padding between URL bar and side elements. */ #customizableui-special-spring1, #customizableui-special-spring2 { display: none !important; } - #urlbar { - background: var(--background) !important; - color: var(--foreground) !important; - font-family: var(--sans-serif-font-family) !important; - font-size: var(--sans-serif-font-size) !important; - border-color: transparent !important; - } - - /* #urlbar:not(:-moz-lwtheme):not([focused="true"]) > #urlbar-background, */ - /* #searchbar:not(:-moz-lwtheme):not(:focus-within) { */ - /* border: none !important; */ - /* } */ - - /* #urlbar *|*.textbox-input::-moz-placeholder { */ - /* color: transparent !important; */ - /* } */ - - /* .urlbar-icon:hover:not([disabled]), */ - /* .urlbar-icon-wrapper:hover:not([disabled]) { */ - /* background-color: var(--background-alt) !important; */ - /* } */ - - /* #urlbar-background { */ - /* background: transparent !important; */ - /* } */ - - /* .urlbarView-tags, */ - /* .urlbarView-url, */ - /* .urlbarView-title:not(:empty) ~ .urlbarView-action { */ - /* font-size: var(--sans-serif-font-size) !important; */ - /* } */ - - .urlbarView-row[label="Firefox Suggest"] { - margin-block-start: 0 !important; - } - .urlbarView-row[label="Firefox Suggest"]::before { - display: none !important; - } - - /* - *** - * Misc. - *** - */ - /* * Call indicator that some "designer" decided to make floating and impossible * to hide. @@ -157,16 +58,41 @@ } /* - * Disable some context menu entries. - */ - #context-navigation { + * Context menu. Both for tabs and page. + */ + #context-bookmarklink, + #context-inspect-a11y, + #context-navigation, + #context-pocket, + #context-print-selection, + #context-searchselect, + #context-selectall, + #context-sendimage, + #context-sendlinktodevice, + #context-sendpagetodevice, + #context-viewsource, + #context_bookmarkTab, + #context_moveTabOptions, + #context_selectAllTabs, + #context_sendTabToDevice, + menuseparator { display: none !important; } /* - * Remove dumb websites that Mozilla is forced to include. + * Unify margins for tab browser. */ - .search-one-offs { - display: none !important; + #tabbrowser-tabs { + margin-inline-start: 0 !important; + border-inline-start: 0 !important; + padding-inline-start: calc( + var(--tab-overflow-pinned-tabs-width) + 2px + ) !important; + margin-inline-start: 0 !important; + } + #tabbrowser-tabs[haspinnedtabs]:not([positionpinnedtabs])[orient="horizontal"] + > #tabbrowser-arrowscrollbox + > .tabbrowser-tab:nth-child(1 of :not([pinned], [hidden])) { + margin-inline-start: 0 !important; } } diff --git a/modules/firefox/userContent.css b/modules/firefox/userContent.css index 96bb529..a009ad8 100644 --- a/modules/firefox/userContent.css +++ b/modules/firefox/userContent.css @@ -1,16 +1,11 @@ @-moz-document media-document(all) { body { background-image: none !important; - background-color: var(--background) !important; + background-color: var(--background-color-box) !important; } } @-moz-document regexp("about:(blank|home|newtab|privatebrowsing|welcome)") { - html, - body { - background: var(--background) !important; - } - body { display: none !important; } @@ -265,7 +260,8 @@ #highlight__main-container, .global-footer, .global-navigation, - .global-registration-buttons { + .global-registration-buttons, + .notifications-placeholder { display: none !important; } diff --git a/modules/games/gamemode.nix b/modules/games/gamemode.nix index eb485f8..4e57a8b 100644 --- a/modules/games/gamemode.nix +++ b/modules/games/gamemode.nix @@ -1,13 +1,12 @@ { config, lib, ... }: -with lib; let cfg = config.nixfiles.modules.games.gamemode; in { - options.nixfiles.modules.games.gamemode.enable = mkEnableOption "Feral GameMode"; + options.nixfiles.modules.games.gamemode.enable = lib.mkEnableOption "Feral GameMode"; - config = mkIf cfg.enable { - hm.xdg.configFile."gamemode.ini".text = generators.toINI { } { general.softrealtime = "auto"; }; + config = lib.mkIf cfg.enable { + hm.xdg.configFile."gamemode.ini".text = lib.generators.toINI { } { general.softrealtime = "auto"; }; programs.gamemode.enable = true; }; diff --git a/modules/games/lutris.nix b/modules/games/lutris.nix index 62fe521..d926971 100644 --- a/modules/games/lutris.nix +++ b/modules/games/lutris.nix @@ -22,10 +22,12 @@ in (lutris.override { extraPkgs = _: [ vkBasalt - wine + wine-staging winetricks ]; }) + wine-staging + winetricks ]; }; } diff --git a/modules/games/minecraft.nix b/modules/games/minecraft.nix index f93a139..f849360 100644 --- a/modules/games/minecraft.nix +++ b/modules/games/minecraft.nix @@ -5,7 +5,6 @@ pkgs, ... }: -with lib; let cfg = config.nixfiles.modules.games.minecraft; in @@ -13,28 +12,30 @@ in imports = [ inputs.minecraft.nixosModules.minecraft-servers ]; options.nixfiles.modules.games.minecraft = { - client.enable = mkEnableOption "Minecraft client"; + client.enable = lib.mkEnableOption "Minecraft client"; server = { - enable = mkEnableOption "Minecraft server"; + enable = lib.mkEnableOption "Minecraft server"; - port = mkOption { + port = lib.mkOption { description = "Server port."; - type = types.port; + type = lib.types.port; default = 25565; }; - memory = mkOption { + memory = lib.mkOption { description = "Amount of RAM to allocate."; - type = types.str; + type = lib.types.str; default = "2G"; }; }; }; - config = mkMerge [ - (mkIf cfg.client.enable { hm.home.packages = [ pkgs.prismlauncher ]; }) - (mkIf cfg.server.enable { - nixfiles.modules.common.nix.allowedUnfreePackages = [ "minecraft-server" ]; + config = lib.mkMerge [ + (lib.mkIf cfg.client.enable { hm.home.packages = [ pkgs.prismlauncher ]; }) + (lib.mkIf cfg.server.enable { + nixfiles.modules.common.nix.allowedUnfreePackages = [ + "minecraft-server" # proprietary + ]; ark.directories = [ config.services.minecraft-servers.dataDir ]; @@ -50,7 +51,7 @@ in # https://api.papermc.io/v2/projects/paper # https://github.com/Infinidoge/nix-minecraft/blob/master/pkgs/paper-servers/lock.json - package = pkgs.paperServers.paper-1_21_47; + package = pkgs.minecraftServers.paper-1_21_3; serverProperties = { # motd = ""; @@ -71,7 +72,7 @@ in }; jvmOpts = - (concatStringsSep " " [ + (lib.concatStringsSep " " [ "-Xms${cfg.server.memory}" "-Xmx${cfg.server.memory}" "--add-modules=jdk.incubator.vector" # Required by some plugins. diff --git a/modules/games/steam-run.nix b/modules/games/steam-run.nix index be06c78..9e3c962 100644 --- a/modules/games/steam-run.nix +++ b/modules/games/steam-run.nix @@ -2,72 +2,49 @@ config, lib, pkgs, - pkgsRev, ... }: -with lib; let cfg = config.nixfiles.modules.games.steam-run; in { options.nixfiles.modules.games.steam-run = { - enable = mkEnableOption "native Steam runtime"; + enable = lib.mkEnableOption "native Steam runtime"; quirks = { - blackIsleStudios = mkEnableOption "fixes for games from Black Isle Studios"; - cryptOfTheNecrodancer = mkEnableOption ''fixes for "Crypt of the NecroDancer" issues''; - mountAndBladeWarband = mkEnableOption ''fixes for "Mount & Blade: Warband" issues''; + blackIsleStudios = lib.mkEnableOption "fixes for games from Black Isle Studios"; + cryptOfTheNecrodancer = lib.mkEnableOption ''fixes for "Crypt of the NecroDancer" issues''; + mountAndBladeWarband = lib.mkEnableOption ''fixes for "Mount & Blade: Warband" issues''; }; }; - config = mkIf cfg.enable { - nixfiles.modules.games.steam.enable = true; + config = lib.mkIf cfg.enable { + nixfiles.modules = { + games.steam.enable = true; - hm.home.packages = with pkgs; [ - (steam.override { + common.nix.allowedUnfreePackages = lib.optionals cfg.quirks.mountAndBladeWarband [ + "fmod" # proprietary + ]; + }; + + hm.home.packages = [ + (pkgs.steam.override { + extraEnv.MANGOHUD = 1; extraLibraries = _: - with cfg.quirks; - optional blackIsleStudios openssl_1_0_0 - ++ optional cryptOfTheNecrodancer (pkgsRev "d1c3fea7ecbed758168787fe4e4a3157e52bc808" "sha256-3muuhz3fjtF1bz32UXOYCho51E8JSeEwo2iDZFQJdXo=") - .flac - ++ optionals mountAndBladeWarband [ - (glew.overrideAttrs ( - _: super: - let - opname = super.pname; - in - rec { - pname = "${opname}-steam-run-fix"; - inherit (super) version; - src = fetchurl { - url = "mirror://sourceforge/${opname}/${opname}-${version}.tgz"; - hash = "sha256-BN6R5+Z2MDm8EZQAlc2cf4gLq6ghlqd2X3J6wFqZPJU="; - }; - } - )) - (fmodex.overrideAttrs ( - _: super: - let - opname = super.pname; - in - rec { - pname = "${opname}-steam-run-fix"; - inherit (super) version; - installPhase = - let - libPath = makeLibraryPath [ - alsa-lib - libpulseaudio - stdenv.cc.cc - ]; - in - '' - install -Dm755 api/lib/libfmodex64-${version}.so $out/lib/libfmodex64.so - patchelf --set-rpath ${libPath} $out/lib/libfmodex64.so - ''; - } - )) + lib.optionals cfg.quirks.blackIsleStudios [ + pkgs.openssl_1_0_0 + ] + ++ lib.optionals cfg.quirks.cryptOfTheNecrodancer [ + (lib.packages.fromRev "d1c3fea7ecbed758168787fe4e4a3157e52bc808" "sha256-3muuhz3fjtF1bz32UXOYCho51E8JSeEwo2iDZFQJdXo=") + .flac + ] + ++ lib.optionals cfg.quirks.mountAndBladeWarband [ + (pkgs.fmodex.overrideAttrs (oldAttrs: { + postInstall = '' + ln -s $out/lib/libfmodex64.so $out/lib/libfmodex-${oldAttrs.version}.so + ''; + })) ]; }).run ]; diff --git a/modules/git/default.nix b/modules/git/default.nix index b618a57..f370ae6 100644 --- a/modules/git/default.nix +++ b/modules/git/default.nix @@ -8,38 +8,37 @@ this, ... }: -with lib; let cfg = config.nixfiles.modules.git; in { options.nixfiles.modules.git = { - client.enable = mkEnableOption "Git client"; + client.enable = lib.mkEnableOption "Git client"; server = { - enable = mkEnableOption "Git server"; + enable = lib.mkEnableOption "Git server"; - domain = mkOption { + domain = lib.mkOption { description = "Domain name sans protocol scheme."; - type = with types; nullOr str; + type = with lib.types; nullOr str; default = "git.${config.networking.domain}"; }; - package = mkOption { + package = lib.mkOption { description = "Package."; - type = types.package; + type = lib.types.package; default = pkgs.cgit; }; }; }; - config = mkMerge [ - (mkIf cfg.client.enable { + config = lib.mkMerge [ + (lib.mkIf cfg.client.enable { secrets = { glab-cli-config = { file = "${inputs.self}/secrets/glab-cli-config"; path = "${config.dirs.config}/glab-cli/config.yml"; - owner = my.username; + owner = lib.my.username; }; # NOTE SSO requires relogin every day, so keeping persistent auth tokens # doesn't work. @@ -51,7 +50,7 @@ in hut = { file = "${inputs.self}/secrets/hut"; path = "${config.dirs.config}/hut/config"; - owner = my.username; + owner = lib.my.username; }; }; @@ -73,10 +72,10 @@ in package = if this.isHeadful then pkgs.gitFull else pkgs.gitMinimal; - userName = my.username; - userEmail = my.email; + userName = lib.my.username; + userEmail = lib.my.email; signing = { - inherit (my.pgp) key; + inherit (lib.my.pgp) key; signByDefault = true; }; @@ -102,48 +101,46 @@ in }; submodule.recurse = true; sendemail = rec { - smtpServer = my.domain.shire; - smtpUser = "${my.username}@${smtpServer}"; + smtpServer = lib.my.domain.shire; + smtpUser = "${lib.my.username}@${smtpServer}"; smtpEncryption = "ssl"; smtpServerPort = 465; annotate = true; confirm = "always"; }; column.ui = "auto"; - github.user = my.username; - gitlab.user = my.username; + github.user = lib.my.username; + gitlab.user = lib.my.username; } - // mapAttrs' (name: value: nameValuePair ''url "git@${value}:"'' { insteadOf = "${name}:"; }) { + // lib.mapAttrs' (n: v: lib.nameValuePair ''url "git@${v}:"'' { insteadOf = "${n}:"; }) { "bitbucket" = "bitbucket.com"; "codeberg" = "codeberg.org"; "github" = "github.com"; "gitlab" = "gitlab.com"; "sourcehut" = "git.sr.ht"; } - // - mapAttrs' (name: values: nameValuePair ''url "https://${values}/"'' { insteadOf = "${name}:"; }) - { - "alpine" = "gitlab.alpinelinux.org"; - "clan" = "git.clan.lol"; - "debian" = "salsa.debian.org"; - "freedesktop" = "gitlab.freedesktop.org"; - "gnome" = "gitlab.gnome.org"; - "haskell" = "gitlab.haskell.org"; - "homotopic" = "gitlab.homotopic.tech"; - "horizon" = "gitlab.horizon-haskell.net"; - "kde" = "invent.kde.org"; - "nixca" = "gitlab.nixca.dev"; - "notabug" = "notabug.org"; - "opencode" = "opencode.net"; - "syndicate" = "git.syndicate-lang.org"; - "torproject" = "gitlab.torproject.org"; - "videolan" = "code.videolan.org"; - }; + // lib.mapAttrs' (n: v: lib.nameValuePair ''url "https://${v}/"'' { insteadOf = "${n}:"; }) { + "alpine" = "gitlab.alpinelinux.org"; + "clan" = "git.clan.lol"; + "debian" = "salsa.debian.org"; + "freedesktop" = "gitlab.freedesktop.org"; + "gnome" = "gitlab.gnome.org"; + "haskell" = "gitlab.haskell.org"; + "homotopic" = "gitlab.homotopic.tech"; + "horizon" = "gitlab.horizon-haskell.net"; + "kde" = "invent.kde.org"; + "nixca" = "gitlab.nixca.dev"; + "notabug" = "notabug.org"; + "opencode" = "opencode.net"; + "syndicate" = "git.syndicate-lang.org"; + "torproject" = "gitlab.torproject.org"; + "videolan" = "code.videolan.org"; + }; aliases = let - git = getExe config.hm.programs.git.package; - curl = getExe pkgs.curl; + git = lib.getExe config.hm.programs.git.package; + curl = lib.getExe pkgs.curl; in { amend = "commit --amend"; @@ -189,181 +186,178 @@ in }; }; }) - (mkIf cfg.server.enable ( - with cfg.server; - { - ark.directories = [ config.services.gitolite.dataDir ]; + (lib.mkIf cfg.server.enable { + ark.directories = [ config.services.gitolite.dataDir ]; - nixfiles.modules.nginx = { - enable = true; - virtualHosts.${domain}.locations = { }; - }; + nixfiles.modules.nginx = { + enable = true; + virtualHosts.${cfg.server.domain}.locations = { }; + }; - services = { - cgit.${domain} = { - enable = true; + services = { + cgit.${cfg.server.domain} = { + enable = true; - package = pkgs.cgit-pink; + package = pkgs.cgit-pink; - # We make gitolite repos readable by the common group. - user = "git"; - group = "git"; + # We make gitolite repos readable by the common group. + user = "git"; + group = "git"; - scanPath = "${config.services.gitolite.dataDir}/repositories"; + scanPath = "${config.services.gitolite.dataDir}/repositories"; - settings = { - root-title = "git.azahi.cc"; - root-desc = "British scientists have discovered that using GitHub frequently is harmful to one's mental health, especially GitHub Actions..."; + settings = { + root-title = "git.azahi.cc"; + root-desc = "British scientists have discovered that using GitHub frequently is harmful to one's mental health, especially GitHub Actions..."; - footer = "${pkgs.writeText "cgit-footer" '' - <p style="text-align: center;">Consider giving <a href="https://nixos.org">Nix/NixOS</a> a try! <3</p> - ''}"; + footer = "${pkgs.writeText "cgit-footer" '' + <p style="text-align: center;">Consider giving <a href="https://nixos.org">Nix/NixOS</a> a try! <3</p> + ''}"; - about-filter = "${pkgs.writeScript "cgit-about-filter.sh" '' - #!${pkgs.bash}/bin/sh - filename=$1 - case "$filename" in - *.md) - exec ${pkgs.pandoc}/bin/pandoc -f markdown -t html - ;; - *.org) - exec ${pkgs.pandoc}/bin/pandoc -f org -t html - ;; - *) - echo "<pre>" - ${pkgs.coreutils}/bin/cat - echo "</pre>" - ;; - esac - ''}"; - source-filter = "${package}/lib/cgit/filters/syntax-highlighting.py"; - commit-filter = "${package}/lib/cgit/filters/commit-links.sh"; + about-filter = "${pkgs.writeScript "cgit-about-filter.sh" '' + #!${pkgs.bash}/bin/sh + filename=$1 + case "$filename" in + *.md) + exec ${pkgs.pandoc}/bin/pandoc -f markdown -t html + ;; + *.org) + exec ${pkgs.pandoc}/bin/pandoc -f org -t html + ;; + *) + echo "<pre>" + ${pkgs.coreutils}/bin/cat + echo "</pre>" + ;; + esac + ''}"; + source-filter = "${cfg.server.package}/lib/cgit/filters/syntax-highlighting.py"; + commit-filter = "${cfg.server.package}/lib/cgit/filters/commit-links.sh"; - readme = [ - ":README" - ":readme.md" - ":readme.org" - ]; + readme = [ + ":README" + ":readme.md" + ":readme.org" + ]; - clone-url = "https://$HTTP_HOST/$CGIT_REPO_URL"; + clone-url = "https://$HTTP_HOST/$CGIT_REPO_URL"; - enable-blame = true; - enable-commit-graph = true; - enable-follow-links = true; - enable-git-config = true; - enable-gitweb-owner = true; - enable-html-serving = true; - enable-http-clone = true; - enable-index-links = false; - enable-index-owner = false; - enable-log-filecount = true; - enable-log-linecount = true; - enable-subject-links = true; - enable-tree-linenumbers = true; + enable-blame = true; + enable-commit-graph = true; + enable-follow-links = true; + enable-git-config = true; + enable-gitweb-owner = true; + enable-html-serving = true; + enable-http-clone = true; + enable-index-links = false; + enable-index-owner = false; + enable-log-filecount = true; + enable-log-linecount = true; + enable-subject-links = true; + enable-tree-linenumbers = true; - branch-sort = "age"; - repository-sort = "age"; + branch-sort = "age"; + repository-sort = "age"; - remove-suffix = true; + remove-suffix = true; - logo = "/logo.gif"; - logo-link = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"; - }; + logo = "/logo.gif"; + logo-link = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"; }; + }; - gitolite = { - enable = true; - user = "git"; - group = "git"; - adminPubkey = my.ssh.key; - extraGitoliteRc = '' - # This allows cgit to scan repositories while running under a - # different user. - $RC{UMASK} = 0027; + gitolite = { + enable = true; + user = "git"; + group = "git"; + adminPubkey = lib.my.ssh.key; + extraGitoliteRc = '' + # This allows cgit to scan repositories while running under a + # different user. + $RC{UMASK} = 0027; - # This allows hiding repositories via "cgit.ignore"[1]. - # - # [1]: https://www.omarpolo.com/post/cgit-gitolite.html - $RC{GIT_CONFIG_KEYS} = '.*'; - ''; - }; + # This allows hiding repositories via "cgit.ignore"[1]. + # + # [1]: https://www.omarpolo.com/post/cgit-gitolite.html + $RC{GIT_CONFIG_KEYS} = '.*'; + ''; + }; - nginx.virtualHosts.${domain}.locations = - let - extraHead = '' - ${libNginx.config.appendHead [ - ''<meta name="go-import" content="$host$uri git https://$host$uri">'' - (libPlausible.htmlPlausibleScript { inherit (cfg.server) domain; }) - ]} + nginx.virtualHosts.${cfg.server.domain}.locations = + let + extraHead = '' + ${libNginx.config.appendHead [ + ''<meta name="go-import" content="$host$uri git https://$host$uri">'' + (libPlausible.htmlPlausibleScript { inherit (cfg.server) domain; }) + ]} + ''; + in + { + "/" = { + extraConfig = lib.mkBefore extraHead; + fastcgiParams.HTTP_ACCEPT_ENCODING = ""; + }; + "~ /.+/(info/refs|git-upload-pack)" = { + extraConfig = lib.mkBefore extraHead; + fastcgiParams.HTTP_ACCEPT_ENCODING = ""; + }; + "= /logo.gif".alias = "${./logo.gif}"; + "= /favicon.ico" = { + alias = "${./favicon.ico}"; + extraConfig = lib.mkForce ""; + }; + "= /cgit.css" = { + alias = pkgs.writeText "cgit.css" '' + ${builtins.readFile "${cfg.server.package}/cgit/cgit.css"} + * { + line-height: 1.25em; + } + div#cgit { + font-family: ${ + lib.concatMapStringsSep ", " (f: ''"${f}"'') config.fonts.fontconfig.defaultFonts.monospace + }, monospace; + -moz-tab-size: 2; + tab-size: 2; + max-width: 117ch; + margin: auto; + } + div#cgit table#header td.sub { + border-top: none; + } + div#cgit table#header td.sub.right { + padding-right: 1em; + } + div#cgit table.tabs { + border-bottom: none; + } + div#cgit div.content { + border-bottom: none; + } + div#cgit table.list th a { + color: inherit; + } + div#cgit table.list tr:nth-child(even) { + background: inherit; + } + div#cgit table.list tr:hover { + background: inherit; + } + div#cgit table.list tr.nohover-highlight:hover:nth-child(even) { + background: inherit; + } + div#cgit table.blob td.linenumbers a:target { + color: goldenrod; + text-decoration: underline; + outline: none; + } + div#cgit div#summary { + max-width: 80ch; + } ''; - in - { - "/" = { - extraConfig = mkBefore extraHead; - fastcgiParams.HTTP_ACCEPT_ENCODING = ""; - }; - "~ /.+/(info/refs|git-upload-pack)" = { - extraConfig = mkBefore extraHead; - fastcgiParams.HTTP_ACCEPT_ENCODING = ""; - }; - "= /logo.gif".alias = "${./logo.gif}"; - "= /favicon.ico" = { - alias = "${./favicon.ico}"; - extraConfig = mkForce ""; - }; - "= /cgit.css" = { - alias = pkgs.writeText "cgit.css" '' - ${readFile "${package}/cgit/cgit.css"} - * { - line-height: 1.25em; - } - div#cgit { - font-family: ${ - concatMapStringsSep ", " (f: ''"${f}"'') config.fonts.fontconfig.defaultFonts.monospace - }, monospace; - -moz-tab-size: 2; - tab-size: 2; - max-width: 117ch; - margin: auto; - } - div#cgit table#header td.sub { - border-top: none; - } - div#cgit table#header td.sub.right { - padding-right: 1em; - } - div#cgit table.tabs { - border-bottom: none; - } - div#cgit div.content { - border-bottom: none; - } - div#cgit table.list th a { - color: inherit; - } - div#cgit table.list tr:nth-child(even) { - background: inherit; - } - div#cgit table.list tr:hover { - background: inherit; - } - div#cgit table.list tr.nohover-highlight:hover:nth-child(even) { - background: inherit; - } - div#cgit table.blob td.linenumbers a:target { - color: goldenrod; - text-decoration: underline; - outline: none; - } - div#cgit div#summary { - max-width: 80ch; - } - ''; - extraConfig = mkForce ""; - }; + extraConfig = lib.mkForce ""; }; - }; - } - )) + }; + }; + }) ]; } diff --git a/modules/hyprland.nix b/modules/hyprland.nix new file mode 100644 index 0000000..c7f574a --- /dev/null +++ b/modules/hyprland.nix @@ -0,0 +1,131 @@ +{ + config, + lib, + ... +}: +let + cfg = config.nixfiles.modules.hyprland; +in +{ + options.nixfiles.modules.hyprland.enable = lib.mkEnableOption "Hyprland"; + + config = lib.mkIf cfg.enable { + nixfiles.modules.wayland.enable = true; + + hm = { + stylix.targets.hyprland.enable = false; + + wayland.windowManager.hyprland = { + enable = true; + + systemd = { + enable = true; + variables = [ "--all" ]; + }; + + settings = { + misc = { + disable_hyprland_logo = true; + disable_splash_rendering = true; + }; + + general = { + gaps_in = 0; + gaps_out = 0; + }; + + decoration = { + blur.enabled = false; + }; + + animations.enabled = false; + + debug.disable_logs = false; + + input = with config.services.xserver.xkb; { + kb_layout = layout; + kb_variant = variant; + kb_options = options; + + repeat_delay = config.services.xserver.autoRepeatDelay; + repeat_rate = config.services.xserver.autoRepeatInterval; + }; + + bindm = [ + "SUPER, mouse:272, movewindow" + "SUPER, mouse:273, resizewindow" + "SUPER ALT, mouse:272, resizewindow" + ]; + + bind = + [ + "SUPER SHIFT, E, exec, pkill Hyprland" + + "SUPER, D, killactive," + "SUPER, F, fullscreen," + + "SUPER, G, togglegroup," + "SUPER SHIFT, N, changegroupactive, f" + "SUPER SHIFT, P, changegroupactive, b" + + "SUPER, R, togglesplit," + "SUPER, T, togglefloating," + "SUPER, P, pseudo," + "SUPER ALT, ,resizeactive," + + "SUPER, Return, exec, foot" + "SUPER, L, exec, pgrep hyprlock || hyprlock" + + "SUPER, H, movefocus, l" + "SUPER, J, movefocus, d" + "SUPER, K, movefocus, u" + "SUPER, L, movefocus, r" + + "SUPER SHIFT, H, movewindow, l" + "SUPER SHIFT, J, movewindow, d" + "SUPER SHIFT, K, movewindow, u" + "SUPER SHIFT, L, movewindow, r" + + "SUPER ALT, H, resizeactive, 10 0" + "SUPER ALT, J, resizeactive, 0 10" + "SUPER ALT, K, resizeactive, 0 -10" + "SUPER ALT, L, resizeactive, -10 0" + + ", XF86AudioPlay, exec, mpc play" + ", XF86AudioPrev, exec, mpc prev" + ", XF86AudioNext, exec, mpc next" + + ", XF86AudioRaiseVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ .1+" + ", XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ .1-" + + ", XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle" + ", XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle" + + ", XF86MonBrightnessUp, exec, brightnessctl set +5%" + ", XF86MonBrightnessDown, exec, brightnessctl set 5%-" + ] + ++ (builtins.concatLists ( + builtins.genList ( + x: + let + ws = + let + c = (x + 1) / 10; + in + toString (x + 1 - (c * 10)); + in + [ + "SUPER, ${ws}, workspace, ${toString (x + 1)}" + "SUPER SHIFT, ${ws}, movetoworkspace, ${toString (x + 1)}" + ] + ) 10 + )); + }; + }; + + programs.hyprlock.enable = true; + }; + + programs.hyprland.enable = true; + }; +} diff --git a/modules/ipfs.nix b/modules/ipfs.nix index 25f7fce..80a43b6 100644 --- a/modules/ipfs.nix +++ b/modules/ipfs.nix @@ -175,7 +175,8 @@ in "api.${cfg.domain}" = { locations = { "/".proxyPass = "http://kubo_api"; - "~ ^/$".return = "301 http${optionalString config.nixfiles.modules.acme.enable "s"}://api.${cfg.domain}/webui"; + "~ ^/$".return = + "301 http${optionalString config.nixfiles.modules.acme.enable "s"}://api.${cfg.domain}/webui"; }; extraConfig = libNginx.config.internalOnly; }; diff --git a/modules/jackett.nix b/modules/jackett.nix index 07a5b16..5b0b2c0 100644 --- a/modules/jackett.nix +++ b/modules/jackett.nix @@ -6,22 +6,21 @@ this, ... }: -with lib; let cfg = config.nixfiles.modules.jackett; in { options.nixfiles.modules.jackett = { - enable = mkEnableOption "Jackett"; + enable = lib.mkEnableOption "Jackett"; - domain = mkOption { + domain = lib.mkOption { description = "Domain name sans protocol scheme."; - type = with types; str; + type = lib.types.str; default = "jackett.${config.networking.domain}"; }; }; - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { ark.directories = [ "/var/lib/jackett" ]; nixfiles.modules.nginx = { diff --git a/modules/kde.nix b/modules/kde.nix index e017e11..9490b71 100644 --- a/modules/kde.nix +++ b/modules/kde.nix @@ -50,9 +50,14 @@ in services = { desktopManager.plasma6.enable = true; + displayManager.sddm = { enable = true; - wayland.enable = true; + + wayland = { + enable = false; + compositor = "kwin"; + }; }; }; @@ -64,7 +69,9 @@ in khelpcenter print-manager ]; - systemPackages = with pkgs.kdePackages; [ plasma-disks ]; + systemPackages = with pkgs.kdePackages; [ + plasma-disks + ]; }; }; } diff --git a/modules/monitoring/default.nix b/modules/monitoring/default.nix index 6e5b782..a3e57d3 100644 --- a/modules/monitoring/default.nix +++ b/modules/monitoring/default.nix @@ -166,6 +166,7 @@ in promtail = { hosts = [ manwe + tulkas varda yavanna ]; @@ -182,6 +183,7 @@ in endlessh-go = { hosts = [ manwe + tulkas varda yavanna ]; @@ -197,6 +199,7 @@ in node = { hosts = [ manwe + tulkas varda yavanna ]; diff --git a/modules/nsd.nix b/modules/nsd.nix index 322d88a..acf7e27 100644 --- a/modules/nsd.nix +++ b/modules/nsd.nix @@ -134,6 +134,8 @@ in subdomains = rec { manwe = ips "manwe"; "*.manwe" = manwe; + tulkas = ips "tulkas"; + "*.tulkas" = tulkas; varda = ips "varda"; "*.varda" = varda; yavanna = ips "yavanna"; @@ -148,12 +150,14 @@ in bitwarden = manwe; git = manwe; grafana = manwe; + irc = manwe; loki = manwe; ntfy = manwe; plausible = manwe; prometheus = manwe; radicale = manwe; rss-bridge = manwe; + uptime = manwe; vaultwarden = manwe; flood = yavanna; diff --git a/modules/openssh.nix b/modules/openssh.nix index 470b6c9..a41f0d6 100644 --- a/modules/openssh.nix +++ b/modules/openssh.nix @@ -4,26 +4,25 @@ pkgs, ... }: -with lib; let cfg = config.nixfiles.modules.openssh; in { options.nixfiles.modules.openssh = { - client.enable = mkEnableOption "OpenSSH client"; + client.enable = lib.mkEnableOption "OpenSSH client"; server = { - enable = mkEnableOption "OpenSSH server"; + enable = lib.mkEnableOption "OpenSSH server"; - port = mkOption { + port = lib.mkOption { description = "OpenSSH server port."; - type = types.port; + type = lib.types.port; default = 22022; # Port 22 should be occupied by a tarpit. }; }; }; - config = mkMerge [ - (mkIf cfg.client.enable { + config = lib.mkMerge [ + (lib.mkIf cfg.client.enable { hm = { home.packages = with pkgs; [ mosh @@ -49,11 +48,11 @@ in { hostname ? name, port ? 22022, # NOTE This is not the default OpenSSH port. - user ? my.username, - identityFile ? "${config.my.home}/.ssh/${my.username}_${my.ssh.type}", + user ? lib.my.username, + identityFile ? "${config.my.home}/.ssh/${lib.my.username}_${lib.my.ssh.type}", extraAttrs ? { }, }: - nameValuePair name ( + lib.nameValuePair name ( { inherit hostname @@ -65,23 +64,23 @@ in // extraAttrs ); - internalServers = mapAttrs' mkBlock ( - mapAttrs (name: _: { hostname = "${name}.${my.domain.shire}"; }) ( - filterAttrs (_: attr: hasAttr "wireguard" attr && attr.isHeadless) my.configurations + internalServers = lib.mapAttrs' mkBlock ( + lib.mapAttrs (name: _: { hostname = "${name}.${lib.my.domain.shire}"; }) ( + lib.filterAttrs (_: attr: lib.hasAttr "wireguard" attr && attr.isHeadless) lib.my.configurations ) ); in internalServers - // (mapAttrs' mkBlock { + // (lib.mapAttrs' mkBlock { gitolite = { user = "git"; - hostname = "git.${my.domain.shire}"; + hostname = "git.${lib.my.domain.shire}"; }; }); }; }; }) - (mkIf cfg.server.enable { + (lib.mkIf cfg.server.enable { ark.files = [ "/etc/ssh/ssh_host_ed25519_key" "/etc/ssh/ssh_host_ed25519_key.pub" @@ -101,7 +100,7 @@ in KbdInteractiveAuthentication = false; MaxAuthTries = 3; PasswordAuthentication = false; - PermitRootLogin = mkForce "no"; + PermitRootLogin = lib.mkForce "no"; }; }; diff --git a/modules/password-store.nix b/modules/password-store.nix index e5cd756..886afb6 100644 --- a/modules/password-store.nix +++ b/modules/password-store.nix @@ -9,7 +9,8 @@ let cfg = config.nixfiles.modules.password-store; in { - options.nixfiles.modules.password-store.enable = mkEnableOption "the standard UNIX password manager"; + options.nixfiles.modules.password-store.enable = + mkEnableOption "the standard UNIX password manager"; config = mkIf cfg.enable { hm.programs = { diff --git a/modules/plausible.nix b/modules/plausible.nix index c5b66c3..89729fd 100644 --- a/modules/plausible.nix +++ b/modules/plausible.nix @@ -80,12 +80,12 @@ in services.plausible = { enable = true; - adminUser = { - name = "admin"; - email = "admin@${my.domain.shire}"; - passwordFile = config.secrets.plausible-admin-password.path; - activate = false; - }; + # adminUser = { + # name = "admin"; + # email = "admin@${my.domain.shire}"; + # passwordFile = config.secrets.plausible-admin-password.path; + # activate = false; + # }; mail = { email = "admin+plausible@${my.domain.shire}"; diff --git a/modules/podman.nix b/modules/podman.nix index bdef5be..6c4b20a 100644 --- a/modules/podman.nix +++ b/modules/podman.nix @@ -5,14 +5,13 @@ pkgs, ... }: -with lib; let cfg = config.nixfiles.modules.podman; in { - options.nixfiles.modules.podman.enable = mkEnableOption "Podman"; + options.nixfiles.modules.podman.enable = lib.mkEnableOption "Podman"; - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { assertions = [ { assertion = cfg.enable -> !config.nixfiles.modules.docker.enable; @@ -20,33 +19,31 @@ in } ]; + ark.directories = [ "/var/lib/containers" ]; + nixfiles.modules.common.shell.aliases.p = "podman"; secrets.containers-auth = { file = "${inputs.self}/secrets/containers-auth"; path = "${config.dirs.config}/containers/auth.json"; - owner = my.username; + owner = lib.my.username; inherit (config.my) group; }; virtualisation.podman = { enable = true; - dockerCompat = true; - dockerSocket.enable = true; + dockerCompat = false; + dockerSocket.enable = false; }; - environment.systemPackages = with pkgs; [ podman-compose ]; + environment.systemPackages = [ pkgs.podman-compose ]; my.extraGroups = [ "podman" ]; - hm.xdg.configFile = { - "containers/registries.conf".source = pkgs.writers.writeTOML "containers-registries.toml" { - registries.search.registries = [ "docker.io" ]; - }; - - "containers/storage.conf".source = pkgs.writers.writeTOML "containers-storage.toml" { - storage.driver = "overlay"; - }; - }; + hm.xdg.configFile."containers/registries.conf".source = + pkgs.writers.writeTOML "containers-registries.toml" + { + registries.search.registries = [ "docker.io" ]; + }; }; } diff --git a/modules/profiles/default.nix b/modules/profiles/default.nix index 8824dfd..ae03bcc 100644 --- a/modules/profiles/default.nix +++ b/modules/profiles/default.nix @@ -54,6 +54,7 @@ in dnsutils file inetutils + iotop ldns lshw lsof diff --git a/modules/profiles/dev/default.nix b/modules/profiles/dev/default.nix index 61de848..af151a1 100644 --- a/modules/profiles/dev/default.nix +++ b/modules/profiles/dev/default.nix @@ -11,7 +11,8 @@ in { imports = attrValues (modulesIn ./.); - options.nixfiles.modules.profiles.dev.enable = mkEnableOption "Catch-all profile for stuff related to software development and etc."; + options.nixfiles.modules.profiles.dev.enable = + mkEnableOption "Catch-all profile for stuff related to software development and etc."; config = mkIf cfg.enable { nixfiles.modules = { @@ -22,6 +23,7 @@ in git.client.enable = true; nmap.enable = true; wget.enable = true; + podman.enable = true; }; hm = { @@ -58,6 +60,8 @@ in packages = with pkgs; [ age + dbeaver-bin + distrobox google-cloud-sdk htmlq httpie @@ -69,6 +73,8 @@ in nixpkgs-review scaleway-cli sops + sqlitebrowser + toolbox vultr-cli yq ]; diff --git a/modules/profiles/headful.nix b/modules/profiles/headful.nix index 256ec25..e2ed1df 100644 --- a/modules/profiles/headful.nix +++ b/modules/profiles/headful.nix @@ -123,15 +123,16 @@ in services = { fwupd.enable = true; libinput.enable = true; - psd.enable = true; upower.enable = true; }; time.timeZone = "Europe/Moscow"; environment.systemPackages = with pkgs; [ + brightnessctl lm_sensors usbutils + wirelesstools ]; my.extraGroups = [ diff --git a/modules/profiles/headless.nix b/modules/profiles/headless.nix index 5d42df0..bf0d23a 100644 --- a/modules/profiles/headless.nix +++ b/modules/profiles/headless.nix @@ -5,16 +5,15 @@ this, ... }: -with lib; let cfg = config.nixfiles.modules.profiles.headless; in { - options.nixfiles.modules.profiles.headless.enable = mkEnableOption "headless profile" // { + options.nixfiles.modules.profiles.headless.enable = lib.mkEnableOption "headless profile" // { default = this.isHeadless; }; - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { nixfiles.modules = { openssh.server.enable = true; endlessh-go.enable = true; diff --git a/modules/psd.nix b/modules/psd.nix index f974af2..5bb9dc3 100644 --- a/modules/psd.nix +++ b/modules/psd.nix @@ -17,6 +17,7 @@ in xdg.configFile."psd/psd.conf".text = '' USE_OVERLAYFS="yes" + USE_BACKUPS="no" ''; }; diff --git a/modules/searx.nix b/modules/searx.nix index de51a20..ab186af 100644 --- a/modules/searx.nix +++ b/modules/searx.nix @@ -5,28 +5,27 @@ libNginx, ... }: -with lib; let cfg = config.nixfiles.modules.searx; in { options.nixfiles.modules.searx = { - enable = mkEnableOption "SearX"; + enable = lib.mkEnableOption "SearX"; - port = mkOption { + port = lib.mkOption { description = "Port."; - type = with types; port; + type = with lib.types; port; default = 61001; }; - domain = mkOption { + domain = lib.mkOption { description = "Domain name sans protocol scheme."; - type = with types; nullOr str; + type = with lib.types; nullOr str; default = "searx.${config.networking.domain}"; }; }; - config = mkIf cfg.enable { + config = lib.mkIf cfg.enable { secrets.searx-environment = { file = "${inputs.self}/secrets/searx-environment"; owner = "searx"; diff --git a/modules/syncthing.nix b/modules/syncthing.nix index e261a12..d239aa4 100644 --- a/modules/syncthing.nix +++ b/modules/syncthing.nix @@ -79,7 +79,7 @@ in devices = mapAttrs ( name: attr: - mkIf (attr.syncthing.id != null && hasAttr "wireguard" attr) { + mkIf (hasAttr "syncthing" attr && hasAttr "wireguard" attr) { inherit (attr.syncthing) id; compression = "always"; introducer = false; @@ -98,7 +98,7 @@ in f: attrNames ( filterAttrs ( - _: attr: (attr.hostname != this.hostname) && (attr.syncthing.id != null) && f attr + _: attr: attr.hostname != this.hostname && hasAttr "syncthing" attr && f attr ) my.configurations ); all = filterDevices (_: true); @@ -111,7 +111,7 @@ in }; trashcan = { type = "trashcan"; - params.cleanoutDays = "7"; + params.cleanouctDays = "7"; }; in with config.hm.xdg.userDirs; @@ -121,11 +121,6 @@ in devices = notHeadless; versioning = trashcan; }; - pass = { - path = config.hm.programs.password-store.settings.PASSWORD_STORE_DIR; - devices = notOther; - versioning = trashcan; - }; org = { path = "${documents}/org"; devices = all; diff --git a/modules/thelounge.nix b/modules/thelounge.nix new file mode 100644 index 0000000..ae4b4ff --- /dev/null +++ b/modules/thelounge.nix @@ -0,0 +1,49 @@ +{ + config, + lib, + libNginx, + ... +}: +let + cfg = config.nixfiles.modules.thelounge; +in +{ + options.nixfiles.modules.thelounge = { + enable = lib.mkEnableOption "The Lounge"; + + port = lib.mkOption { + description = "Port."; + type = lib.types.port; + default = 11887; + }; + + domain = lib.mkOption { + description = "Domain name sans protocol scheme."; + type = lib.types.str; + default = "irc.${config.networking.domain}"; + }; + }; + + config = lib.mkIf cfg.enable { + ark.directories = [ "/var/lib/thelounge" ]; + + nixfiles.modules.nginx = { + upstreams.thelounge.servers."127.0.0.1:${toString cfg.port}" = { }; + virtualHosts.${cfg.domain} = { + locations."/".proxyPass = "http://thelounge"; + extraConfig = libNginx.config.internalOnly; + }; + }; + + services.thelounge = { + enable = true; + extraConfig = { + public = false; + host = "127.0.0.1"; + inherit (cfg) port; + reverseProxy = true; + defaults = { }; + }; + }; + }; +} diff --git a/modules/unbound-ng.nix b/modules/unbound-ng.nix new file mode 100644 index 0000000..3d3c6da --- /dev/null +++ b/modules/unbound-ng.nix @@ -0,0 +1,185 @@ +{ + config, + inputs, + lib, + pkgs, + this, + ... +}: +with lib; +let + cfg = config.nixfiles.modules.unbound-ng; +in +{ + options.nixfiles.modules.unbound-ng = { + enable = mkEnableOption "Unbound"; + + domain = mkOption { + description = "Domain name sans protocol scheme."; + type = with types; str; + default = config.networking.domain; + }; + }; + + config = mkIf cfg.enable { + ark.directories = [ config.services.unbound.stateDir ]; + + nixfiles.modules.redis.enable = true; + + services = { + unbound = { + enable = true; + + package = pkgs.unbound-with-systemd.override { + withRedis = true; + withTFO = true; + }; + + checkconf = true; + settings = { + server = { + module-config = ''"respip validator iterator"''; + + interface = with this.wireguard-ng; [ + "127.0.0.1" + "::1" + ipv4.address + ipv6.address + ]; + + local-zone = concatLists ( + mapAttrsToList (h: _: [ "\"${h}.${cfg.domain}\" redirect" ]) my.configurations + ); + local-data = concatLists ( + mapAttrsToList ( + hostname: + let + domain = "${hostname}.${cfg.domain}"; + in + attr: + (optionals (hasAttr "wireguard-ng" attr) ( + with attr.wireguard-ng; + [ + "\"${domain} 604800 IN A ${ipv4.address}\"" + "\"${domain} 604800 IN AAAA ${ipv6.address}\"" + "\"${domain}. A ${ipv4.address}\"" + "\"${domain}. AAAA ${ipv6.address}\"" + ] + ++ (optionals (hasAttr "domains" attr) ( + concatMap (domain: [ + "\"${domain}. A ${ipv4.address}\"" + "\"${domain}. AAAA ${ipv6.address}\"" + ]) attr.domains + )) + )) + ) my.configurations + ); + local-data-ptr = concatLists ( + mapAttrsToList ( + hostname: + let + domain = "${hostname}.${cfg.domain}"; + in + attr: + (optionals (hasAttr "wireguard-ng" attr) ( + with attr.wireguard-ng; + [ + "\"${ipv4.address} ${domain}\"" + "\"${ipv6.address} ${domain}\"" + ] + ++ (optionals (hasAttr "domains" attr) ( + concatMap (domain: [ + "\"${ipv4.address} ${domain}\"" + "\"${ipv6.address} ${domain}\"" + ]) attr.domains + )) + )) + ) my.configurations + ); + + private-domain = map (domain: "${domain}.") [ + cfg.domain + "local" + ]; + private-address = with config.nixfiles.modules.wireguard-ng; [ + ipv4.subnet + ipv6.subnet + ]; + + access-control = with config.nixfiles.modules.wireguard-ng; [ + "0.0.0.0/0 refuse" + "::/0 refuse" + "127.0.0.0/8 allow" + "::1/128 allow" + "${ipv4.subnet} allow" + "${ipv6.subnet} allow" + ]; + + cache-min-ttl = 0; + + serve-expired = true; + serve-expired-reply-ttl = 0; + + prefetch = true; + prefetch-key = true; + + hide-identity = true; + hide-version = true; + + extended-statistics = true; + + log-replies = false; + log-tag-queryreply = false; + log-local-actions = false; + + verbosity = 0; + }; + + forward-zone = [ + { + name = "."; + forward-tls-upstream = true; + forward-addr = dns.mkDoT dns.const.quad9.ecs; + } + ]; + + cachedb = with config.services.redis.servers.default; { + backend = "redis"; + redis-server-host = bind; + redis-server-port = port; + }; + + rpz = { + name = "hagezi.pro"; + zonefile = "hagezi.pro"; + url = "https://cdn.jsdelivr.net/gh/hagezi/dns-blocklists@latest/rpz/pro.txt"; + }; + }; + + enableRootTrustAnchor = true; + + localControlSocketPath = "/run/unbound/unbound.socket"; + }; + + prometheus.exporters.unbound = { + enable = true; + listenAddress = mkDefault this.wireguard-ng.ipv4.address; + port = 9167; + inherit (config.services.unbound) group user; + unbound.host = "unix://${config.services.unbound.localControlSocketPath}"; + }; + }; + + boot.kernel.sysctl."net.ipv4.tcp_fastopen" = mkOverride 200 3; + + topology = with cfg; { + nodes.${this.hostname}.services.unbound = { + name = "Unbound"; + icon = "${inputs.homelab-svg-assets}/assets/unbound.svg"; + details.listen.text = concatMapStringsSep "\n" (i: "${i}:53") ( + filter (i: i != "127.0.0.1" && i != "::1") config.services.unbound.settings.server.interface + ); + }; + }; + }; +} diff --git a/modules/unbound.nix b/modules/unbound.nix index e837f89..b8de321 100644 --- a/modules/unbound.nix +++ b/modules/unbound.nix @@ -65,10 +65,12 @@ in "\"${domain}. A ${ipv4.address}\"" "\"${domain}. AAAA ${ipv6.address}\"" ] - ++ concatMap (domain: [ - "\"${domain}. A ${ipv4.address}\"" - "\"${domain}. AAAA ${ipv6.address}\"" - ]) attr.domains + ++ (optionals (hasAttr "domains" attr) ( + concatMap (domain: [ + "\"${domain}. A ${ipv4.address}\"" + "\"${domain}. AAAA ${ipv6.address}\"" + ]) attr.domains + )) )) ) my.configurations ); @@ -85,10 +87,12 @@ in "\"${ipv4.address} ${domain}\"" "\"${ipv6.address} ${domain}\"" ] - ++ concatMap (domain: [ - "\"${ipv4.address} ${domain}\"" - "\"${ipv6.address} ${domain}\"" - ]) attr.domains + ++ (optionals (hasAttr "domains" attr) ( + concatMap (domain: [ + "\"${ipv4.address} ${domain}\"" + "\"${ipv6.address} ${domain}\"" + ]) attr.domains + )) )) ) my.configurations ); diff --git a/modules/uptime-kuma.nix b/modules/uptime-kuma.nix new file mode 100644 index 0000000..5f48d0d --- /dev/null +++ b/modules/uptime-kuma.nix @@ -0,0 +1,49 @@ +{ + config, + lib, + libNginx, + ... +}: +let + cfg = config.nixfiles.modules.uptime-kuma; +in +{ + options.nixfiles.modules.uptime-kuma = { + enable = lib.mkEnableOption "Uptime Kuma"; + + port = lib.mkOption { + description = "Port."; + type = lib.types.port; + default = 9988; + }; + + domain = lib.mkOption { + description = "Domain name sans protocol scheme."; + type = lib.types.str; + default = "uptime.${config.networking.domain}"; + }; + }; + + config = lib.mkIf cfg.enable { + ark.directories = [ + "/var/lib/private/uptime-kuma" + "/var/lib/uptime-kuma" + ]; + + nixfiles.modules.nginx = { + upstreams.uptime-kuma.servers."127.0.0.1:${toString cfg.port}" = { }; + virtualHosts.${cfg.domain} = { + locations."/".proxyPass = "http://uptime-kuma"; + extraConfig = libNginx.config.internalOnly; + }; + }; + + services.uptime-kuma = { + enable = true; + settings = { + UPTIME_KUMA_HOST = "127.0.0.1"; + UPTIME_KUMA_PORT = toString cfg.port; + }; + }; + }; +} diff --git a/modules/vaultwarden.nix b/modules/vaultwarden.nix index edce8e5..124ff78 100644 --- a/modules/vaultwarden.nix +++ b/modules/vaultwarden.nix @@ -5,17 +5,16 @@ this, ... }: -with lib; let cfg = config.nixfiles.modules.vaultwarden; in { options.nixfiles.modules.vaultwarden = { - enable = mkEnableOption "Vaultwarden"; + enable = lib.mkEnableOption "Vaultwarden"; - domain = mkOption { + domain = lib.mkOption { description = "Domain name sans protocol scheme."; - type = with types; str; + type = lib.types.str; default = "vaultwarden.${config.networking.domain}"; }; }; @@ -24,7 +23,7 @@ in let db = "vaultwarden"; in - mkIf cfg.enable { + lib.mkIf cfg.enable { ark.directories = [ "/var/lib/bitwarden_rs" ]; secrets.vaultwarden-environment = { @@ -73,7 +72,7 @@ in WEB_VAULT_ENABLED = true; - DOMAIN = optionalString (cfg.domain != null) "http://${cfg.domain}"; + DOMAIN = lib.optionalString (cfg.domain != null) "http://${cfg.domain}"; SIGNUPS_ALLOWED = false; INVITATIONS_ALLOWED = false; @@ -127,14 +126,14 @@ in }; environment.etc = { - "fail2ban/filter.d/vaultwarden.conf".text = generators.toINI { } { + "fail2ban/filter.d/vaultwarden.conf".text = lib.generators.toINI { } { Definition = { failregex = "^.*Username or password is incorrect\. Try again\. IP: <ADDR>\. Username:.*$"; ignoreregex = ""; journalmatch = "_SYSTEMD_UNIT=vaultwarden.service"; }; }; - "fail2ban/filter.d/vaultwarden-admin.conf".text = generators.toINI { } { + "fail2ban/filter.d/vaultwarden-admin.conf".text = lib.generators.toINI { } { Definition = { failregex = "^.*Invalid admin token\. IP: <ADDR>.*$"; ignoreregex = ""; @@ -143,9 +142,9 @@ in }; }; - topology = with cfg; { + topology = { nodes.${this.hostname}.services.vaultwarden = { - info = mkForce domain; + info = lib.mkForce cfg.domain; }; }; }; diff --git a/modules/wayland.nix b/modules/wayland.nix index 7a9820d..f15f66e 100644 --- a/modules/wayland.nix +++ b/modules/wayland.nix @@ -15,7 +15,12 @@ in nixfiles.modules.foot.enable = true; hm.home = { - packages = with pkgs; [ wl-clipboard ]; + packages = with pkgs; [ + grim + slurp + wl-clipboard + wlr-randr + ]; sessionVariables.NIXOS_OZONE_WL = 1; }; diff --git a/modules/wireguard-ng.nix b/modules/wireguard-ng.nix new file mode 100644 index 0000000..5374a71 --- /dev/null +++ b/modules/wireguard-ng.nix @@ -0,0 +1,255 @@ +{ + config, + inputs, + lib, + pkgs, + this, + ... +}: +with lib; +let + cfg = config.nixfiles.modules.wireguard-ng; + + DNSSetup = optionalString config.services.resolved.enable ( + let + resolvectl = "${config.systemd.package}/bin/resolvectl"; + in + '' + ${resolvectl} dns ${cfg.interface} ${cfg.server.ipv6.address} ${cfg.server.ipv4.address} + ${resolvectl} domain ${cfg.interface} local ${my.domain.shire} + ${resolvectl} dnssec ${cfg.interface} no + ${resolvectl} dnsovertls ${cfg.interface} no + '' + ); +in +{ + options.nixfiles.modules.wireguard-ng = { + client = { + enable = mkEnableOption "WireGuard client"; + + enableTrafficRouting = mkOption { + description = "Whether to enable traffic routing through the sever."; + type = with types; bool; + # default = !this.isHeadless; + default = false; + }; + }; + + server = { + enable = mkEnableOption "WireGuard server"; + + ipv4.address = mkOption { + description = "IPv4 address to bind to."; + type = with types; str; + default = my.configurations.tulkas.wireguard-ng.ipv4.address; + }; + + ipv6.address = mkOption { + description = "IPv4 address to bind to."; + type = with types; str; + default = my.configurations.tulkas.wireguard-ng.ipv6.address; + }; + + address = mkOption { + description = "Endpoint address to use"; + type = with types; str; + default = my.configurations.tulkas.ipv4.address; + }; + + port = mkOption { + description = "Endpoint port to use."; + type = with types; int; + default = 7070; + }; + + publicKey = mkOption { + description = "Server's public key."; + type = with types; str; + default = my.configurations.tulkas.wireguard.publicKey; + }; + + peers = mkOption { + description = "List of peers."; + type = with types; listOf attrs; + default = + mapAttrsToList + ( + _: attr: with attr; { + inherit (wireguard-ng) publicKey; + allowedIPs = with wireguard-ng; [ + "${ipv6.address}/128" + "${ipv4.address}/32" + ]; + } + ) + ( + filterAttrs ( + _: attr: attr.hostname != this.hostname && hasAttr "wireguard-ng" attr + ) my.configurations + ); + }; + }; + + interface = mkOption { + description = "Name of the interface to use WireGuard with."; + type = with types; str; + default = "wg70"; + }; + + ipv4.subnet = mkOption { + description = "CIDR notation for the IPv4 subnet to use over WireGuard."; + type = with types; str; + default = "10.70.0.0/16"; + }; + + ipv6.subnet = mkOption { + description = "CIDR notation for the IPv6 subnet to use over WireGuard."; + type = with types; str; + default = "fd70::/16"; + }; + }; + + config = + { + assertions = [ + { + assertion = config.security.sudo.enable; + message = "Sudo is not enabled."; + } + { + assertion = any (x: x == "wheel") config.my.extraGroups; + message = ''User is not in the "wheel" group.''; + } + ]; + } + // mkMerge [ + (mkIf (cfg.client.enable || cfg.server.enable) { + secrets."wireguard-private-key-${this.hostname}".file = + "${inputs.self}/secrets/wireguard-private-key-${this.hostname}"; + + networking.firewall.trustedInterfaces = [ cfg.interface ]; + + topology = with cfg; { + nodes.${this.hostname}.interfaces.${interface} = { + network = interface; + icon = "interfaces.wireguard"; + }; + }; + }) + (mkIf cfg.client.enable { + networking.wg-quick.interfaces.${cfg.interface} = mkMerge [ + (with this.wireguard-ng; { + privateKeyFile = config.secrets."wireguard-private-key-${this.hostname}".path; + address = [ + "${ipv4.address}/16" + "${ipv6.address}/16" + ]; + }) + (with cfg.server; { + peers = [ + { + inherit publicKey; + endpoint = "${address}:${toString port}"; + allowedIPs = + if cfg.client.enableTrafficRouting then + [ + "::/0" + "0.0.0.0/0" + ] + else + [ + cfg.ipv6.subnet + cfg.ipv4.subnet + ]; + } + ]; + dns = [ + ipv6.address + ipv4.address + ]; + postUp = DNSSetup; + }) + ]; + + environment.systemPackages = with pkgs; [ + (writeShellApplication { + name = "wg-toggle-ng"; + runtimeInputs = [ + iproute2 + jq + ]; + text = '' + ip46() { + sudo ip -4 "$@" + sudo ip -6 "$@" + } + + fwmark=$(sudo awg show ${cfg.interface} fwmark) || exit + if ip -j rule list lookup "$fwmark" | jq -e 'length > 0' >/dev/null; then + ip46 rule del lookup main suppress_prefixlength 0 + ip46 rule del lookup "$fwmark" + else + ip46 rule add not fwmark "$fwmark" lookup "$fwmark" + ip46 rule add lookup main suppress_prefixlength 0 + fi + ''; + }) + ]; + }) + (mkIf cfg.server.enable { + networking = { + wireguard = { + enable = true; + interfaces.${cfg.interface} = with cfg.server; { + privateKeyFile = config.secrets."wireguard-private-key-${this.hostname}".path; + ips = [ + "${ipv6.address}/16" + "${ipv4.address}/16" + ]; + listenPort = port; + inherit peers; + postSetup = DNSSetup; + allowedIPsAsRoutes = false; + }; + }; + + nat = { + enable = true; + enableIPv6 = true; + + externalInterface = mkDefault "eth0"; + + internalInterfaces = [ cfg.interface ]; + internalIPs = [ cfg.ipv4.subnet ]; + internalIPv6s = [ cfg.ipv6.subnet ]; + }; + + firewall.allowedUDPPorts = [ cfg.server.port ]; + }; + + services.prometheus.exporters.wireguard = { + enable = true; + listenAddress = mkDefault this.wireguard-ng.ipv4.address; + withRemoteIp = true; + port = 9586; + }; + + topology = with cfg; { + networks = { + ${interface} = { + name = interface; + cidrv4 = ipv4.subnet; + cidrv6 = ipv6.subnet; + icon = "interfaces.wireguard"; + }; + }; + + nodes.${this.hostname}.interfaces.${interface}.physicalConnections = + mapAttrsToList (name: _: config.lib.topology.mkConnection name interface) + ( + filterAttrs (n: v: !v.isOther && n != this.hostname && hasAttr "wireguard-ng" v) my.configurations + ); + }; + }) + ]; +} diff --git a/modules/wireguard.nix b/modules/wireguard.nix index 3589e12..633ec5b 100644 --- a/modules/wireguard.nix +++ b/modules/wireguard.nix @@ -10,16 +10,29 @@ with lib; let cfg = config.nixfiles.modules.wireguard; - DNSSetup = + DNSSetup = optionalString config.services.resolved.enable ( let resolvectl = "${config.systemd.package}/bin/resolvectl"; in '' ${resolvectl} dns ${cfg.interface} ${cfg.server.ipv6.address} ${cfg.server.ipv4.address} - ${resolvectl} domain ${cfg.interface} ${my.domain.shire} + ${resolvectl} domain ${cfg.interface} local ${my.domain.shire} ${resolvectl} dnssec ${cfg.interface} no ${resolvectl} dnsovertls ${cfg.interface} no - ''; + '' + ); + + extraOptions = { + jc = 23; + jmin = 58; + jmax = 1021; + s1 = 49; + s2 = 87; + h1 = 1264154357; + h2 = 462401493; + h3 = 737329836; + h4 = 1039929807; + }; in { disabledModules = [ @@ -129,7 +142,8 @@ in } // mkMerge [ (mkIf (cfg.client.enable || cfg.server.enable) { - secrets."wireguard-private-key-${this.hostname}".file = "${inputs.self}/secrets/wireguard-private-key-${this.hostname}"; + secrets."wireguard-private-key-${this.hostname}".file = + "${inputs.self}/secrets/wireguard-private-key-${this.hostname}"; networking.firewall.trustedInterfaces = [ cfg.interface ]; @@ -149,13 +163,7 @@ in "${ipv4.address}/16" "${ipv6.address}/16" ]; - extraInterfaceConfig = '' - jc = 228 - jmin = 42 - jmax = 420 - s1 = 69 - s2 = 96 - ''; + inherit extraOptions; }) (with cfg.server; { peers = [ @@ -221,17 +229,8 @@ in "${ipv4.address}/16" ]; listenPort = port; - inherit peers; - postSetup = - DNSSetup - + '' - awg set ${cfg.interface} \ - jc 228 \ - jmin 42 \ - jmax 420 \ - s1 69 \ - s2 96 - ''; + inherit peers extraOptions; + postSetup = DNSSetup; allowedIPsAsRoutes = false; }; }; |