338 lines
9.2 KiB
Nix
338 lines
9.2 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
|
|
}
|
|
}'';
|
|
# a little script to dynamically replace the domain tag with an actual domain
|
|
# under which it's accessed.
|
|
#script = ''
|
|
# const domain = window.location.hostname;
|
|
# document.getElementById("domain").textContent="auth."+domain;
|
|
#'';
|
|
# cat - | base64 -w0
|
|
scriptB64 = "ICAgIGNvbnN0IGRvbWFpbiA9IHdpbmRvdy5sb2NhdGlvbi5ob3N0bmFtZTsKICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJkb21haW4iKS50ZXh0Q29udGVudD0iYXV0aC4iK2RvbWFpbjsK";
|
|
landingPage = ''
|
|
<<HTML
|
|
<!doctype html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, height=device-height initial-scale=1.0, minimum-scale=1.0">
|
|
<title>Welcome! @( * O * )@</title>
|
|
<style>
|
|
.cursor {
|
|
display: inline-block;
|
|
background-color: black;
|
|
animation-name: cursor;
|
|
animation-duration: .8s;
|
|
animation-iteration-count: infinite;
|
|
}
|
|
@keyframes cursor {
|
|
0% { background-color: #ffffff; }
|
|
20% { background-color: #555; }
|
|
50% { background-color: #555; }
|
|
60% { background-color: #ffffff; }
|
|
100% { background-color: #ffffff; }
|
|
}
|
|
</style>
|
|
<script defer src="data:text/javascript;base64,${scriptB64}"></script>
|
|
</head>
|
|
<body>
|
|
<pre style="font-family: monospace">
|
|
┏━━━━━━━━━━━━━━━━┑
|
|
┃┏━━━ @ ━━━ @ ━━┓┃
|
|
┃┃ ┃┃
|
|
┃┃ $ Welcome! <div class="cursor"> </div> ┃┃
|
|
┃┃ ┃┃
|
|
┃┗━━━ ╰─────╯ ━━┛┃
|
|
┗━━━━━━━━━━━━━━━━┛
|
|
╲ ############### ╲
|
|
╲ ############### ╲
|
|
╲ ############### ╲
|
|
━━━━━━━━━━━━━━━━━━
|
|
|
|
Please log in using <code id=domain>auth.<domain></code> to use the services.
|
|
</pre>
|
|
</body>
|
|
</html>
|
|
HTML
|
|
'';
|
|
in
|
|
{
|
|
networking.firewall.allowedTCPPorts = [
|
|
80
|
|
443
|
|
];
|
|
|
|
# so that caddy can access netbox's static files.
|
|
# users.users.caddy.extraGroups = ["netbox"];
|
|
|
|
services = {
|
|
caddy = {
|
|
enable = true;
|
|
# package = caddyPkg;
|
|
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 = "5s";
|
|
# LimitNOFILE = 1048576;
|
|
# LimitNPROC = 512;
|
|
PrivateTmp = true;
|
|
# ProtectSystem = "full";
|
|
AmbientCapabilities = "cap_net_bind_service";
|
|
};
|
|
};
|
|
# restart Caddy on config file change.
|
|
paths.caddy = {
|
|
pathConfig = {
|
|
PathChanged = config.sops.templates.caddyPls.path;
|
|
Unit = svc;
|
|
};
|
|
};
|
|
};
|
|
|
|
sops.secrets = {
|
|
njallaApiKey = {
|
|
restartUnits = [ svc ];
|
|
sopsFile = ../../../secrets/web/njalla.yaml;
|
|
};
|
|
"caddy/email".restartUnits = [ svc ];
|
|
"desecToken".restartUnits = [ svc ];
|
|
};
|
|
|
|
sops.templates.caddyPls = {
|
|
owner = config.systemd.services.caddy.serviceConfig.User;
|
|
content = ''
|
|
(tlsCommon) {
|
|
tls {
|
|
# dns njalla ${p."njallaApiKey"}
|
|
dns desec {
|
|
token ${p.desecToken}
|
|
}
|
|
# propagation_timeout 1m
|
|
propagation_timeout 2m
|
|
# propagation_timeout -1
|
|
curves x25519
|
|
key_type p384
|
|
protocols tls1.2 tls1.3
|
|
# resolvers 8.8.8.8 8.8.4.4
|
|
resolvers 1.1.1.1 8.8.8.8
|
|
}
|
|
}
|
|
|
|
(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/* http://localhost:${toString config.wanderllama.authentik.port}
|
|
|
|
# Forward authentication to outpost
|
|
forward_auth http://localhost:${toString config.wanderllama.authentik.port} {
|
|
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
|
|
}
|
|
}
|
|
|
|
{
|
|
#admin off
|
|
# servers {
|
|
metrics
|
|
# }
|
|
# acme_dns njalla ${p."njallaApiKey"}
|
|
acme_dns desec {
|
|
token ${p.desecToken}
|
|
}
|
|
email ${p."caddy/email"}
|
|
#grace_period 30s
|
|
grace_period 60s
|
|
|
|
log default {
|
|
output stdout
|
|
format json
|
|
# level INFO
|
|
}
|
|
|
|
# import tlsCommon
|
|
}
|
|
|
|
*.${domain}, ${domain} {
|
|
import tlsCommon
|
|
|
|
|
|
log {
|
|
hostnames ${domain}
|
|
level INFO
|
|
output file /var/log/caddy/${domain}.log
|
|
}
|
|
|
|
@${domain} host ${domain}
|
|
handle @${domain} {
|
|
encode zstd br
|
|
|
|
import headersCommon
|
|
import hsts
|
|
header Content-Type "text/html; charset=utf-8"
|
|
|
|
respond ${landingPage}
|
|
}
|
|
''
|
|
+ ''
|
|
${caddyLog "whoami"}
|
|
|
|
@whoami host whoami.${domain}
|
|
handle @whoami {
|
|
encode zstd br
|
|
|
|
import headersCommon
|
|
import hsts
|
|
# import authentik
|
|
|
|
respond "I am whoami on ${config.networking.hostName}"
|
|
}
|
|
''
|
|
+ optionalString config.services.forgejo.enable ''
|
|
${caddyLog "git"}
|
|
|
|
@git host git.${domain}
|
|
handle @git {
|
|
encode zstd br
|
|
import headersCommon
|
|
|
|
reverse_proxy 127.0.0.1:${toString config.services.forgejo.settings.server.HTTP_PORT}
|
|
}
|
|
''
|
|
+ optionalString config.services.ntopng.enable ''
|
|
${caddyLog "ntopng"}
|
|
|
|
@ntopng host ntopng.${domain}
|
|
handle @ntopng {
|
|
encode zstd br
|
|
import headersCommon
|
|
|
|
reverse_proxy localhost:${toString config.services.ntopng.httpPort}
|
|
}
|
|
''
|
|
+ optionalString config.services.netbox.enable ''
|
|
${caddyLog "netbox"}
|
|
|
|
@netbox host netbox.${domain}
|
|
handle @netbox {
|
|
encode zstd br
|
|
import headersCommon
|
|
|
|
### special handling for netbox static files
|
|
route {
|
|
file_server /static/* {
|
|
root /var/lib/netbox
|
|
}
|
|
}
|
|
reverse_proxy ${config.services.netbox.listenAddress}:${toString config.wanderllama.netbox.port}
|
|
}
|
|
''
|
|
+ optionalString config.services.atuin.enable ''
|
|
${caddyLog "atuin"}
|
|
|
|
# atuin - magical shell history.
|
|
@atuin host atuin.${domain}
|
|
handle @atuin {
|
|
encode zstd br
|
|
|
|
import headersCommon
|
|
import hsts
|
|
reverse_proxy localhost:${toString config.wanderllama.atuin.port}
|
|
}
|
|
''
|
|
+ optionalString config.services.vaultwarden.enable ''
|
|
${caddyLog "vaultwarden"}
|
|
|
|
@vaultwarden host waldemar.${domain}
|
|
handle @vaultwarden {
|
|
encode zstd br
|
|
import headersCommon
|
|
import hsts
|
|
reverse_proxy localhost:${toString config.wanderllama.vaultwarden.port}
|
|
}
|
|
''
|
|
+ ''} # end *.${domain}, ${domain}'';
|
|
};
|
|
}
|