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  };
30
31  proxyLine = config: e:
32    if e.resolution.kind == "import"
33    then "import ${config.vaultix.templates.${templateName e.domain}.path}"
34    else let
35      upstream =
36        if e.upstream != null
37        then e.upstream
38        else "";
39    in "reverse_proxy http://${e.resolution.address}:${toString e.port}${upstream}";
40
41  entryLines = config: e: [(proxyLine config e)];
42
43  entryBlock = config: e: let
44    lines = entryLines config e;
45    directive =
46      if e.stripPath
47      then "handle_path"
48      else "handle";
49    mkBlock = p: "${directive} ${p} {\n${lib.concatMapStrings (l: "\t${l}\n") lines}}";
50  in [
51    (mkBlock e.path)
52    (mkBlock "${e.path}/*")
53  ];
54
55  fallbackBlock = config: e: let
56    lines = entryLines config e;
57  in "handle {\n${lib.concatMapStrings (l: "\t${l}\n") lines}}";
58
59  forwardAuthBlock = ''
60    forward_auth unix//run/tailscale.nginx-auth.sock {
61        uri /auth
62        header_up Remote-Addr {remote_host}
63        header_up Remote-Port {remote_port}
64        header_up Original-URI {uri}
65        copy_headers {
66            Tailscale-User>X-Webauth-User
67            Tailscale-Name>X-Webauth-Name
68            Tailscale-Login>X-Webauth-Login
69            Tailscale-Tailnet>X-Webauth-Tailnet
70            Tailscale-Profile-Picture>X-Webauth-Profile-Picture
71        }
72    }
73  '';
74}