phase 2: promote services/, tests/, patches/, lib/, scripts/
This commit is contained in:
162
services/caddy/caddy.nix
Normal file
162
services/caddy/caddy.nix
Normal file
@@ -0,0 +1,162 @@
|
||||
{
|
||||
config,
|
||||
service_configs,
|
||||
pkgs,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
theme = pkgs.fetchFromGitHub {
|
||||
owner = "kaiiiz";
|
||||
repo = "hugo-theme-monochrome";
|
||||
rev = "d17e05715e91f41a842f2656e6bdd70cba73de91";
|
||||
sha256 = "h9I2ukugVrldIC3SXefS0L3R245oa+TuRChOCJJgF24=";
|
||||
};
|
||||
|
||||
hugo-neko = pkgs.fetchFromGitHub {
|
||||
owner = "ystepanoff";
|
||||
repo = "hugo-neko";
|
||||
rev = "5a50034acbb1ae0cec19775af64e7167ca22725e";
|
||||
sha256 = "VLwr4zEeFQU/b+vj0XTLSuEiosuNFu2du4uud7m8bnw=";
|
||||
};
|
||||
|
||||
hugoWebsite = pkgs.stdenv.mkDerivation {
|
||||
pname = "hugo-site";
|
||||
version = "0.1";
|
||||
|
||||
src = inputs.website;
|
||||
|
||||
nativeBuildInputs = with pkgs; [
|
||||
hugo
|
||||
go
|
||||
git
|
||||
];
|
||||
|
||||
installPhase = ''
|
||||
rm -fr themes/theme modules/hugo-neko
|
||||
cp -r ${theme} themes/theme
|
||||
cp -r ${hugo-neko} modules/hugo-neko
|
||||
hugo --minify -d $out;
|
||||
'';
|
||||
};
|
||||
|
||||
newDomain = service_configs.https.domain;
|
||||
oldDomain = service_configs.https.old_domain;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(lib.serviceMountWithZpool "caddy" service_configs.zpool_ssds [
|
||||
config.services.caddy.dataDir
|
||||
])
|
||||
];
|
||||
|
||||
services.caddy = {
|
||||
enable = true;
|
||||
email = "titaniumtown@proton.me";
|
||||
|
||||
# Build with Njalla DNS provider for DNS-01 ACME challenges (wildcard certs)
|
||||
package = pkgs.caddy.withPlugins {
|
||||
plugins = [ "github.com/caddy-dns/njalla@v0.0.0-20250823094507-f709141f1fe6" ];
|
||||
hash = "sha256-rrOAR6noTDpV/I/hZXxhz0OXVJKu0mFQRq87RUrpmzw=";
|
||||
};
|
||||
|
||||
globalConfig = ''
|
||||
# Wildcard cert for *.${newDomain} via DNS-01 challenge
|
||||
acme_dns njalla {
|
||||
api_token {env.NJALLA_API_TOKEN}
|
||||
}
|
||||
|
||||
# On-demand TLS for old domain redirects
|
||||
on_demand_tls {
|
||||
ask http://localhost:9123/check
|
||||
}
|
||||
'';
|
||||
|
||||
# Internal endpoint to validate on-demand TLS requests
|
||||
# Only allows certs for *.${oldDomain}
|
||||
extraConfig = ''
|
||||
http://localhost:9123 {
|
||||
@allowed expression {query.domain}.endsWith(".${oldDomain}") || {query.domain} == "${oldDomain}" || {query.domain} == "www.${oldDomain}"
|
||||
respond @allowed 200
|
||||
respond 403
|
||||
}
|
||||
'';
|
||||
|
||||
virtualHosts = {
|
||||
${newDomain} = {
|
||||
extraConfig = ''
|
||||
root * ${hugoWebsite}
|
||||
file_server browse
|
||||
'';
|
||||
|
||||
serverAliases = [ "www.${newDomain}" ];
|
||||
};
|
||||
|
||||
# Redirect old domain (bare + www) to new domain
|
||||
${oldDomain} = {
|
||||
extraConfig = ''
|
||||
redir https://${newDomain}{uri} permanent
|
||||
'';
|
||||
serverAliases = [ "www.${oldDomain}" ];
|
||||
};
|
||||
|
||||
# Wildcard redirect for all old domain subdomains
|
||||
# Uses on-demand TLS - certs issued automatically on first request
|
||||
"*.${oldDomain}" = {
|
||||
extraConfig = ''
|
||||
tls {
|
||||
on_demand
|
||||
}
|
||||
# {labels.2} extracts subdomain from *.gardling.com
|
||||
redir https://{labels.2}.${newDomain}{uri} permanent
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Inject Njalla API token for DNS-01 challenge
|
||||
systemd.services.caddy.serviceConfig.EnvironmentFile = config.age.secrets.njalla-api-token-env.path;
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d ${config.services.caddy.dataDir} 700 ${config.services.caddy.user} ${config.services.caddy.group}"
|
||||
];
|
||||
|
||||
systemd.packages = with pkgs; [ nssTools ];
|
||||
|
||||
networking.firewall.allowedTCPPorts = [
|
||||
service_configs.ports.public.https.port
|
||||
|
||||
# http (but really acmeCA challenges)
|
||||
service_configs.ports.public.http.port
|
||||
];
|
||||
|
||||
networking.firewall.allowedUDPPorts = [
|
||||
service_configs.ports.public.https.port
|
||||
];
|
||||
|
||||
# Protect Caddy basic auth endpoints from brute force attacks
|
||||
services.fail2ban.jails.caddy-auth = {
|
||||
enabled = true;
|
||||
settings = {
|
||||
backend = "auto";
|
||||
port = "http,https";
|
||||
logpath = "/var/log/caddy/access-*.log";
|
||||
# defaults: maxretry=5, findtime=10m, bantime=10m
|
||||
|
||||
# Ignore local network IPs - NAT hairpinning causes all LAN traffic to
|
||||
# appear from the router IP (192.168.1.1). Banning it blocks all internal access.
|
||||
ignoreip = "127.0.0.1/8 ::1 192.168.1.0/24";
|
||||
};
|
||||
filter.Definition = {
|
||||
# Only match 401s where an Authorization header was actually sent.
|
||||
# Without this, the normal HTTP Basic Auth challenge-response flow
|
||||
# (browser probes without credentials, gets 401, then resends with
|
||||
# credentials) counts every page visit as a "failure."
|
||||
failregex = ''^.*"remote_ip":"<HOST>".*"Authorization":\["REDACTED"\].*"status":401.*$'';
|
||||
ignoreregex = "";
|
||||
datepattern = ''"ts":{Epoch}\.'';
|
||||
};
|
||||
};
|
||||
}
|
||||
39
services/caddy/caddy_senior_project.nix
Normal file
39
services/caddy/caddy_senior_project.nix
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
service_configs,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
theme = pkgs.fetchFromGitHub {
|
||||
owner = "kaiiiz";
|
||||
repo = "hugo-theme-monochrome";
|
||||
rev = "d17e05715e91f41a842f2656e6bdd70cba73de91";
|
||||
sha256 = "h9I2ukugVrldIC3SXefS0L3R245oa+TuRChOCJJgF24=";
|
||||
};
|
||||
|
||||
hugoWebsite = pkgs.stdenv.mkDerivation {
|
||||
pname = "hugo-site";
|
||||
version = "0.1";
|
||||
|
||||
src = inputs.senior_project-website;
|
||||
|
||||
nativeBuildInputs = with pkgs; [
|
||||
hugo
|
||||
];
|
||||
|
||||
installPhase = ''
|
||||
rm -fr themes/theme
|
||||
cp -rv ${theme} themes/theme
|
||||
hugo --minify -d $out;
|
||||
'';
|
||||
};
|
||||
in
|
||||
{
|
||||
services.caddy.virtualHosts."senior-project.${service_configs.https.domain}".extraConfig = ''
|
||||
root * ${hugoWebsite}
|
||||
file_server browse
|
||||
'';
|
||||
}
|
||||
7
services/caddy/default.nix
Normal file
7
services/caddy/default.nix
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
imports = [
|
||||
./caddy.nix
|
||||
# KEEP UNTIL 2028
|
||||
./caddy_senior_project.nix
|
||||
];
|
||||
}
|
||||
Reference in New Issue
Block a user