feat(refactor): WIP refactor server modules
This commit is contained in:
192
modules/server/infra/traefik/default.nix
Normal file
192
modules/server/infra/traefik/default.nix
Normal file
@@ -0,0 +1,192 @@
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
pkgs,
|
||||
self,
|
||||
...
|
||||
}: let
|
||||
inherit (lib) mkEnableOption mkIf types;
|
||||
|
||||
cfg = config.server.infra.traefik;
|
||||
srv = config.server;
|
||||
|
||||
# Generates all Traefik routers from the central service list
|
||||
generateRouters = services:
|
||||
lib.mapAttrs' (
|
||||
name: service: let
|
||||
domain =
|
||||
if service.exposure == "tunnel"
|
||||
then "cnst.dev"
|
||||
else if service.exposure == "tailscale"
|
||||
then "ts.cnst.dev"
|
||||
else srv.domain;
|
||||
in
|
||||
lib.nameValuePair "${service.subdomain}" {
|
||||
entryPoints = ["websecure"];
|
||||
rule = "Host(`${service.subdomain}.${domain}`)";
|
||||
service = service.subdomain;
|
||||
tls.certResolver = "letsencrypt";
|
||||
}
|
||||
) (lib.filterAttrs (name: service: service.enable) services);
|
||||
|
||||
# Generates all Traefik backend services
|
||||
generateServices = services:
|
||||
lib.mapAttrs' (name: service:
|
||||
lib.nameValuePair "${service.subdomain}" {
|
||||
loadBalancer.servers = [{url = "http://localhost:${toString service.port}";}];
|
||||
}) (lib.filterAttrs (name: service: service.enable) services);
|
||||
|
||||
getCloudflareCredentials = hostname:
|
||||
if hostname == "ziggy"
|
||||
then config.age.secrets.cloudflareDnsCredentialsZiggy.path
|
||||
else if hostname == "sobotka"
|
||||
then config.age.secrets.cloudflareDnsCredentials.path
|
||||
else throw "Unknown hostname: ${hostname}";
|
||||
in {
|
||||
options.server.infra.traefik = {
|
||||
enable = mkEnableOption "Enable global Traefik reverse proxy with ACME";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
age.secrets = {
|
||||
traefikEnv = {
|
||||
file = "${self}/secrets/traefikEnv.age";
|
||||
mode = "640";
|
||||
owner = "traefik";
|
||||
group = "traefik";
|
||||
};
|
||||
crowdsecApi.file = "${self}/secrets/crowdsecApi.age";
|
||||
};
|
||||
|
||||
systemd.services.traefik = {
|
||||
serviceConfig = {
|
||||
EnvironmentFile = [config.age.secrets.traefikEnv.path];
|
||||
};
|
||||
};
|
||||
networking.firewall.allowedTCPPorts = [80 443];
|
||||
|
||||
services = {
|
||||
tailscale.permitCertUid = "traefik";
|
||||
traefik = {
|
||||
enable = true;
|
||||
|
||||
staticConfigOptions = {
|
||||
log = {
|
||||
level = "DEBUG";
|
||||
};
|
||||
|
||||
accesslog = {filepath = "/var/lib/traefik/logs/access.log";};
|
||||
|
||||
tracing = {};
|
||||
api = {
|
||||
dashboard = true;
|
||||
insecure = false;
|
||||
};
|
||||
|
||||
certificatesResolvers = {
|
||||
vpn.tailscale = {};
|
||||
letsencrypt = {
|
||||
acme = {
|
||||
email = "adam@cnst.dev";
|
||||
storage = "/var/lib/traefik/cert.json";
|
||||
dnsChallenge = {
|
||||
provider = "cloudflare";
|
||||
resolvers = [
|
||||
"1.1.1.1:53"
|
||||
"1.0.0.1:53"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
entryPoints = {
|
||||
# redis = {
|
||||
# address = "0.0.0.0:6381";
|
||||
# };
|
||||
# postgres = {
|
||||
# address = "0.0.0.0:5433";
|
||||
# };
|
||||
web = {
|
||||
address = ":80";
|
||||
forwardedHeaders.insecure = true;
|
||||
http.redirections.entryPoint = {
|
||||
to = "websecure";
|
||||
scheme = "https";
|
||||
permanent = true;
|
||||
};
|
||||
# http.middlewares = "crowdsec@file";
|
||||
};
|
||||
|
||||
websecure = {
|
||||
address = ":443";
|
||||
forwardedHeaders.insecure = true;
|
||||
http.tls = {
|
||||
certResolver = "letsencrypt";
|
||||
domains = [
|
||||
{
|
||||
main = "cnix.dev";
|
||||
sans = ["*.cnix.dev"];
|
||||
}
|
||||
{
|
||||
main = "ts.cnst.dev";
|
||||
sans = ["*ts.cnst.dev"];
|
||||
}
|
||||
];
|
||||
};
|
||||
# http.middlewares = "crowdsec@file";
|
||||
};
|
||||
|
||||
experimental = {
|
||||
address = ":1111";
|
||||
forwardedHeaders.insecure = true;
|
||||
};
|
||||
};
|
||||
|
||||
experimental = {
|
||||
# Install the Crowdsec Bouncer plugin
|
||||
plugins = {
|
||||
#enabled = "true";
|
||||
bouncer = {
|
||||
moduleName = "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin";
|
||||
version = "v1.4.5";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
dynamicConfigOptions = {
|
||||
http = {
|
||||
# Generate the services from your central list
|
||||
services = generateServices srv.services;
|
||||
|
||||
# Generate the routers and manually add the special 'api' router
|
||||
routers =
|
||||
(generateRouters srv.services)
|
||||
// {
|
||||
api = {
|
||||
entryPoints = ["websecure"];
|
||||
rule = "Host(`traefik.${srv.domain}`)";
|
||||
service = "api@internal";
|
||||
tls.certResolver = "letsencrypt";
|
||||
};
|
||||
};
|
||||
# middlewares = {
|
||||
# crowdsec = {
|
||||
# plugin = {
|
||||
# bouncer = {
|
||||
# enabled = "true";
|
||||
# logLevel = "DEBUG";
|
||||
# crowdsecLapiKeyFile = config.age.secrets.crowdsecApi.path;
|
||||
# crowdsecMode = "live";
|
||||
# crowdsecLapiHost = ":4223";
|
||||
# };
|
||||
# };
|
||||
# };
|
||||
# };
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user