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