nix-configs/modules/services/traefik.nix
Lucy Hochkamp d74a131529
Some checks failed
ci/woodpecker/push/build-cache Pipeline failed
meow
2025-11-26 11:11:49 +01:00

197 lines
5.2 KiB
Nix

{
pkgs,
lib,
config,
...
}:
let
cfg = config.xyno.services.traefik;
simpleProxyOpts = lib.mapAttrsToList (
n: v:
let
router = "simpleproxy-${n}-router";
service = "simpleproxy-${n}-service";
spl = lib.splitString "." v.host;
certDomain =
if (builtins.length spl) > 2 then lib.concatStringsSep "." (builtins.tail spl) else spl;
in
{
routers."${router}-robotstxt" = {
service = "robotstxt";
rule = "Host(`${v.host}`) && Path(`/robots.txt`)";
tls.certResolver = "letsencrypt";
tls.domains = [
{
main = certDomain;
sans = [ "*.${certDomain}" ];
}
];
};
routers.${router} = {
inherit service;
rule = "Host(`${v.host}`)";
tls.certResolver = "letsencrypt";
tls.domains = [
{
main = certDomain;
sans = [ "*.${certDomain}" ];
}
];
};
services.${service} = {
loadBalancer.servers = [
{ url = v.internal; }
];
loadBalancer.serverTransport = lib.mkIf (v.transport != null) v.transport;
};
services.robotstxt = {
loadBalancer.servers = [
{ url = "http://127.0.0.2:8080"; }
];
};
}
) cfg.simpleProxy;
in
{
options.xyno.services.traefik.enable = lib.mkEnableOption "enables traefik";
options.xyno.services.traefik.noBots = lib.mkOption {
type = lib.types.bool;
default = true;
};
options.xyno.services.traefik.simpleProxy = lib.mkOption {
example = {
"example" = {
host = "example.org";
middlewares = [ "meow" ];
internal = "http://127.0.0.1:8080";
};
};
default = { };
type = lib.types.attrsOf (
lib.types.submodule {
options = {
middlewares = lib.mkOption {
type = lib.types.nullOr (lib.types.listOf lib.types.str);
};
internal = lib.mkOption {
type = lib.types.str;
};
host = lib.mkOption {
type = lib.types.str;
};
transport = lib.mkOption {
type = lib.types.nullOr lib.types.anything;
default = null;
};
};
}
);
};
config = lib.mkIf cfg.enable {
services.nginx = {
enable = lib.mkIf cfg.noBots true;
defaultListen = lib.mkIf cfg.noBots [
{
addr = "127.0.0.2";
port = 8080;
}
];
virtualHosts._.default = true;
virtualHosts._.locations."/".root = pkgs.writeTextFile {
name = "robots.txt";
destination = "/robots.txt";
text = ''
User-agent: *
Disallow: /
'';
};
};
services.traefik = {
enable = true;
environmentFiles = [
config.sops.templates."traefik.env".path
];
staticConfigOptions = {
metrics = lib.mkIf config.xyno.services.monitoring.enable {
otlp.http.endpoint = "http://localhost:8429/v1/metrics";
};
entryponits.web = {
address = ":80";
redirections.entryPoint = {
to = "websecure";
scheme = "https";
permanent = true;
};
};
entrypoints.websecure = {
address = ":443";
http.tls.certResolver = "letsencrypt";
http3 = { };
};
log.level = "INFO";
certificatesResolvers.letsencrypt.acme = {
email = "ssl@xyno.systems";
caServer = "https://acme-v02.api.letsencrypt.org/directory";
dnsChallenge = {
resolvers = [ "8.8.8.8" "1.1.1.1" ];
provider = "desec";
};
};
};
dynamicConfigOptions = {
http = lib.mkMerge simpleProxyOpts;
# tls.options.default = {
# # mozilla modern
# minVersion = "VersionTLS13";
# curvePreferences = [
# "X25519"
# "CurveP256"
# "CurveP384"
# ];
# };
# tls.options.old = {
# # mozilla intermediate
# minVersion = "VersionTLS12";
# curvePreferences = [
# "X25519"
# "CurveP256"
# "CurveP384"
# ];
# cipherSuites = [
# "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
# "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
# "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
# "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
# "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305"
# "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305"
# ];
# };
};
};
networking.firewall.allowedTCPPorts = [
80
443
];
networking.firewall.allowedUDPPorts = [ 443 ];
xyno.impermanence.directories = [ config.services.traefik.dataDir ];
sops.secrets."desec_token" = {
};
sops.templates."traefik.env".content = ''
DESEC_TOKEN=${config.sops.placeholder.desec_token}
DESEC_PROPAGATION_TIMEOUT=1200
LEGO_DISABLE_CNAME_SUPPORT=true
'';
sops.templates."traefik.env".reloadUnits = [ "traefik.service" ];
# services.borgmatic.settings.traefikql_databases = [
# {
# name = "all"; # gets run as root anyways so can log in
# }
# ];
};
}