at master 2.6 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7 8with lib; 9 10{ 11 options = { 12 13 services.xray = { 14 enable = mkOption { 15 type = types.bool; 16 default = false; 17 description = '' 18 Whether to run xray server. 19 20 Either `settingsFile` or `settings` must be specified. 21 ''; 22 }; 23 24 package = mkPackageOption pkgs "xray" { }; 25 26 settingsFile = mkOption { 27 type = types.nullOr types.path; 28 default = null; 29 example = "/etc/xray/config.json"; 30 description = '' 31 The absolute path to the configuration file. 32 33 Either `settingsFile` or `settings` must be specified. 34 35 See <https://www.v2fly.org/en_US/config/overview.html>. 36 ''; 37 }; 38 39 settings = mkOption { 40 type = types.nullOr (types.attrsOf types.unspecified); 41 default = null; 42 example = { 43 inbounds = [ 44 { 45 port = 1080; 46 listen = "127.0.0.1"; 47 protocol = "http"; 48 } 49 ]; 50 outbounds = [ 51 { 52 protocol = "freedom"; 53 } 54 ]; 55 }; 56 description = '' 57 The configuration object. 58 59 Either `settingsFile` or `settings` must be specified. 60 61 See <https://www.v2fly.org/en_US/config/overview.html>. 62 ''; 63 }; 64 }; 65 66 }; 67 68 config = 69 let 70 cfg = config.services.xray; 71 settingsFile = 72 if cfg.settingsFile != null then 73 cfg.settingsFile 74 else 75 pkgs.writeTextFile { 76 name = "xray.json"; 77 text = builtins.toJSON cfg.settings; 78 checkPhase = '' 79 ${cfg.package}/bin/xray -test -config $out 80 ''; 81 }; 82 83 in 84 mkIf cfg.enable { 85 assertions = [ 86 { 87 assertion = (cfg.settingsFile == null) != (cfg.settings == null); 88 message = "Either but not both `settingsFile` and `settings` should be specified for xray."; 89 } 90 ]; 91 92 systemd.services.xray = { 93 description = "xray Daemon"; 94 after = [ "network.target" ]; 95 wantedBy = [ "multi-user.target" ]; 96 script = '' 97 exec "${cfg.package}/bin/xray" -config "$CREDENTIALS_DIRECTORY/config.json" 98 ''; 99 serviceConfig = { 100 DynamicUser = true; 101 LoadCredential = "config.json:${settingsFile}"; 102 CapabilityBoundingSet = "CAP_NET_ADMIN CAP_NET_BIND_SERVICE"; 103 AmbientCapabilities = "CAP_NET_ADMIN CAP_NET_BIND_SERVICE"; 104 NoNewPrivileges = true; 105 }; 106 }; 107 }; 108}