199 lines
5.3 KiB
Nix
199 lines
5.3 KiB
Nix
{
|
|
lib,
|
|
config,
|
|
pkgs,
|
|
sops-nix,
|
|
...
|
|
}:
|
|
with lib;
|
|
let
|
|
p = config.sops.placeholder;
|
|
domain = p.domainName;
|
|
svc = "caddy.service";
|
|
caddyLogPath = "/var/log/caddy";
|
|
caddyLog = sub: if (sub != "") then ''
|
|
log {
|
|
hostnames ${sub}.${domain}
|
|
level INFO
|
|
format json
|
|
output file ${caddyLogPath}/${sub}.${domain}.log {
|
|
roll_size 100MiB
|
|
roll_keep 5
|
|
roll_keep_for 240d
|
|
}
|
|
}''
|
|
else
|
|
''
|
|
log {
|
|
hostnames ${domain}
|
|
level INFO
|
|
format json
|
|
output file ${caddyLogPath}/${domain}.log {
|
|
roll_size 100MiB
|
|
roll_keep 5
|
|
roll_keep_for 240d
|
|
}
|
|
}'';
|
|
in {
|
|
networking.firewall.allowedTCPPorts = [80 443];
|
|
|
|
services = {
|
|
caddy = {
|
|
enable = true;
|
|
configFile = config.sops.templates.caddyPls.path;
|
|
adapter = "caddyfile";
|
|
};
|
|
};
|
|
|
|
systemd = {
|
|
services = {
|
|
caddy = {
|
|
description = "Caddy web server";
|
|
after = ["network-online.target" "sops-nix.service"];
|
|
wants = ["network-online.target"];
|
|
wantedBy = ["multi-user.target"];
|
|
serviceConfig = {
|
|
TimeoutStopSec = "7s";
|
|
# LimitNOFILE = 1048576;
|
|
# LimitNPROC = 512;
|
|
PrivateTmp = true;
|
|
# ProtectSystem = "full";
|
|
AmbientCapabilities = "cap_net_bind_service";
|
|
};
|
|
};
|
|
caddy-watcher = {
|
|
description = "Caddy watcher";
|
|
wantedBy = ["multi-user.target"];
|
|
serviceConfig = {
|
|
Type = "oneshot";
|
|
ExecStart = "systemctl restart ${svc}";
|
|
};
|
|
};
|
|
};
|
|
# restart Caddy on config file change.
|
|
paths.caddy-watcher = {
|
|
pathConfig = {
|
|
PathChanged = config.sops.templates.caddyPls.path;
|
|
# Unit = svc;
|
|
};
|
|
wantedBy = ["paths.target"];
|
|
};
|
|
};
|
|
|
|
sops.secrets = {
|
|
"caddy/email".restartUnits = [svc];
|
|
"desecToken".restartUnits = [svc];
|
|
"domainName".restartUnits = [svc];
|
|
};
|
|
|
|
sops.templates.caddyPls = {
|
|
owner = config.systemd.services.caddy.serviceConfig.User;
|
|
content = ''
|
|
(hsts) {
|
|
header Strict-Transport-Security "max-age=86400; preload"
|
|
# header Strict-Transport-Security "max-age=15552000; preload"
|
|
# header Strict-Transport-Security "max-age=3600"
|
|
# header Strict-Transport-Security "max-age=86400"
|
|
}
|
|
|
|
(headersCommon) {
|
|
header / {
|
|
x-frame-options "sameorigin"
|
|
x-content-type-options "nosniff"
|
|
x-xss-protection "1; mode=block"
|
|
content-security-policy "
|
|
upgrade-insecure-requests;
|
|
default-src 'self';
|
|
style-src 'self';
|
|
script-src 'self';
|
|
font-src 'self';
|
|
img-src data: 'self';
|
|
form-action 'self';
|
|
connect-src 'self';
|
|
frame-ancestors 'none';
|
|
"
|
|
cross-origin-opener-policy "same-origin"
|
|
permissions-policy "geolocation=(), midi=(), sync-xhr=(), microphone=(), camera=(), magnetometer=(), gyroscope=(), fullscreen=(self), payment=()"
|
|
referrer-policy "strict-origin-when-cross-origin"
|
|
-Server
|
|
-server
|
|
Permissions-Policy interest-cohort=()
|
|
# Strict-Transport-Security "max-age=86400"
|
|
}
|
|
}
|
|
|
|
(authentik) {
|
|
# Always forward outpost path to actual outpost
|
|
reverse_proxy /outpost.goauthentik.io/* https://auth.${p.domainName}
|
|
|
|
# Forward authentication to outpost
|
|
forward_auth https://auth.${p.domainName} {
|
|
uri /outpost.goauthentik.io/auth/caddy
|
|
|
|
# Capitalization of the headers is important, otherwise they will be empty
|
|
copy_headers X-Authentik-Username X-Authentik-Groups X-Authentik-Email X-Authentik-Name X-Authentik-Uid X-Authentik-Jwt X-Authentik-Meta-Jwks X-Authentik-Meta-Outpost X-Authentik-Meta-Provider X-Authentik-Meta-App X-Authentik-Meta-Version
|
|
}
|
|
}
|
|
|
|
(tlsCommon) {
|
|
tls {
|
|
dns desec {
|
|
token ${p.desecToken}
|
|
}
|
|
# propagation_timeout 30s
|
|
# propagation_timeout 1m
|
|
# propagation_timeout 2m
|
|
propagation_timeout -1
|
|
#propagation_delay 30s
|
|
propagation_delay 90s
|
|
curves x25519
|
|
key_type p384
|
|
protocols tls1.2 tls1.3
|
|
# resolvers 1.1.1.1
|
|
# resolvers 8.8.8.8 8.8.4.4
|
|
# resolvers 1.1.1.1 8.8.8.8
|
|
}
|
|
}
|
|
|
|
|
|
{
|
|
# acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
|
|
#admin off
|
|
# servers {
|
|
metrics
|
|
# }
|
|
acme_dns desec {
|
|
token ${p.desecToken}
|
|
}
|
|
email ${p."caddy/email"}
|
|
# grace_period 60s
|
|
grace_period 30s
|
|
|
|
log default {
|
|
output stdout
|
|
format json
|
|
# level INFO
|
|
level DEBUG
|
|
}
|
|
|
|
# import tlsCommon
|
|
}
|
|
|
|
# *.${domain}, ${domain} {
|
|
*.${domain} {
|
|
import tlsCommon
|
|
|
|
${caddyLog "ollama"}
|
|
@ollama host ollama.${domain}
|
|
handle @ollama {
|
|
encode zstd br
|
|
import headersCommon
|
|
import hsts
|
|
reverse_proxy localhost:${toString config.services.ollama.port}
|
|
}
|
|
|
|
} # end *.${domain}, ${domain}
|
|
'';
|
|
};
|
|
}
|