at 25.11-pre 3.7 kB view raw
1# NOTE: 2# cfg.configFile contains secrets such as proxy servers' credential! 3# we dont want plaintext secrets in world-readable `/nix/store`. 4 5{ 6 lib, 7 config, 8 pkgs, 9 ... 10}: 11let 12 cfg = config.services.mihomo; 13in 14{ 15 options.services.mihomo = { 16 enable = lib.mkEnableOption "Mihomo, A rule-based proxy in Go"; 17 18 package = lib.mkPackageOption pkgs "mihomo" { }; 19 20 configFile = lib.mkOption { 21 type = lib.types.path; 22 description = "Configuration file to use."; 23 }; 24 25 webui = lib.mkOption { 26 default = null; 27 type = lib.types.nullOr lib.types.path; 28 example = lib.literalExpression "pkgs.metacubexd"; 29 description = '' 30 Local web interface to use. 31 32 You can also use the following website: 33 - metacubexd: 34 - https://d.metacubex.one 35 - https://metacubex.github.io/metacubexd 36 - https://metacubexd.pages.dev 37 - yacd: 38 - https://yacd.haishan.me 39 - clash-dashboard: 40 - https://clash.razord.top 41 ''; 42 }; 43 44 extraOpts = lib.mkOption { 45 default = null; 46 type = lib.types.nullOr lib.types.str; 47 description = "Extra command line options to use."; 48 }; 49 50 tunMode = lib.mkEnableOption '' 51 necessary permission for Mihomo's systemd service for TUN mode to function properly. 52 53 Keep in mind, that you still need to enable TUN mode manually in Mihomo's configuration 54 ''; 55 }; 56 57 config = lib.mkIf cfg.enable { 58 ### systemd service 59 systemd.services."mihomo" = { 60 description = "Mihomo daemon, A rule-based proxy in Go."; 61 documentation = [ "https://wiki.metacubex.one/" ]; 62 requires = [ "network-online.target" ]; 63 after = [ "network-online.target" ]; 64 wantedBy = [ "multi-user.target" ]; 65 serviceConfig = 66 { 67 ExecStart = lib.concatStringsSep " " [ 68 (lib.getExe cfg.package) 69 "-d /var/lib/private/mihomo" 70 "-f \${CREDENTIALS_DIRECTORY}/config.yaml" 71 (lib.optionalString (cfg.webui != null) "-ext-ui ${cfg.webui}") 72 (lib.optionalString (cfg.extraOpts != null) cfg.extraOpts) 73 ]; 74 75 DynamicUser = true; 76 StateDirectory = "mihomo"; 77 LoadCredential = "config.yaml:${cfg.configFile}"; 78 79 ### Hardening 80 AmbientCapabilities = ""; 81 CapabilityBoundingSet = ""; 82 DeviceAllow = ""; 83 LockPersonality = true; 84 MemoryDenyWriteExecute = true; 85 NoNewPrivileges = true; 86 PrivateDevices = true; 87 PrivateMounts = true; 88 PrivateTmp = true; 89 PrivateUsers = true; 90 ProcSubset = "pid"; 91 ProtectClock = true; 92 ProtectControlGroups = true; 93 ProtectHome = true; 94 ProtectHostname = true; 95 ProtectKernelLogs = true; 96 ProtectKernelModules = true; 97 ProtectKernelTunables = true; 98 ProtectProc = "invisible"; 99 ProtectSystem = "strict"; 100 RestrictRealtime = true; 101 RestrictSUIDSGID = true; 102 RestrictNamespaces = true; 103 RestrictAddressFamilies = "AF_INET AF_INET6"; 104 SystemCallArchitectures = "native"; 105 SystemCallFilter = "@system-service bpf"; 106 UMask = "0077"; 107 } 108 // lib.optionalAttrs cfg.tunMode { 109 AmbientCapabilities = "CAP_NET_ADMIN"; 110 CapabilityBoundingSet = "CAP_NET_ADMIN"; 111 PrivateDevices = false; 112 PrivateUsers = false; 113 RestrictAddressFamilies = "AF_INET AF_INET6 AF_NETLINK"; 114 }; 115 }; 116 }; 117 118 meta.maintainers = with lib.maintainers; [ Guanran928 ]; 119}