about summary refs log tree commit diff
path: root/nixpkgs/nixos/modules/services/networking/mihomo.nix
blob: ae700603b52906448870616e2629f221e7300357 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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 ];
}