-
Notifications
You must be signed in to change notification settings - Fork 4
/
tinyproxy.nix
150 lines (137 loc) · 4.86 KB
/
tinyproxy.nix
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# Inspired from https://github.com/NixOS/nixpkgs/pull/231152 but made it so we can have multiple instances.
{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.shb.tinyproxy;
mkValueStringTinyproxy = with lib; v:
if true == v then "yes"
else if false == v then "no"
else generators.mkValueStringDefault {} v;
mkKeyValueTinyproxy = {
mkValueString ? mkValueStringDefault {}
}: sep: k: v:
if null == v then ""
else "${lib.strings.escape [sep] k}${sep}${mkValueString v}";
settingsFormat = (pkgs.formats.keyValue {
mkKeyValue = mkKeyValueTinyproxy {
mkValueString = mkValueStringTinyproxy;
} " ";
listsAsDuplicateKeys= true;
});
configFile = name: cfg: settingsFormat.generate "tinyproxy-${name}.conf" cfg.settings;
someEnabled = any (mapAttrsToList (name: c: c.enable) cfg);
in
{
options =
let
instanceOption = types.submodule {
options = {
enable = mkEnableOption "Tinyproxy daemon";
package = mkPackageOptionMD pkgs "tinyproxy" {};
dynamicBindFile = mkOption {
description = ''
File holding the IP to bind to.
'';
default = "";
};
settings = mkOption {
description = ''
Configuration for [tinyproxy](https://tinyproxy.github.io/).
'';
default = { };
example = literalExpression ''{
Port 8888;
Listen 127.0.0.1;
Timeout 600;
Allow 127.0.0.1;
Anonymous = ['"Host"' '"Authorization"'];
ReversePath = '"/example/" "http://www.example.com/"';
}'';
type = types.submodule ({name, ...}: {
freeformType = settingsFormat.type;
options = {
Listen = mkOption {
type = types.str;
default = "127.0.0.1";
description = ''
Specify which address to listen to.
'';
};
Port = mkOption {
type = types.int;
default = 8888;
description = ''
Specify which port to listen to.
'';
};
Anonymous = mkOption {
type = types.listOf types.str;
default = [];
description = ''
If an `Anonymous` keyword is present, then anonymous proxying is enabled. The
headers listed with `Anonymous` are allowed through, while all others are denied.
If no Anonymous keyword is present, then all headers are allowed through. You must
include quotes around the headers.
'';
};
Filter = mkOption {
type = types.nullOr types.path;
default = null;
description = ''
Tinyproxy supports filtering of web sites based on URLs or domains. This option
specifies the location of the file containing the filter rules, one rule per line.
'';
};
};
});
};
};
};
in
{
shb.tinyproxy = mkOption {
description = "Tinyproxy instances.";
default = {};
type = types.attrsOf instanceOption;
};
};
config = {
systemd.services =
let
instanceConfig = name: c: mkIf c.enable {
"tinyproxy-${name}" = {
description = "TinyProxy daemon - instance ${name}";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
User = "tinyproxy";
Group = "tinyproxy";
Type = "simple";
ExecStart = "${getExe c.package} -d -c /etc/tinyproxy/${name}.conf";
ExecReload = "${pkgs.coreutils}/bin/kill -SIGHUP $MAINPID";
KillSignal = "SIGINT";
TimeoutStopSec = "30s";
Restart = "on-failure";
RestartSec = "1s";
RestartSteps = "3";
RestartMaxDelaySec = "10s";
ConfigurationDirectory = "tinyproxy";
};
preStart = concatStringsSep "\n" ([
"cat ${configFile name c} > /etc/tinyproxy/${name}.conf"
] ++ optionals (c.dynamicBindFile != "") [
"echo -n 'Bind ' >> /etc/tinyproxy/${name}.conf"
"cat ${c.dynamicBindFile} >> /etc/tinyproxy/${name}.conf"
]);
};
};
in
mkMerge (mapAttrsToList instanceConfig cfg);
users.users.tinyproxy = {
group = "tinyproxy";
isSystemUser = true;
};
users.groups.tinyproxy = {};
};
meta.maintainers = with maintainers; [ tcheronneau ];
}