diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 3eece09f1ae..683be7f20ad 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -610,6 +610,7 @@ ./services/networking/morty.nix ./services/networking/miredo.nix ./services/networking/mstpd.nix + ./services/networking/mtprotoproxy.nix ./services/networking/murmur.nix ./services/networking/mxisd.nix ./services/networking/namecoind.nix diff --git a/nixos/modules/services/networking/mtprotoproxy.nix b/nixos/modules/services/networking/mtprotoproxy.nix new file mode 100644 index 00000000000..24bf33815da --- /dev/null +++ b/nixos/modules/services/networking/mtprotoproxy.nix @@ -0,0 +1,110 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.mtprotoproxy; + + configOpts = { + PORT = cfg.port; + USERS = cfg.users; + SECURE_ONLY = cfg.secureOnly; + } // lib.optionalAttrs (cfg.adTag != null) { AD_TAG = cfg.adTag; } + // cfg.extraConfig; + + convertOption = opt: + if isString opt || isInt opt then + builtins.toJSON opt + else if isBool opt then + if opt then "True" else "False" + else if isList opt then + "[" + concatMapStringsSep "," convertOption opt + "]" + else if isAttrs opt then + "{" + concatStringsSep "," (mapAttrsToList (name: opt: "${builtins.toJSON name}: ${convertOption opt}") opt) + "}" + else + throw "Invalid option type"; + + configFile = pkgs.writeText "config.py" (concatStringsSep "\n" (mapAttrsToList (name: opt: "${name} = ${convertOption opt}") configOpts)); + +in + +{ + + ###### interface + + options = { + + services.mtprotoproxy = { + + enable = mkEnableOption "mtprotoproxy"; + + port = mkOption { + type = types.int; + default = 3256; + description = '' + TCP port to accept mtproto connections on. + ''; + }; + + users = mkOption { + type = types.attrsOf types.str; + example = { + "tg" = "00000000000000000000000000000000"; + "tg2" = "0123456789abcdef0123456789abcdef"; + }; + description = '' + Allowed users and their secrets. A secret is a 32 characters long hex string. + ''; + }; + + secureOnly = mkOption { + type = types.bool; + default = true; + description = '' + Don't allow users to connect in non-secure mode (without random padding). + ''; + }; + + adTag = mkOption { + type = types.nullOr types.str; + default = null; + # Taken from mtproxyproto's repo. + example = "3c09c680b76ee91a4c25ad51f742267d"; + description = '' + Tag for advertising that can be obtained from @MTProxybot. + ''; + }; + + extraConfig = mkOption { + type = types.attrs; + default = {}; + example = { + "STATS_PRINT_PERIOD" = 600; + }; + description = '' + Extra configuration options for mtprotoproxy. + ''; + }; + + }; + + }; + + + ###### implementation + + config = mkIf cfg.enable { + + systemd.services.mtprotoproxy = { + description = "MTProto Proxy Daemon"; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + ExecStart = "${pkgs.mtprotoproxy}/bin/mtprotoproxy ${configFile}"; + DynamicUser = true; + }; + }; + + }; + +}