nixos-config/modules/caddy-proxy/default.nix

96 lines
2 KiB
Nix

{
pkgs,
config,
lib,
...
}:
with lib;
let
cfg = config.eboskma.caddy-proxy;
proxyHost = types.submodule {
options = {
externalHostname = mkOption {
description = "Hostname where this service should be reached";
type = types.str;
};
proxyAddress = mkOption {
description = "Internal address where this service is reachable";
type = types.str;
};
external = mkEnableOption "Make this host externally reachable.";
};
};
cloudflare-tls = ''
tls {
dns cloudflare {env.CF_API_TOKEN}
resolvers 1.1.1.1
}
'';
mkProxyHost = target: {
extraConfig = ''
reverse_proxy ${target}
${cloudflare-tls}
'';
};
mkLocalProxyHost = target: {
extraConfig = ''
@local_or_ts {
remote_ip 10.0.0.0/24 100.64.0.0/10 fd7a:115c:a1e0::/96 fd7a:115c:a1e0:ab12::/64
}
handle @local_or_ts {
reverse_proxy ${target}
}
handle {
error "Nope." 403
}
${cloudflare-tls}
'';
};
in
{
options.eboskma.caddy-proxy = {
enable = mkEnableOption "Caddy proxy";
package = mkPackageOption pkgs "caddy" { };
proxyHosts = mkOption {
description = "Proxy hosts";
type = types.listOf proxyHost;
};
};
config = mkIf cfg.enable {
services.caddy = {
enable = true;
package = cfg.package;
email = "erwin@datarift.nl";
acmeCA = "https://acme-v02.api.letsencrypt.org/directory";
virtualHosts = builtins.listToAttrs (
map (
host:
let
mkProxy = if host ? external && host.external then mkProxyHost else mkLocalProxyHost;
in
{
name = host.externalHostname;
value = mkProxy host.proxyAddress;
}
) cfg.proxyHosts
);
};
systemd.services.caddy.serviceConfig.EnvironmentFile = [ config.sops.secrets.caddy-env.path ];
networking.firewall.allowedTCPPorts = [
80
443
];
};
}