diff options
Diffstat (limited to '')
-rw-r--r-- | modules/acme.nix | 13 | ||||
-rw-r--r-- | modules/chromium.nix | 3 | ||||
-rw-r--r-- | modules/common/ark.nix | 13 | ||||
-rw-r--r-- | modules/common/home-manager.nix | 13 | ||||
-rw-r--r-- | modules/common/networking.nix | 132 | ||||
-rw-r--r-- | modules/common/nix.nix | 8 | ||||
-rw-r--r-- | modules/common/secrets.nix | 16 | ||||
-rw-r--r-- | modules/common/stylix.nix | 13 | ||||
-rw-r--r-- | modules/common/users.nix | 13 | ||||
-rw-r--r-- | modules/emacs/default.nix | 5 | ||||
-rw-r--r-- | modules/firefox/default.nix | 1 | ||||
-rw-r--r-- | modules/hyprland.nix | 12 | ||||
-rw-r--r-- | modules/ipfs.nix | 3 | ||||
-rw-r--r-- | modules/password-store.nix | 3 | ||||
-rw-r--r-- | modules/plausible.nix | 12 | ||||
-rw-r--r-- | modules/profiles/dev/default.nix | 3 | ||||
-rw-r--r-- | modules/syncthing.nix | 6 | ||||
-rw-r--r-- | modules/unbound-ng.nix | 185 | ||||
-rw-r--r-- | modules/unbound.nix | 20 | ||||
-rw-r--r-- | modules/wireguard-ng.nix | 255 | ||||
-rw-r--r-- | modules/wireguard.nix | 22 |
21 files changed, 623 insertions, 128 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/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 ba3056b..007e209 100644 --- a/modules/common/ark.nix +++ b/modules/common/ark.nix @@ -10,11 +10,14 @@ in { imports = [ inputs.impermanence.nixosModules.impermanence - (lib.mkAliasOptionModule [ "ark" ] [ - "nixfiles" - "modules" - "ark" - ]) + (lib.mkAliasOptionModule + [ "ark" ] + [ + "nixfiles" + "modules" + "ark" + ] + ) ]; options.nixfiles.modules.ark = diff --git a/modules/common/home-manager.nix b/modules/common/home-manager.nix index f3e8143..118fc0e 100644 --- a/modules/common/home-manager.nix +++ b/modules/common/home-manager.nix @@ -7,11 +7,14 @@ { imports = [ inputs.home-manager.nixosModule - (lib.mkAliasOptionModule [ "hm" ] [ - "home-manager" - "users" - lib.my.username - ]) + (lib.mkAliasOptionModule + [ "hm" ] + [ + "home-manager" + "users" + lib.my.username + ] + ) ]; hm = { diff --git a/modules/common/networking.nix b/modules/common/networking.nix index 468bd8b..2e9c218 100644 --- a/modules/common/networking.nix +++ b/modules/common/networking.nix @@ -7,9 +7,12 @@ }: let cfg = config.nixfiles.modules.common.networking; + + interface = "eth0"; # This assumes `usePredictableInterfaceNames` is false. in { - options.nixfiles.modules.common.networking.onlyDefault = lib.mkEnableOption "custom networking settings"; + options.nixfiles.modules.common.networking.onlyDefault = + lib.mkEnableOption "custom networking settings"; config = lib.mkIf (!cfg.onlyDefault) { ark.directories = @@ -31,20 +34,6 @@ in "::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 lib.my.configurations.manwe.wireguard; [ - ipv6.address - ipv4.address - ]; - useDHCP = false; nftables.enable = true; @@ -62,45 +51,46 @@ in logRefusedUnicastsOnly = false; logReversePathDrops = false; }; + + usePredictableInterfaceNames = false; } - ( - let - interface = "eth0"; # This assumes `usePredictableInterfaceNames` is false. - in - lib.mkIf (lib.hasAttr "ipv4" this && lib.hasAttr "ipv6" this) { - usePredictableInterfaceNames = false; # NOTE This can break something! - interfaces.${interface} = { - ipv4.addresses = - with this.ipv4; - lib.optional (lib.isString address && lib.isInt prefixLength) { - inherit address prefixLength; - }; - - ipv6.addresses = - with this.ipv6; - lib.optional (lib.isString address && lib.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; + lib.mkIf (lib.isString gatewayAddress) { + inherit interface; + address = gatewayAddress; }; - defaultGateway = - with this.ipv4; - lib.mkIf (lib.isString gatewayAddress) { - inherit interface; - address = gatewayAddress; - }; - defaultGateway6 = - with this.ipv6; - 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 = true; - plugins = lib.mkForce [ ]; wifi.backend = "iwd"; + dns = "none"; }; wireless = { @@ -109,15 +99,49 @@ in userControlled.enable = true; allowAuxiliaryImperativeNetworks = true; }; + + resolvconf.extraConfig = '' + append_nameservers='127.0.0.1' + ''; }) ]; - services.resolved = { - llmnr = "false"; - dnsovertls = "opportunistic"; - dnssec = "allow-downgrade"; - fallbackDns = lib.dns.mkDoT lib.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 = lib.listToAttrs ( diff --git a/modules/common/nix.nix b/modules/common/nix.nix index 09d57ed..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 = [ @@ -83,6 +88,9 @@ in trusted-public-keys = [ "cache.tvl.su:kjc6KOMupXc1vHVufJUoDUYeLzbwSr9abcAKdn/U1Jk=" ]; + + # https://github.com/NixOS/nix/issues/6901 + fallback = true; }; }; 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/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/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/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/firefox/default.nix b/modules/firefox/default.nix index 4b04c40..ee45434 100644 --- a/modules/firefox/default.nix +++ b/modules/firefox/default.nix @@ -536,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/hyprland.nix b/modules/hyprland.nix index cab01b6..c7f574a 100644 --- a/modules/hyprland.nix +++ b/modules/hyprland.nix @@ -1,6 +1,5 @@ { config, - inputs, lib, ... }: @@ -128,16 +127,5 @@ in }; programs.hyprland.enable = true; - - nixpkgs.overlays = [ inputs.hyprland.overlays.default ]; - - nix.settings = { - substituters = [ - "https://hyprland.cachix.org" - ]; - trusted-public-keys = [ - "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc=" - ]; - }; }; } 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/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/profiles/dev/default.nix b/modules/profiles/dev/default.nix index 4d85168..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 = { diff --git a/modules/syncthing.nix b/modules/syncthing.nix index e61c080..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; 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/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 5138946..633ec5b 100644 --- a/modules/wireguard.nix +++ b/modules/wireguard.nix @@ -10,7 +10,7 @@ with lib; let cfg = config.nixfiles.modules.wireguard; - DNSSetup = + DNSSetup = optionalString config.services.resolved.enable ( let resolvectl = "${config.systemd.package}/bin/resolvectl"; in @@ -19,14 +19,19 @@ let ${resolvectl} domain ${cfg.interface} local ${my.domain.shire} ${resolvectl} dnssec ${cfg.interface} no ${resolvectl} dnsovertls ${cfg.interface} no - ''; + '' + ); extraOptions = { - jc = 228; - jmin = 42; - jmax = 420; - s1 = 69; - s2 = 96; + jc = 23; + jmin = 58; + jmax = 1021; + s1 = 49; + s2 = 87; + h1 = 1264154357; + h2 = 462401493; + h3 = 737329836; + h4 = 1039929807; }; in { @@ -137,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 ]; |