diff options
Diffstat (limited to 'nixos/modules/services/networking')
-rw-r--r-- | nixos/modules/services/networking/dnscache.nix | 6 | ||||
-rw-r--r-- | nixos/modules/services/networking/mihomo.nix | 118 | ||||
-rw-r--r-- | nixos/modules/services/networking/mycelium.nix | 133 | ||||
-rw-r--r-- | nixos/modules/services/networking/networkmanager.nix | 22 |
4 files changed, 275 insertions, 4 deletions
diff --git a/nixos/modules/services/networking/dnscache.nix b/nixos/modules/services/networking/dnscache.nix index eff13f69f470..4f5b77a5b685 100644 --- a/nixos/modules/services/networking/dnscache.nix +++ b/nixos/modules/services/networking/dnscache.nix @@ -86,7 +86,11 @@ in { config = mkIf config.services.dnscache.enable { environment.systemPackages = [ pkgs.djbdns ]; - users.users.dnscache.isSystemUser = true; + users.users.dnscache = { + isSystemUser = true; + group = "dnscache"; + }; + users.groups.dnscache = {}; systemd.services.dnscache = { description = "djbdns dnscache server"; diff --git a/nixos/modules/services/networking/mihomo.nix b/nixos/modules/services/networking/mihomo.nix new file mode 100644 index 000000000000..ae700603b529 --- /dev/null +++ b/nixos/modules/services/networking/mihomo.nix @@ -0,0 +1,118 @@ +# NOTE: +# cfg.configFile contains secrets such as proxy servers' credential! +# we dont want plaintext secrets in world-readable `/nix/store`. + +{ lib +, config +, pkgs +, ... +}: +let + cfg = config.services.mihomo; +in +{ + options.services.mihomo = { + enable = lib.mkEnableOption "Mihomo, A rule-based proxy in Go."; + + package = lib.mkPackageOption pkgs "mihomo" { }; + + configFile = lib.mkOption { + default = null; + type = lib.types.nullOr lib.types.path; + description = "Configuration file to use."; + }; + + webui = lib.mkOption { + default = null; + type = lib.types.nullOr lib.types.path; + description = '' + Local web interface to use. + + You can also use the following website, just in case: + - metacubexd: + - https://d.metacubex.one + - https://metacubex.github.io/metacubexd + - https://metacubexd.pages.dev + - yacd: + - https://yacd.haishan.me + - clash-dashboard (buggy): + - https://clash.razord.top + ''; + }; + + extraOpts = lib.mkOption { + default = null; + type = lib.types.nullOr lib.types.str; + description = "Extra command line options to use."; + }; + + tunMode = lib.mkEnableOption '' + necessary permission for Mihomo's systemd service for TUN mode to function properly. + + Keep in mind, that you still need to enable TUN mode manually in Mihomo's configuration. + ''; + }; + + config = lib.mkIf cfg.enable { + ### systemd service + systemd.services."mihomo" = { + description = "Mihomo daemon, A rule-based proxy in Go."; + documentation = [ "https://wiki.metacubex.one/" ]; + requires = [ "network-online.target" ]; + after = [ "network-online.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = + { + ExecStart = lib.concatStringsSep " " [ + (lib.getExe cfg.package) + "-d /var/lib/private/mihomo" + (lib.optionalString (cfg.configFile != null) "-f \${CREDENTIALS_DIRECTORY}/config.yaml") + (lib.optionalString (cfg.webui != null) "-ext-ui ${cfg.webui}") + (lib.optionalString (cfg.extraOpts != null) cfg.extraOpts) + ]; + + DynamicUser = true; + StateDirectory = "mihomo"; + LoadCredential = "config.yaml:${cfg.configFile}"; + + ### Hardening + AmbientCapabilities = ""; + CapabilityBoundingSet = ""; + DeviceAllow = ""; + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateMounts = true; + PrivateTmp = true; + PrivateUsers = true; + ProcSubset = "pid"; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProtectProc = "invisible"; + ProtectSystem = "strict"; + RestrictRealtime = true; + RestrictSUIDSGID = true; + RestrictNamespaces = true; + RestrictAddressFamilies = "AF_INET AF_INET6"; + SystemCallArchitectures = "native"; + SystemCallFilter = "@system-service bpf"; + UMask = "0077"; + } + // lib.optionalAttrs cfg.tunMode { + AmbientCapabilities = "CAP_NET_ADMIN"; + CapabilityBoundingSet = "CAP_NET_ADMIN"; + PrivateDevices = false; + PrivateUsers = false; + RestrictAddressFamilies = "AF_INET AF_INET6 AF_NETLINK"; + }; + }; + }; + + meta.maintainers = with lib.maintainers; [ Guanran928 ]; +} diff --git a/nixos/modules/services/networking/mycelium.nix b/nixos/modules/services/networking/mycelium.nix new file mode 100644 index 000000000000..9c4bca7c6861 --- /dev/null +++ b/nixos/modules/services/networking/mycelium.nix @@ -0,0 +1,133 @@ +{ config, pkgs, lib, ... }: + +let + cfg = config.services.mycelium; +in +{ + options.services.mycelium = { + enable = lib.mkEnableOption "mycelium network"; + peers = lib.mkOption { + type = lib.types.listOf lib.types.str; + description = '' + List of peers to connect to, in the formats: + - `quic://[2001:0db8::1]:9651` + - `quic://192.0.2.1:9651` + - `tcp://[2001:0db8::1]:9651` + - `tcp://192.0.2.1:9651` + + If addHostedPublicNodes is set to true, the hosted public nodes will also be added. + ''; + default = [ ]; + }; + keyFile = lib.mkOption { + type = lib.types.nullOr lib.types.path; + default = null; + description = '' + Optional path to a file containing the mycelium key material. + If unset, the default location (`/var/lib/mycelium/key.bin`) will be used. + If no key exist at this location, it will be generated on startup. + ''; + }; + openFirewall = lib.mkOption { + type = lib.types.bool; + default = false; + description = "Open the firewall for mycelium"; + }; + package = lib.mkOption { + type = lib.types.package; + default = pkgs.mycelium; + defaultText = lib.literalExpression ''"''${pkgs.mycelium}"''; + description = "The mycelium package to use"; + }; + addHostedPublicNodes = lib.mkOption { + type = lib.types.bool; + default = true; + description = '' + Adds the hosted peers from https://github.com/threefoldtech/mycelium#hosted-public-nodes. + ''; + }; + }; + config = lib.mkIf cfg.enable { + networking.firewall.allowedTCPPorts = lib.optionals cfg.openFirewall [ 9651 ]; + networking.firewall.allowedUDPPorts = lib.optionals cfg.openFirewall [ 9650 9651 ]; + + systemd.services.mycelium = { + description = "Mycelium network"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + restartTriggers = [ + cfg.keyFile + ]; + + unitConfig.Documentation = "https://github.com/threefoldtech/mycelium"; + + serviceConfig = { + User = "mycelium"; + DynamicUser = true; + StateDirectory = "mycelium"; + ProtectHome = true; + ProtectSystem = true; + LoadCredential = lib.mkIf (cfg.keyFile != null) "keyfile:${cfg.keyFile}"; + SyslogIdentifier = "mycelium"; + AmbientCapabilities = [ "CAP_NET_ADMIN" ]; + MemoryDenyWriteExecute = true; + ProtectControlGroups = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + RestrictAddressFamilies = "AF_UNIX AF_INET AF_INET6 AF_NETLINK"; + RestrictNamespaces = true; + RestrictRealtime = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ "@system-service" "~@privileged @keyring" ]; + ExecStart = lib.concatStringsSep " " ([ + (lib.getExe cfg.package) + (if (cfg.keyFile != null) then + "--key-file \${CREDENTIALS_DIRECTORY}/keyfile" else + "--key-file %S/mycelium/key.bin" + ) + "--tun-name" + "mycelium" + ] ++ + (lib.optional (cfg.addHostedPublicNodes || cfg.peers != [ ]) "--peers") + ++ cfg.peers ++ (lib.optionals cfg.addHostedPublicNodes [ + "tcp://188.40.132.242:9651" # DE 01 + "tcp://[2a01:4f8:221:1e0b::2]:9651" + "quic://188.40.132.242:9651" + "quic://[2a01:4f8:221:1e0b::2]:9651" + + "tcp://136.243.47.186:9651" # DE 02 + "tcp://[2a01:4f8:212:fa6::2]:9651" + "quic://136.243.47.186:9651" + "quic://[2a01:4f8:212:fa6::2]:9651" + + "tcp://185.69.166.7:9651" # BE 03 + "tcp://[2a02:1802:5e:0:8478:51ff:fee2:3331]:9651" + "quic://185.69.166.7:9651" + "quic://[2a02:1802:5e:0:8478:51ff:fee2:3331]:9651" + + "tcp://185.69.166.8:9651" # BE 04 + "tcp://[2a02:1802:5e:0:8c9e:7dff:fec9:f0d2]:9651" + "quic://185.69.166.8:9651" + "quic://[2a02:1802:5e:0:8c9e:7dff:fec9:f0d2]:9651" + + "tcp://65.21.231.58:9651" # FI 05 + "tcp://[2a01:4f9:6a:1dc5::2]:9651" + "quic://65.21.231.58:9651" + "quic://[2a01:4f9:6a:1dc5::2]:9651" + + "tcp://65.109.18.113:9651" # FI 06 + "tcp://[2a01:4f9:5a:1042::2]:9651" + "quic://65.109.18.113:9651" + "quic://[2a01:4f9:5a:1042::2]:9651" + ])); + Restart = "always"; + RestartSec = 5; + TimeoutStopSec = 5; + }; + }; + }; + meta = { + maintainers = with lib.maintainers; [ flokli lassulus ]; + }; +} + diff --git a/nixos/modules/services/networking/networkmanager.nix b/nixos/modules/services/networking/networkmanager.nix index b7f0d9373608..573a02cbda9e 100644 --- a/nixos/modules/services/networking/networkmanager.nix +++ b/nixos/modules/services/networking/networkmanager.nix @@ -101,7 +101,23 @@ let pre-down = "pre-down.d/"; }; - macAddressOpt = mkOption { + macAddressOptWifi = mkOption { + type = types.either types.str (types.enum [ "permanent" "preserve" "random" "stable" "stable-ssid" ]); + default = "preserve"; + example = "00:11:22:33:44:55"; + description = lib.mdDoc '' + Set the MAC address of the interface. + + - `"XX:XX:XX:XX:XX:XX"`: MAC address of the interface + - `"permanent"`: Use the permanent MAC address of the device + - `"preserve"`: Don’t change the MAC address of the device upon activation + - `"random"`: Generate a randomized value upon each connect + - `"stable"`: Generate a stable, hashed MAC address + - `"stable-ssid"`: Generate a stable MAC addressed based on Wi-Fi network + ''; + }; + + macAddressOptEth = mkOption { type = types.either types.str (types.enum [ "permanent" "preserve" "random" "stable" ]); default = "preserve"; example = "00:11:22:33:44:55"; @@ -258,10 +274,10 @@ in ''; }; - ethernet.macAddress = macAddressOpt; + ethernet.macAddress = macAddressOptEth; wifi = { - macAddress = macAddressOpt; + macAddress = macAddressOptWifi; backend = mkOption { type = types.enum [ "wpa_supplicant" "iwd" ]; |