107 lines
2.7 KiB
Nix
107 lines
2.7 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
namespace,
|
|
...
|
|
}:
|
|
with lib;
|
|
let
|
|
name = "caddy-internal";
|
|
cfg = config.${namespace}.services.${name};
|
|
net = lib.${namespace}.network;
|
|
|
|
caddyPackage = pkgs.caddy.withPlugins {
|
|
plugins = [
|
|
"github.com/caddy-dns/cloudflare@v0.2.3"
|
|
];
|
|
hash = "sha256-20o+14cn/eeLuf1c8uGE1ODRZGC0oxocaIVlv4tFSvA=";
|
|
};
|
|
|
|
# Build a virtual-host block for one proxy entry.
|
|
# Access is restricted to LAN + Nebula subnets; all other clients get 403.
|
|
mkProxyBlock =
|
|
entryName: proxyCfg:
|
|
let
|
|
fqdn = "${proxyCfg.subdomain}.${net.domain}";
|
|
in
|
|
''
|
|
@${entryName} host ${fqdn}
|
|
handle @${entryName} {
|
|
@${entryName}_internal {
|
|
remote_ip ${net.subnet.lan} ${net.subnet.nebula}
|
|
host ${fqdn}
|
|
}
|
|
handle @${entryName}_internal {
|
|
reverse_proxy ${proxyCfg.upstream}
|
|
${proxyCfg.extraCaddyConfig}
|
|
}
|
|
handle {
|
|
respond "Forbidden" 403
|
|
}
|
|
}
|
|
'';
|
|
|
|
proxyBlocks = lib.concatStringsSep "\n" (
|
|
lib.mapAttrsToList mkProxyBlock (lib.filterAttrs (_: p: p.enable) cfg.proxies)
|
|
);
|
|
|
|
caddy-internal = lib.${namespace}.mkModule {
|
|
inherit config name;
|
|
description = "Internal-only Caddy reverse proxy with HTTPS via Cloudflare DNS challenge";
|
|
options = {
|
|
proxies = mkOption {
|
|
type = types.attrsOf (
|
|
types.submodule {
|
|
options = {
|
|
enable = lib.${namespace}.mkBoolOpt true "Whether to enable this proxy entry";
|
|
subdomain = lib.${namespace}.mkOpt types.str "" "Subdomain under ${net.domain}";
|
|
upstream = lib.${namespace}.mkOpt types.str "" "Upstream address (e.g. http://127.0.0.1:8123)";
|
|
extraCaddyConfig =
|
|
lib.${namespace}.mkOpt types.lines ""
|
|
"Extra Caddyfile directives for this entry";
|
|
};
|
|
}
|
|
);
|
|
default = { };
|
|
description = "Internal services to proxy, each restricted to LAN + Nebula subnets";
|
|
};
|
|
};
|
|
moduleConfig = {
|
|
services.caddy = {
|
|
enable = true;
|
|
package = caddyPackage;
|
|
environmentFile = config.sops.templates."caddy-internal.env".path;
|
|
email = "jalle008@proton.me";
|
|
enableReload = true;
|
|
globalConfig = ''
|
|
metrics
|
|
http_port 80
|
|
https_port 443
|
|
default_bind 0.0.0.0
|
|
'';
|
|
virtualHosts."*.${net.domain}" = {
|
|
extraConfig = ''
|
|
tls {
|
|
dns cloudflare {$CLOUDFLARE_DNS_API_TOKEN}
|
|
}
|
|
|
|
${proxyBlocks}
|
|
'';
|
|
};
|
|
};
|
|
|
|
networking.firewall.allowedTCPPorts = [
|
|
80
|
|
443
|
|
];
|
|
};
|
|
};
|
|
in
|
|
{
|
|
imports = [
|
|
caddy-internal
|
|
./sops.nix
|
|
];
|
|
}
|