main
1{lib, ...}: rec {
2 # Wrap IPv6 addresses in brackets so they can be used in a URL authority.
3 fmtAddr = isV6: addr:
4 if isV6
5 then "[${addr}]"
6 else addr;
7
8 sanitize = lib.replaceStrings ["." ":" "/" "*"] ["-" "-" "-" "-"];
9
10 templateName = domain: "caddy-reverse-proxy-${sanitize domain}";
11
12 normalizePath = p: let
13 p' =
14 if lib.hasPrefix "/" p
15 then p
16 else "/${p}";
17 in
18 lib.removeSuffix "/" p';
19
20 mkEntry = resolution: domain: conf: {
21 inherit domain resolution;
22 port = conf.port;
23 path =
24 if conf ? path && conf.path != null
25 then normalizePath conf.path
26 else null;
27 stripPath = conf.stripPath or false;
28 upstream = conf.upstream or null;
29 maxSize = conf.maxSize or null;
30 };
31
32 proxyLine = config: e:
33 if e.resolution.kind == "import"
34 then "import ${config.vaultix.templates.${templateName e.domain}.path}"
35 else let
36 upstream =
37 if e.upstream != null
38 then e.upstream
39 else "";
40 in "reverse_proxy http://${e.resolution.address}:${toString e.port}${upstream}";
41
42 maxSizeLines = e:
43 if e.maxSize == null
44 then []
45 else [
46 "request_body {"
47 " max_size ${e.maxSize}"
48 "}"
49 ];
50
51 entryLines = config: e: maxSizeLines e ++ [(proxyLine config e)];
52
53 entryBlock = config: e: let
54 lines = entryLines config e;
55 directive =
56 if e.stripPath
57 then "handle_path"
58 else "handle";
59 mkBlock = p: "${directive} ${p} {\n${lib.concatMapStrings (l: "\t${l}\n") lines}}";
60 in [
61 (mkBlock e.path)
62 (mkBlock "${e.path}/*")
63 ];
64
65 fallbackBlock = config: e: let
66 lines = entryLines config e;
67 in "handle {\n${lib.concatMapStrings (l: "\t${l}\n") lines}}";
68
69 forwardAuthBlock = let
70 podmanRanges = [
71 "10.88.0.0/16"
72 "10.89.0.0/16"
73 "10.90.0.0/16"
74 "10.91.0.0/16"
75 "10.92.0.0/16"
76 "10.93.0.0/16"
77 "10.94.0.0/16"
78 "10.95.0.0/16"
79 "fd00::/8"
80 ];
81 in ''
82 @tailnet-clients {
83 not remote_ip ${lib.concatStringsSep " " podmanRanges}
84 }
85 forward_auth @tailnet-clients unix//run/tailscale.nginx-auth.sock {
86 uri /auth
87 header_up Remote-Addr {remote_host}
88 header_up Remote-Port {remote_port}
89 header_up Original-URI {uri}
90 copy_headers {
91 Tailscale-User>X-Webauth-User
92 Tailscale-Name>X-Webauth-Name
93 Tailscale-Login>X-Webauth-Login
94 Tailscale-Tailnet>X-Webauth-Tailnet
95 Tailscale-Profile-Picture>X-Webauth-Profile-Picture
96 }
97 }
98 '';
99}