1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7
8with lib;
9
10let
11
12 cfg = config.services.mtprotoproxy;
13
14 configOpts =
15 {
16 PORT = cfg.port;
17 USERS = cfg.users;
18 SECURE_ONLY = cfg.secureOnly;
19 }
20 // lib.optionalAttrs (cfg.adTag != null) { AD_TAG = cfg.adTag; }
21 // cfg.extraConfig;
22
23 convertOption =
24 opt:
25 if isString opt || isInt opt then
26 builtins.toJSON opt
27 else if isBool opt then
28 if opt then "True" else "False"
29 else if isList opt then
30 "[" + concatMapStringsSep "," convertOption opt + "]"
31 else if isAttrs opt then
32 "{"
33 + concatStringsSep "," (
34 mapAttrsToList (name: opt: "${builtins.toJSON name}: ${convertOption opt}") opt
35 )
36 + "}"
37 else
38 throw "Invalid option type";
39
40 configFile = pkgs.writeText "config.py" (
41 concatStringsSep "\n" (mapAttrsToList (name: opt: "${name} = ${convertOption opt}") configOpts)
42 );
43
44in
45
46{
47
48 ###### interface
49
50 options = {
51
52 services.mtprotoproxy = {
53
54 enable = mkEnableOption "mtprotoproxy";
55
56 port = mkOption {
57 type = types.port;
58 default = 3256;
59 description = ''
60 TCP port to accept mtproto connections on.
61 '';
62 };
63
64 users = mkOption {
65 type = types.attrsOf types.str;
66 example = {
67 tg = "00000000000000000000000000000000";
68 tg2 = "0123456789abcdef0123456789abcdef";
69 };
70 description = ''
71 Allowed users and their secrets. A secret is a 32 characters long hex string.
72 '';
73 };
74
75 secureOnly = mkOption {
76 type = types.bool;
77 default = true;
78 description = ''
79 Don't allow users to connect in non-secure mode (without random padding).
80 '';
81 };
82
83 adTag = mkOption {
84 type = types.nullOr types.str;
85 default = null;
86 # Taken from mtproxyproto's repo.
87 example = "3c09c680b76ee91a4c25ad51f742267d";
88 description = ''
89 Tag for advertising that can be obtained from @MTProxybot.
90 '';
91 };
92
93 extraConfig = mkOption {
94 type = types.attrs;
95 default = { };
96 example = {
97 STATS_PRINT_PERIOD = 600;
98 };
99 description = ''
100 Extra configuration options for mtprotoproxy.
101 '';
102 };
103
104 };
105
106 };
107
108 ###### implementation
109
110 config = mkIf cfg.enable {
111
112 systemd.services.mtprotoproxy = {
113 description = "MTProto Proxy Daemon";
114 wantedBy = [ "multi-user.target" ];
115 serviceConfig = {
116 ExecStart = "${pkgs.mtprotoproxy}/bin/mtprotoproxy ${configFile}";
117 DynamicUser = true;
118 };
119 };
120
121 };
122
123}