1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7
8with lib;
9
10let
11 cfg = config.services.tinyproxy;
12 mkValueStringTinyproxy =
13 with lib;
14 v:
15 if true == v then
16 "yes"
17 else if false == v then
18 "no"
19 else if types.path.check v then
20 ''"${v}"''
21 else
22 generators.mkValueStringDefault { } v;
23 mkKeyValueTinyproxy =
24 {
25 mkValueString ? mkValueStringDefault { },
26 }:
27 sep: k: v:
28 if null == v then "" else "${lib.strings.escape [ sep ] k}${sep}${mkValueString v}";
29
30 settingsFormat = (
31 pkgs.formats.keyValue {
32 mkKeyValue = mkKeyValueTinyproxy {
33 mkValueString = mkValueStringTinyproxy;
34 } " ";
35 listsAsDuplicateKeys = true;
36 }
37 );
38 configFile = settingsFormat.generate "tinyproxy.conf" cfg.settings;
39
40in
41{
42
43 options = {
44 services.tinyproxy = {
45 enable = mkEnableOption "Tinyproxy daemon";
46 package = mkPackageOption pkgs "tinyproxy" { };
47 settings = mkOption {
48 description = "Configuration for [tinyproxy](https://tinyproxy.github.io/).";
49 default = { };
50 example = literalExpression ''
51 {
52 Port 8888;
53 Listen 127.0.0.1;
54 Timeout 600;
55 Allow 127.0.0.1;
56 Anonymous = ['"Host"' '"Authorization"'];
57 ReversePath = '"/example/" "http://www.example.com/"';
58 }
59 '';
60 type = types.submodule (
61 { name, ... }:
62 {
63 freeformType = settingsFormat.type;
64 options = {
65 Listen = mkOption {
66 type = types.str;
67 default = "127.0.0.1";
68 description = ''
69 Specify which address to listen to.
70 '';
71 };
72 Port = mkOption {
73 type = types.int;
74 default = 8888;
75 description = ''
76 Specify which port to listen to.
77 '';
78 };
79 Anonymous = mkOption {
80 type = types.listOf types.str;
81 default = [ ];
82 description = ''
83 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.
84 '';
85 };
86 Filter = mkOption {
87 type = types.nullOr types.path;
88 default = null;
89 description = ''
90 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.
91 '';
92 };
93 };
94 }
95 );
96 };
97 };
98 };
99 config = mkIf cfg.enable {
100 systemd.services.tinyproxy = {
101 description = "TinyProxy daemon";
102 after = [ "network.target" ];
103 wantedBy = [ "multi-user.target" ];
104 serviceConfig = {
105 User = "tinyproxy";
106 Group = "tinyproxy";
107 Type = "simple";
108 ExecStart = "${getExe cfg.package} -d -c ${configFile}";
109 ExecReload = "${pkgs.coreutils}/bin/kill -SIGHUP $MAINPID";
110 KillSignal = "SIGINT";
111 TimeoutStopSec = "30s";
112 Restart = "on-failure";
113 };
114 };
115
116 users.users.tinyproxy = {
117 group = "tinyproxy";
118 isSystemUser = true;
119 };
120 users.groups.tinyproxy = { };
121 };
122 meta.maintainers = with maintainers; [ tcheronneau ];
123}