caddy int
This commit is contained in:
107
modules/nixos/services/caddy-internal/default.nix
Normal file
107
modules/nixos/services/caddy-internal/default.nix
Normal file
@@ -0,0 +1,107 @@
|
||||
{
|
||||
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;
|
||||
dataDir = "${cfg.configDir}/caddy";
|
||||
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
|
||||
];
|
||||
}
|
||||
39
modules/nixos/services/caddy-internal/sops.nix
Normal file
39
modules/nixos/services/caddy-internal/sops.nix
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
namespace,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.${namespace}.services.caddy-internal;
|
||||
|
||||
caddyUser = config.users.users.caddy.name;
|
||||
caddyGroup = config.users.users.caddy.group;
|
||||
|
||||
caddySecret = {
|
||||
owner = caddyUser;
|
||||
group = caddyGroup;
|
||||
sopsFile = lib.snowfall.fs.get-file "secrets/nuc-secrets.yaml";
|
||||
restartUnits = [ "caddy.service" ];
|
||||
};
|
||||
in
|
||||
{
|
||||
config = lib.mkIf cfg.enable {
|
||||
sops = {
|
||||
secrets = {
|
||||
# Add this key to secrets/nuc-secrets.yaml:
|
||||
# nuc/caddy/cloudflare-dns-api-token: <token>
|
||||
"nuc/caddy/cloudflare-dns-api-token" = caddySecret;
|
||||
};
|
||||
|
||||
templates."caddy-internal.env" = {
|
||||
content = ''
|
||||
CLOUDFLARE_DNS_API_TOKEN=${config.sops.placeholder."nuc/caddy/cloudflare-dns-api-token"}
|
||||
'';
|
||||
owner = caddyUser;
|
||||
group = caddyGroup;
|
||||
restartUnits = [ "caddy.service" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user