diff --git a/darwin/modules/default.nix b/darwin/modules/default.nix index eed7124..4a9b810 100644 --- a/darwin/modules/default.nix +++ b/darwin/modules/default.nix @@ -1 +1,6 @@ -_: {} +{...}: { + imports = [ + ./networking + ./services + ]; +} diff --git a/darwin/modules/networking/default.nix b/darwin/modules/networking/default.nix new file mode 100644 index 0000000..a2cf971 --- /dev/null +++ b/darwin/modules/networking/default.nix @@ -0,0 +1,5 @@ +{...}: { + imports = [ + ./proxy + ]; +} diff --git a/darwin/modules/networking/proxy/default.nix b/darwin/modules/networking/proxy/default.nix new file mode 100644 index 0000000..3d35330 --- /dev/null +++ b/darwin/modules/networking/proxy/default.nix @@ -0,0 +1,123 @@ +# Copy & pasted https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/config/networking.nix +{ + lib, + config, + ... +}: +with lib; let + cfg = config.networking; + opt = options.networking; +in { + options = { + networking.proxy = { + default = lib.mkOption { + type = types.nullOr types.str; + default = null; + description = lib.mdDoc '' + This option specifies the default value for httpProxy, httpsProxy, ftpProxy and rsyncProxy. + ''; + example = "http://127.0.0.1:3128"; + }; + + httpProxy = lib.mkOption { + type = types.nullOr types.str; + inherit (cfg.proxy) default; + defaultText = literalExpression "config.${opt.proxy.default}"; + description = lib.mdDoc '' + This option specifies the http_proxy environment variable. + ''; + example = "http://127.0.0.1:3128"; + }; + + httpsProxy = lib.mkOption { + type = types.nullOr types.str; + inherit (cfg.proxy) default; + defaultText = literalExpression "config.${opt.proxy.default}"; + description = lib.mdDoc '' + This option specifies the https_proxy environment variable. + ''; + example = "http://127.0.0.1:3128"; + }; + + ftpProxy = lib.mkOption { + type = types.nullOr types.str; + inherit (cfg.proxy) default; + defaultText = literalExpression "config.${opt.proxy.default}"; + description = lib.mdDoc '' + This option specifies the ftp_proxy environment variable. + ''; + example = "http://127.0.0.1:3128"; + }; + + rsyncProxy = lib.mkOption { + type = types.nullOr types.str; + inherit (cfg.proxy) default; + defaultText = literalExpression "config.${opt.proxy.default}"; + description = lib.mdDoc '' + This option specifies the rsync_proxy environment variable. + ''; + example = "http://127.0.0.1:3128"; + }; + + allProxy = lib.mkOption { + type = types.nullOr types.str; + inherit (cfg.proxy) default; + defaultText = literalExpression "config.${opt.proxy.default}"; + description = lib.mdDoc '' + This option specifies the all_proxy environment variable. + ''; + example = "http://127.0.0.1:3128"; + }; + + noProxy = lib.mkOption { + type = types.nullOr types.str; + default = null; + description = lib.mdDoc '' + This option specifies the no_proxy environment variable. + If a default proxy is used and noProxy is null, + then noProxy will be set to 127.0.0.1,localhost. + ''; + example = "127.0.0.1,localhost,.localdomain"; + }; + + envVars = lib.mkOption { + type = types.attrs; + internal = true; + default = {}; + description = lib.mdDoc '' + Environment variables used for the network proxy. + ''; + }; + }; + }; + + config = { + networking.proxy.envVars = + optionalAttrs (cfg.proxy.default != null) { + # other options already fallback to proxy.default + no_proxy = "127.0.0.1,localhost"; + } + // optionalAttrs (cfg.proxy.httpProxy != null) { + http_proxy = cfg.proxy.httpProxy; + } + // optionalAttrs (cfg.proxy.httpsProxy != null) { + https_proxy = cfg.proxy.httpsProxy; + } + // optionalAttrs (cfg.proxy.rsyncProxy != null) { + rsync_proxy = cfg.proxy.rsyncProxy; + } + // optionalAttrs (cfg.proxy.ftpProxy != null) { + ftp_proxy = cfg.proxy.ftpProxy; + } + // optionalAttrs (cfg.proxy.allProxy != null) { + all_proxy = cfg.proxy.allProxy; + } + // optionalAttrs (cfg.proxy.noProxy != null) { + no_proxy = cfg.proxy.noProxy; + }; + + # Install the proxy environment variables + environment.variables = cfg.proxy.envVars; + launchd.daemons."nix-daemon".environment = cfg.proxy.envVars; + }; +} diff --git a/darwin/modules/services/clash/default.nix b/darwin/modules/services/clash/default.nix new file mode 100644 index 0000000..0795c66 --- /dev/null +++ b/darwin/modules/services/clash/default.nix @@ -0,0 +1,58 @@ +{ + lib, + config, + pkgs, + ... +}: let + cfg = config.services.clash; +in { + options.services.clash = { + enable = lib.mkEnableOption "Whether to enable Clash, A rule-based proxy in Go."; + package = lib.mkPackageOption pkgs "clash" {}; + 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: + - http://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.string; + description = "Extra command line options to use."; + }; + }; + + config = lib.mkIf cfg.enable { + ### launchd service + # TODO: not run as root user + launchd.daemons."clash" = { + command = builtins.concatStringsSep " " [ + (lib.getExe cfg.package) + "-d /etc/clash" + (lib.optionalString (cfg.configFile != null) "-f ${cfg.configFile}") + (lib.optionalString (cfg.webui != null) "-ext-ui ${cfg.webui}") + (lib.optionalString (cfg.extraOpts != null) cfg.extraOpts) + ]; + serviceConfig = { + RunAtLoad = true; + KeepAlive.NetworkState = true; + }; + }; + }; +} diff --git a/darwin/modules/services/default.nix b/darwin/modules/services/default.nix new file mode 100644 index 0000000..044fd10 --- /dev/null +++ b/darwin/modules/services/default.nix @@ -0,0 +1,5 @@ +{...}: { + imports = [ + ./clash + ]; +} diff --git a/users/guanranwang/darwin/profiles/common/opt-in/clash-meta-client.nix b/users/guanranwang/darwin/profiles/common/opt-in/clash-meta-client.nix index d27f219..839383d 100644 --- a/users/guanranwang/darwin/profiles/common/opt-in/clash-meta-client.nix +++ b/users/guanranwang/darwin/profiles/common/opt-in/clash-meta-client.nix @@ -1,31 +1,14 @@ { inputs, pkgs, - lib, ... -}: let - env = { - "http_proxy" = "http://127.0.0.1:7890"; - "https_proxy" = "http://127.0.0.1:7890"; - "ftp_proxy" = "http://127.0.0.1:7890"; - "rsync_proxy" = "http://127.0.0.1:7890"; - }; -in { - # TODO: not run as root - - # Proxy environment variables - environment.variables = env; - launchd.daemons."nix-daemon".environment = env; - - # launchd service - launchd.daemons."clash-meta" = { - command = "${lib.getExe pkgs.clash-meta} -d /etc/clash-meta"; - serviceConfig = { - RunAtLoad = true; - KeepAlive.NetworkState = true; - }; +}: { + services.clash = { + enable = true; + package = pkgs.clash-meta; + webui = inputs.self.packages.${pkgs.stdenv.hostPlatform.system}.metacubexd; }; - # Web interface - environment.etc."clash-meta/metacubexd".source = inputs.self.packages.${pkgs.stdenv.hostPlatform.system}.metacubexd; + ### System proxy settings + networking.proxy.default = "http://127.0.0.1:7890/"; }