flake/nixos/modules/services/clash.nix

106 lines
3.4 KiB
Nix
Raw Normal View History

2023-12-21 03:59:19 +00:00
{
lib,
config,
pkgs,
...
}: let
cfg = config.services.clash;
in {
options.services.clash = {
2023-12-31 12:22:48 +00:00
enable = lib.mkEnableOption "Whether to enable Clash, A rule-based proxy in Go.";
2023-12-21 03:59:19 +00:00
package = lib.mkPackageOption pkgs "clash" {};
2023-12-31 12:22:48 +00:00
configFile = lib.mkOption {
2023-12-25 02:58:41 +00:00
default = null;
type = lib.types.nullOr lib.types.path;
2023-12-31 12:22:48 +00:00
description = "Configuration file to use.";
2023-12-25 02:58:41 +00:00
};
2023-12-31 12:22:48 +00:00
webui = lib.mkOption {
2023-12-25 02:58:41 +00:00
default = null;
type = lib.types.nullOr lib.types.path;
2023-12-31 12:22:48 +00:00
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
'';
2023-12-25 02:58:41 +00:00
};
extraOpts = lib.mkOption {
default = null;
type = lib.types.nullOr lib.types.str;
2023-12-31 12:22:48 +00:00
description = "Extra command line options to use.";
2023-12-25 02:58:41 +00:00
};
2024-01-15 11:50:57 +00:00
tunMode = lib.mkEnableOption ''
Whether to grant necessary permission for Clash's systemd service for TUN mode to function properly.
Keep in mind, that you still need to enable TUN mode manually in Clash's configuration.
'';
2023-12-21 03:59:19 +00:00
};
config = lib.mkIf cfg.enable {
### systemd service
systemd.services."clash" = {
2023-12-23 08:47:14 +00:00
description = "Clash daemon, A rule-based proxy in Go.";
2024-01-02 09:46:36 +00:00
documentation = ["https://clash.wiki/" "https://wiki.metacubex.one/"];
2023-12-21 03:59:19 +00:00
after = ["network-online.target"];
wantedBy = ["multi-user.target"];
2024-01-15 11:50:57 +00:00
serviceConfig =
{
ExecStart = builtins.concatStringsSep " " [
(lib.getExe cfg.package)
"-d /var/lib/private/clash"
(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)
];
2024-01-02 09:46:36 +00:00
2024-01-15 11:50:57 +00:00
DynamicUser = true;
StateDirectory = "clash";
LoadCredential = "config.yaml:${cfg.configFile}";
2023-12-23 08:47:14 +00:00
2024-01-15 11:50:57 +00:00
### 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 CAP_NET_RAW";
CapabilityBoundingSet = "CAP_NET_ADMIN CAP_NET_RAW";
PrivateDevices = false;
PrivateUsers = false;
RestrictAddressFamilies = "AF_INET AF_INET6 AF_NETLINK";
};
2023-12-21 03:59:19 +00:00
};
};
}